<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pt-BR">
	<id>http://fiscomp.if.ufrgs.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gabrielcanova</id>
	<title>Física Computacional - Contribuições do usuário [pt-br]</title>
	<link rel="self" type="application/atom+xml" href="http://fiscomp.if.ufrgs.br/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gabrielcanova"/>
	<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php/Especial:Contribui%C3%A7%C3%B5es/Gabrielcanova"/>
	<updated>2026-04-15T21:39:58Z</updated>
	<subtitle>Contribuições do usuário</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=337</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=337"/>
		<updated>2015-07-16T21:33:45Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em uma dada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa. No próximo passo, a função rint(dx/Lx) arredondará o valor da divisão para o inteiro mais próximo, assim, se &amp;lt;math&amp;gt; dx/L_x &amp;gt; 0.5 &amp;lt;/math&amp;gt; descontaremos &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; de &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e se &amp;lt;math&amp;gt; dx/L_x \le 0.5 &amp;lt;/math&amp;gt; já teremos o &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; correto. O mesmo procedimento também é aplicado sobre a componente &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. No ''if'' testamos se a distância ao quadrado entre um par de partículas é menor que o raio crítico de interação, ou seja, a distância máxima acima da qual desconsideramos a força entre duas partículas, lembrando que isso é feito devido ao fato do potencial Lennard-Jones ser de curto alcance.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=336</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=336"/>
		<updated>2015-07-16T20:40:10Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em uma dada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa. No próximo passo, a função rint(dx/Lx) arredondará o valor da divisão para o inteiro mais próximo, assim, se &amp;lt;math&amp;gt; dx/L_x &amp;gt;0.5 &amp;lt;/math&amp;gt; descontaremos &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; de &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e se &amp;lt;math&amp;gt; dx/L_x \le 0.5 &amp;lt;/math&amp;gt; já teremos o &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; correto. O mesmo procedimento também é aplicado sobre a componente &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. No {\it if} testamos se a distância ao quadrado entre um par de partículas é menor que o raio crítico de interação, ou seja, a distância máxima acima da qual desconsideramos a força entre duas partículas, lembrando que isso é feito devido ao fato do potencial Lennard-Jones ser de curto alcance.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=335</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=335"/>
		<updated>2015-07-16T20:28:32Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em uma dada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa. No próximo passo, a função rint(dx/Lx) arredondará o valor da divisão para o inteiro mais próximo, assim, se &amp;lt;math&amp;gt; dx/L_x &amp;gt;0.5 &amp;lt;/math&amp;gt; descontaremos &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; de &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e se &amp;lt;math&amp;gt; dx/L_x \le 0.5 &amp;lt;/math&amp;gt; já teremos o &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; correto. O mesmo procedimento é aplicado sobre a componente &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=334</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=334"/>
		<updated>2015-07-16T20:27:19Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em uma dada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa. No próximo passo, a função rint(dx/Lx) arredondará o valor da divisão para o inteiro mais próximo, assim, se &amp;lt;math&amp;gt; dx/L_x &amp;gt;0.5 &amp;lt;/math&amp;gt; descontaremos &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; de &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e se &amp;lt;math&amp;gt; dx/L_x &amp;lt; 0.5 &amp;lt;/math&amp;gt; já teremos o &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; correto. O mesmo procedimento é aplicado sobre a componente &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=333</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=333"/>
		<updated>2015-07-16T20:26:31Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em uma dada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa. No próximo passo, a função rint(dx/Lx) arredondará o valor da divisão para o inteiro mais próximo, assim, se &amp;lt;math&amp;gt; dx/L_x &amp;gt;0.5 &amp;lt;/math&amp;gt; descontaremos &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; de &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e se &amp;lt;math&amp;gt; dx/L_x \l.e 0.5 &amp;lt;/math&amp;gt; já teremos o &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; correto. O mesmo procedimento é aplicado sobre a componente &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.   &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=332</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=332"/>
		<updated>2015-07-16T19:57:06Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada uma delas teríamos que fazer um loop sobre todas as outras, porém, pela Terceira Lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em cada direção, além disso, elas não precisam necessariamente estar limitadas aos contornos da caixa as quais foram inseridas, mas o cálculo da força sim. Desse modo, a função resto fmod(dx,Lx) nos assegura que nenhuma distância estará fora da caixa e ao...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=331</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=331"/>
		<updated>2015-07-16T19:41:30Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada partícula do sistema teríamos que fazer um loop sobre todas as outras, porém, pela terceira lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares. &amp;lt;math&amp;gt; x_1 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; x_2 &amp;lt;/math&amp;gt; são, respectivamente, as posições das partículas &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;, enquanto &amp;lt;math&amp;gt; dx &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy &amp;lt;/math&amp;gt; as distâncias entre elas. Porém, como nosso sistema possui condições periódicas de contorno, nenhum par de partículas poderá ter um distância maior que &amp;lt;math&amp;gt; L/2 &amp;lt;/math&amp;gt; em cada direção.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=330</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=330"/>
		<updated>2015-07-15T22:26:54Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada partícula do sistema teríamos que fazer um loop sobre todas as outras, porém, pela terceira lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo varremos &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Desse modo, asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=329</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=329"/>
		<updated>2015-07-15T22:20:25Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Como a aceleração resultante sobre uma partícula é a soma de todas as forças que agem sobre ela, para cada partícula do sistema teríamos que fazer um loop sobre todas as outras, porém, pela terceira lei de Newton &amp;lt;math&amp;gt; F_{ij}=-F_{ji} &amp;lt;/math&amp;gt;, ou seja, apenas temos que somar sobre todas as combinações de pares de partículas. No primeiro loop abaixo estamos varrendo &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; para todas partículas, no segundo, a varredura começa em &amp;lt;math&amp;gt; i+1 &amp;lt;/math&amp;gt; e segue até &amp;lt;math&amp;gt; N-1 &amp;lt;/math&amp;gt;. Assim asseguramos que todos os pares de partículas entrem no cálculo, no caso, temos &amp;lt;math&amp;gt; N(N-1)/2 &amp;lt;/math&amp;gt; pares.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=328</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=328"/>
		<updated>2015-07-15T22:03:24Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
O cálculo da força é a parte mais crucial do programa, pois é a que mais consome recursos e pode ser drasticamente melhorada com otimizações. Abaixo introduzimos a rotina mais simples possível para o cálculo da força. Ela recebe os ponteiros das forças nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, as coordenadas (o potencial Lennard-Jones só depende da posição) e a energia potencial. No primeiro loop zeramos as duas componentes da força para todas as partículas. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=327</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=327"/>
		<updated>2015-07-15T21:45:45Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void compute_forces(double *fx,double *fy,double *x,double *y,double *Ep)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i,j;&lt;br /&gt;
  double  x1,y1,x2,y2,dx,dy,r2,r2i,r6,ff,Energy=0.;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        fx[i] = 0.;&lt;br /&gt;
        fy[i] = 0.;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        x1=x[i]; y1=y[i];&lt;br /&gt;
&lt;br /&gt;
        for(j=i+1;j&amp;lt;N;j++)&lt;br /&gt;
        {&lt;br /&gt;
                x2=x[j];&lt;br /&gt;
&lt;br /&gt;
                dx=x1 - x2;&lt;br /&gt;
                dx=fmod(dx,Lx);&lt;br /&gt;
                dx=dx-rint(dx/Lx)*Lx;&lt;br /&gt;
&lt;br /&gt;
                y2=y[j];&lt;br /&gt;
&lt;br /&gt;
                dy=y1 - y2;&lt;br /&gt;
                dy=fmod(dy,Ly);&lt;br /&gt;
                dy=dy-rint(dy/Ly)*Ly;&lt;br /&gt;
&lt;br /&gt;
                r2=dx*dx + dy*dy;&lt;br /&gt;
&lt;br /&gt;
                if(r2&amp;lt;Rc2)&lt;br /&gt;
                {&lt;br /&gt;
                        r2i=1/r2 ;&lt;br /&gt;
                        r6=r2i*r2i*r2i;&lt;br /&gt;
                        ff=48*r2i*r6*(r6-0.5);&lt;br /&gt;
                        fx[i] += ff*dx;   fy[i] += ff*dy;&lt;br /&gt;
                        fx[j] -= ff*dx;   fy[j] -= ff*dy;&lt;br /&gt;
                        Energy += 4*r6*(r6-1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
  *Ep=Energy;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=326</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=326"/>
		<updated>2015-07-15T21:37:10Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. Como &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; é o índice global das partículas, o resto (%) da divisão inteira entre &amp;lt;math&amp;gt; L_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Nx &amp;lt;/math&amp;gt; nos dará a coordenada &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt;, enquanto o resultado da divisão inteira entre &amp;lt;math&amp;gt; L_y &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; Ny &amp;lt;/math&amp;gt; definirá a coordenada &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=325</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=325"/>
		<updated>2015-07-07T21:37:01Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada representada na Figura 2, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=324</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=324"/>
		<updated>2015-07-07T21:34:32Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg|thumb|300px|Figura 2 - Condição inicial.]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Initialcondition.jpg&amp;diff=323</id>
		<title>Arquivo:Initialcondition.jpg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Initialcondition.jpg&amp;diff=323"/>
		<updated>2015-07-07T21:29:00Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=322</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=322"/>
		<updated>2015-07-07T21:26:30Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.jpg]]&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=321</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=321"/>
		<updated>2015-07-07T21:24:12Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:initialcondition.eps]]&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=320</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=320"/>
		<updated>2015-07-07T20:49:50Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;.  Podemos imaginar a disposição inicial das partículas como uma rede quadrada, onde em cada vértice se encontra uma partícula, a distância entre elas é dada por &amp;lt;math&amp;gt; dx=L_x/N_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; dy=L_y/N_y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=319</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=319"/>
		<updated>2015-07-07T20:37:45Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A rotina da inicialização das posições recebe os ponteiros das coordenadas &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt; das partículas, as coordenadas no tempo anterior &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y_0 &amp;lt;/math&amp;gt;, além das velocidades inicias &amp;lt;math&amp;gt; v_x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; v_y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=318</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=318"/>
		<updated>2015-07-07T20:29:31Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *x,double *y,double *xo,double *yo,double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
        unsigned i;&lt;br /&gt;
        double dx,dy;&lt;br /&gt;
&lt;br /&gt;
        dx=(double)Lx/Nx;&lt;br /&gt;
        dy=(double)Ly/Ny;&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
        {&lt;br /&gt;
                x[i]=(i%Nx)*dx;&lt;br /&gt;
                y[i]=(i/Ny)*dy;&lt;br /&gt;
&lt;br /&gt;
                xo[i]=x[i]-vx[i]*dt;&lt;br /&gt;
                yo[i]=y[i]-vy[i]*dt;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=317</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=317"/>
		<updated>2015-07-07T20:09:25Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso, as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=316</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=316"/>
		<updated>2015-07-07T20:07:18Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descrevemos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das velocidades, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. Como condição inicial, todas as partículas recebem uma velocidade aleatória dada por rand()/RAND_MAX que gera um número entre zero e um. Vcx e Vcy são, respectivamente, as componentes da velocidade do centro de massa do sistema nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;, enquanto V2 é a energia cinética. Para o caso em que as partículas estejam transladando em uma direção preferencial, descontamos suas velocidades pela do centro de massa, além disso as renormalizamos por um fator de escala que depende da temperatura inicial dada, lembrando que a mesma pode variar no ensamble microcanônico.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=315</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=315"/>
		<updated>2015-07-07T05:25:02Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a energia total. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Agora descremos detalhadamente todas as rotinas que aparecem na parte principal. Começamos com a inicialização das posições, a rotina recebe os ponteiros das velocidades nas direções &amp;lt;math&amp;gt; x &amp;lt;/math&amp;gt; e &amp;lt;math&amp;gt; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx,double *vy)&lt;br /&gt;
{&lt;br /&gt;
  unsigned i;&lt;br /&gt;
  double Vcx=0.,Vcy=0.,V2=0.,fs;&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
      vx[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
      vy[i]=1.*rand()/RAND_MAX;&lt;br /&gt;
&lt;br /&gt;
      Vcx+=vx[i];&lt;br /&gt;
      Vcy+=vy[i];&lt;br /&gt;
      V2 +=vx[i]*vx[i] + vy[i]*vy[i];&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Vcx/=N;&lt;br /&gt;
  Vcy/=N;&lt;br /&gt;
  V2 /=N;&lt;br /&gt;
  fs=sqrt(2.*T/V2);&lt;br /&gt;
&lt;br /&gt;
  for(i=0;i&amp;lt;N;i++)&lt;br /&gt;
  {&lt;br /&gt;
        vx[i]=(vx[i]-Vcx)*fs;&lt;br /&gt;
        vy[i]=(vy[i]-Vcy)*fs;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=314</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=314"/>
		<updated>2015-07-03T19:39:03Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total\_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute\_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate\_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a soma das duas últimas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=313</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=313"/>
		<updated>2015-07-03T19:36:05Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total/_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a soma das duas últimas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=312</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=312"/>
		<updated>2015-07-03T19:32:13Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
FILE *file1,*file2;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
initialize_velocities(vx,vy);&lt;br /&gt;
initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. O &amp;lt;math&amp;gt; for &amp;lt;/math&amp;gt; em &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt; imprime no arquivo &amp;quot;trajectories.dat&amp;quot; as posições e velocidades de todas as partículas no instante &amp;lt;math&amp;gt; t &amp;lt;/math&amp;gt;. No &amp;lt;math&amp;gt; if &amp;lt;/math&amp;gt; testamos se o tempo total é maior que o tempo de equilíbrio e se a medida deve ser feita, caso seja, no arquivo &amp;quot;energy.dat&amp;quot; imprimiremos, respectivamente, o tempo, energia cinética, energia potencial e a soma das duas últimas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
{&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
        fflush(file2);&lt;br /&gt;
        rewind(file2);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fclose(file1);&lt;br /&gt;
fclose(file2);&lt;br /&gt;
&lt;br /&gt;
free(x);&lt;br /&gt;
free(y);&lt;br /&gt;
free(xo);&lt;br /&gt;
free(yo);&lt;br /&gt;
free(vx);&lt;br /&gt;
free(vy);&lt;br /&gt;
free(Fx);&lt;br /&gt;
free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=311</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=311"/>
		<updated>2015-07-03T19:17:51Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)malloc(size);&lt;br /&gt;
y= (double*)malloc(size);&lt;br /&gt;
xo=(double*)malloc(size);&lt;br /&gt;
yo=(double*)malloc(size);&lt;br /&gt;
vx=(double*)malloc(size);&lt;br /&gt;
vy=(double*)malloc(size);&lt;br /&gt;
Fx=(double*)malloc(size);&lt;br /&gt;
Fy=(double*)malloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  initialize_velocities(vx,vy);&lt;br /&gt;
  initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
  {&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
                fflush(file2);&lt;br /&gt;
                rewind(file2);&lt;br /&gt;
&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  fclose(file1);&lt;br /&gt;
  fclose(file2);&lt;br /&gt;
&lt;br /&gt;
  free(x);&lt;br /&gt;
  free(y);&lt;br /&gt;
  free(xo);&lt;br /&gt;
  free(yo);&lt;br /&gt;
  free(vx);&lt;br /&gt;
  free(vy);&lt;br /&gt;
  free(Fx);&lt;br /&gt;
  free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=310</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=310"/>
		<updated>2015-07-03T19:10:42Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define transient 5.&lt;br /&gt;
#define total_time 10.&lt;br /&gt;
#define measure 0.1&lt;br /&gt;
#define samples ((total_time-transient)/measure)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transient &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; measure &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; samples &amp;lt;/math&amp;gt; nos dá o número total de medidas que serão realizadas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)jmalloc(size);&lt;br /&gt;
y= (double*)jmalloc(size);&lt;br /&gt;
xo=(double*)jmalloc(size);&lt;br /&gt;
yo=(double*)jmalloc(size);&lt;br /&gt;
vx=(double*)jmalloc(size);&lt;br /&gt;
vy=(double*)jmalloc(size);&lt;br /&gt;
Fx=(double*)jmalloc(size);&lt;br /&gt;
Fy=(double*)jmalloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  initialize_velocities(vx,vy);&lt;br /&gt;
  initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
  {&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
                fflush(file2);&lt;br /&gt;
                rewind(file2);&lt;br /&gt;
&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  fclose(file1);&lt;br /&gt;
  fclose(file2);&lt;br /&gt;
&lt;br /&gt;
  free(x);&lt;br /&gt;
  free(y);&lt;br /&gt;
  free(xo);&lt;br /&gt;
  free(yo);&lt;br /&gt;
  free(vx);&lt;br /&gt;
  free(vy);&lt;br /&gt;
  free(Fx);&lt;br /&gt;
  free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=309</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=309"/>
		<updated>2015-07-03T19:02:41Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define total_time 5000&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; total_time &amp;lt;/math&amp;gt; é o tempo absoluto da simulação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transiente &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; medir &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)jmalloc(size);&lt;br /&gt;
y= (double*)jmalloc(size);&lt;br /&gt;
xo=(double*)jmalloc(size);&lt;br /&gt;
yo=(double*)jmalloc(size);&lt;br /&gt;
vx=(double*)jmalloc(size);&lt;br /&gt;
vy=(double*)jmalloc(size);&lt;br /&gt;
Fx=(double*)jmalloc(size);&lt;br /&gt;
Fy=(double*)jmalloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  initialize_velocities(vx,vy);&lt;br /&gt;
  initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Abaixo é mostrada a parte principal do programa, o loop sobre o tempo. A cada passo de tempo, a rotina &amp;lt;math&amp;gt; compute_forces &amp;lt;/math&amp;gt; calcula a força e a energia potencial das partículas a partir de suas posições, na sequência, a rotina &amp;lt;math&amp;gt; integrate_EqMotion &amp;lt;/math&amp;gt; atualiza as posições das partículas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for(t=0.;t&amp;lt;total_time;t+=dt)&lt;br /&gt;
  {&lt;br /&gt;
        compute_forces(Fx,Fy,x,y,&amp;amp;Ep);&lt;br /&gt;
        integrate_EqMotion(Fx,Fy,x,y,xo,yo,&amp;amp;Ec,&amp;amp;Vxm);&lt;br /&gt;
&lt;br /&gt;
        if( t&amp;gt;transient &amp;amp;&amp;amp; (1.-fmod(t/measure,1.) )&amp;lt;0.00001 )&lt;br /&gt;
        {&lt;br /&gt;
                for(i=0;i&amp;lt;N;i++)fprintf(file2,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,x[i],y[i],vx[i],vy[i]);&lt;br /&gt;
                fflush(file2);&lt;br /&gt;
                rewind(file2);&lt;br /&gt;
&lt;br /&gt;
                fprintf(file1,&amp;quot;%lf %lf %lf %lf\n&amp;quot;,t,Ec,Ep,Ec+Ep);&lt;br /&gt;
                fflush(file1);&lt;br /&gt;
        }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  fclose(file1);&lt;br /&gt;
  fclose(file2);&lt;br /&gt;
&lt;br /&gt;
  free(x);&lt;br /&gt;
  free(y);&lt;br /&gt;
  free(xo);&lt;br /&gt;
  free(yo);&lt;br /&gt;
  free(vx);&lt;br /&gt;
  free(vy);&lt;br /&gt;
  free(Fx);&lt;br /&gt;
  free(Fy);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=308</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=308"/>
		<updated>2015-07-02T21:15:18Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; transiente &amp;lt;/math&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; medir &amp;lt;/math&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)jmalloc(size);&lt;br /&gt;
y= (double*)jmalloc(size);&lt;br /&gt;
xo=(double*)jmalloc(size);&lt;br /&gt;
yo=(double*)jmalloc(size);&lt;br /&gt;
vx=(double*)jmalloc(size);&lt;br /&gt;
vy=(double*)jmalloc(size);&lt;br /&gt;
Fx=(double*)jmalloc(size);&lt;br /&gt;
Fy=(double*)jmalloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  initialize_velocities(vx,vy);&lt;br /&gt;
  initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=307</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=307"/>
		<updated>2015-07-02T21:09:35Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; transiente &amp;lt;/pre&amp;gt; é o tempo que esperamos até o sistema supostamente equilibrar e, então, começarmos a fazer medidas. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; medir &amp;lt;/pre&amp;gt; define o intervalo de tempo entre as medições.  &lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)jmalloc(size);&lt;br /&gt;
y= (double*)jmalloc(size);&lt;br /&gt;
xo=(double*)jmalloc(size);&lt;br /&gt;
yo=(double*)jmalloc(size);&lt;br /&gt;
vx=(double*)jmalloc(size);&lt;br /&gt;
vy=(double*)jmalloc(size);&lt;br /&gt;
Fx=(double*)jmalloc(size);&lt;br /&gt;
Fy=(double*)jmalloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
Com o os vetores alocados, podemos agora inicializar as velocidades e posições das partículas na rede&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  initialize_velocities(vx,vy);&lt;br /&gt;
  initialize_positions(x,y,xo,yo,vx,vy);&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=306</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=306"/>
		<updated>2015-07-02T20:50:49Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio de corte acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
unsigned i;&lt;br /&gt;
double *x,*y,*xo,*yo,*vx,*vy,*Fx,*Fy,Ep,Ec,Vxm=0.,t;&lt;br /&gt;
&lt;br /&gt;
size_t size=N*sizeof(double);&lt;br /&gt;
&lt;br /&gt;
x= (double*)jmalloc(size);&lt;br /&gt;
y= (double*)jmalloc(size);&lt;br /&gt;
xo=(double*)jmalloc(size);&lt;br /&gt;
yo=(double*)jmalloc(size);&lt;br /&gt;
vx=(double*)jmalloc(size);&lt;br /&gt;
vy=(double*)jmalloc(size);&lt;br /&gt;
Fx=(double*)jmalloc(size);&lt;br /&gt;
Fy=(double*)jmalloc(size);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Acima são declaradas todas as variáveis essenciais ao programa, assim como a alocação de memória para os vetores como posição, velocidade, força, etc. &lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=305</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=305"/>
		<updated>2015-04-23T00:29:30Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *fx, double *fy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
FILE *file1,*file2,*file3,*file4;&lt;br /&gt;
file1=fopen(&amp;quot;energy.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
file2=fopen(&amp;quot;trajectories.dat&amp;quot;,&amp;quot;w&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=304</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=304"/>
		<updated>2015-04-23T00:09:56Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
#define Rc 4&lt;br /&gt;
#define Rc2 (Rc*Rc)&lt;br /&gt;
#define T 1.&lt;br /&gt;
#define transiente 1000&lt;br /&gt;
#define medir 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R_c &amp;lt;/math&amp;gt; é o raio acima do qual o cálculo da força é desconsiderado. &lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=303</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=303"/>
		<updated>2015-04-23T00:01:12Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np (Nx*Ny)&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Np=N_xN_y &amp;lt;/math&amp;gt; número total de partículas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo de integração na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=302</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=302"/>
		<updated>2015-04-22T23:57:05Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente, introduziremos partes do código comentando cada etapa. Para o leitor mais familiarizado com DM, ao final da página há o programa completo sem comentários. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ideia básica da simulação pode ser entendida como: Leitura dos parâmetros da simulação, inicialização das posições das partículas, inicialização das velocidades das partículas, laço temporal onde se calcula a força, integra-se as equações de movimento e, de tempos em tempos, medidas são realizadas.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
Abaixo introduzimos partes do código onde começamos declarando as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros da simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=301</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=301"/>
		<updated>2015-04-21T18:19:55Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] Aqui mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, o programa pode ser organizado como mostra o fluxograma abaixo. Posteriormente introduziremos partes do programa comentando cada etapa. &lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma.jpg&amp;diff=300</id>
		<title>Arquivo:Fluxograma.jpg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma.jpg&amp;diff=300"/>
		<updated>2015-04-21T18:04:45Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: foi enviada uma nova versão de &amp;amp;quot;Arquivo:Fluxograma.jpg&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=299</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=299"/>
		<updated>2015-04-21T18:02:08Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma(1).jpg&amp;diff=298</id>
		<title>Arquivo:Fluxograma(1).jpg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma(1).jpg&amp;diff=298"/>
		<updated>2015-04-21T03:18:11Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=297</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=297"/>
		<updated>2015-04-21T02:55:51Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma(1).jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=296</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=296"/>
		<updated>2015-04-21T02:54:54Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=295</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=295"/>
		<updated>2015-04-21T02:54:07Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma.jpg&amp;diff=294</id>
		<title>Arquivo:Fluxograma.jpg</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=Arquivo:Fluxograma.jpg&amp;diff=294"/>
		<updated>2015-04-21T02:52:19Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=293</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=293"/>
		<updated>2015-04-21T02:51:32Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
[[Arquivo:fluxograma.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=292</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=292"/>
		<updated>2015-04-19T01:32:06Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Np Nx*Ny&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A seguir introduzimos a função principal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=291</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=291"/>
		<updated>2015-04-19T01:25:20Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem eventualmente aparecer à medida que novas funções são implementadas. Abaixo declaramos as funções essenciais ao programa, onde cada uma delas será detalhadamente explicada no decorrer da implementação. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=290</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=290"/>
		<updated>2015-04-19T01:18:01Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem, eventualmente, aparecer à medida &lt;br /&gt;
/***********      declaring functions       ************/&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=289</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=289"/>
		<updated>2015-04-19T01:16:44Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt; dt &amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem, eventualmente, aparecer à medida &lt;br /&gt;
/***********      declaring functions       ************/&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
	<entry>
		<id>http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=288</id>
		<title>DM: um primeiro programa</title>
		<link rel="alternate" type="text/html" href="http://fiscomp.if.ufrgs.br/index.php?title=DM:_um_primeiro_programa&amp;diff=288"/>
		<updated>2015-04-19T01:13:41Z</updated>

		<summary type="html">&lt;p&gt;Gabrielcanova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[EM CONSTRUÇÃO] A seguir mostraremos o passo a passo de como montar o primeiro programa para simulação de dinâmica molecular. A linguagem de programação utilizada será o C. Como um primeiro esboço, podemos organizar o programa da seguinte maneira, onde cada etapa será explicada detalhadamente.&lt;br /&gt;
&lt;br /&gt;
Aqui declaramos quais são as bibliotecas ''standard'' utilizadas do C&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include&amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include&amp;lt;math.h&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Está parte é reservada para declarações de constantes que definem os parâmetros e condições iniciais utilizadas na simulação. As constantes podem ser definidas utilizando-se das diretivas de compilação do C através do comando &amp;quot;#define&amp;quot; ou podem ser lidas a partir de um arquivo externo chamado pelo programa. A vantagem do segundo método é que o programa só precisará ser compilado uma única vez para diferentes condições iniciais. Porém, por simplicidade e clareza, optaremos pelo primeiro caso. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#define Nx 16&lt;br /&gt;
#define Ny 16&lt;br /&gt;
#define Lx 16&lt;br /&gt;
#define Ly 16&lt;br /&gt;
#define dt 0.01&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; N_x \; \mbox{e} \; N_y &amp;lt;/math&amp;gt; representam, respectivamente, o número de partículas nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;. &lt;br /&gt;
&amp;lt;math&amp;gt; L_x \; \mbox{e} \; L_y &amp;lt;/math&amp;gt; representam, respectivamente, o tamanho da rede nas direções &amp;lt;math&amp;gt; x \; \mbox{e} \; y &amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;math&amp;gt;dt&amp;lt;/math&amp;gt; define o intervalo de tempo na simulação.&lt;br /&gt;
&lt;br /&gt;
Conforme o programa é construído, novas constantes podem, eventualmente, aparecer à medida &lt;br /&gt;
/***********      declaring functions       ************/&lt;br /&gt;
void initialize_positions(double *xx, double *yy ) ;&lt;br /&gt;
void initialize_velocities(double *vx, double *vy ) ;&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) ;&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
  /***********  declaring variables    ************/&lt;br /&gt;
  // declara as variaveis necessarias&lt;br /&gt;
  // ex: double *fx ;&lt;br /&gt;
&lt;br /&gt;
  /**********   allocating memory     ************/&lt;br /&gt;
  // aloca a memoria&lt;br /&gt;
  // ex. de alocacao DINAMICA de memoria:&lt;br /&gt;
  // fx  = (double *)malloc( NP * sizeof(double) );  &lt;br /&gt;
  &lt;br /&gt;
  initialize_positions( px, py); &lt;br /&gt;
  initialize_velocities( vx, vy);&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    { ppx[i] = px[i] - vx[i]*deltat;   ppy[i] = py[i] - vy[i]*deltat; } // positions in the initial time &lt;br /&gt;
  &lt;br /&gt;
  tt=0;  iframe=0;&lt;br /&gt;
  // faz um loop no tempo &lt;br /&gt;
  //       chama a funcao que calcula forcas&lt;br /&gt;
  //       chama a funcao que integra as Eqs de movimento&lt;br /&gt;
  //	   incrementa o tempo de simulacao&lt;br /&gt;
  //       a cada intervalo de tempo definido, fazer medidas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void initialize_positions( double *xx, double *yy )&lt;br /&gt;
{&lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   deltax, deltay; &lt;br /&gt;
  &lt;br /&gt;
  deltax = (double)Lx/Nx;   deltay = (double)Ly/Ny;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xx[i] = (i%Nx)*deltax ; &lt;br /&gt;
      yy[i] = (i/Ny)*deltay ;&lt;br /&gt;
      // printf(&amp;quot;%lf %lf   %d \n&amp;quot;, xx[i], yy[i], i);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void initialize_velocities(double *vx, double *vy )&lt;br /&gt;
{ &lt;br /&gt;
  int      i ;&lt;br /&gt;
  double   vcmx, vcmy, v2, fs;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      vx[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vy[i] = (double)rand()/RAND_MAX ;&lt;br /&gt;
      vcmx += vx[i];    vcmy += vy[i];&lt;br /&gt;
      v2 += vx[i]*vx[i] + vy[i]*vy[i] ;  // kinetic energy&lt;br /&gt;
    }&lt;br /&gt;
  vcmx /= NP ;  vcmy /= NP ;  v2 /= NP;&lt;br /&gt;
  fs=sqrt(2*TEMP/v2) ;  // fator de escala -- escolhe uma dada temp T e computa isto : SE escolher uma dist maxwelliana, isto nao eh necessario (me parece)&lt;br /&gt;
  &lt;br /&gt;
  // set the velocity center of mass to zero (linear momentum of the system is zero)&lt;br /&gt;
  // and set its value in such a way that \sum m_i v^2 = Kb T for each degree of freedom&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {  vx[i] = (vx[i] - vcmx)*fs ;         vy[i] = (vy[i]-vcmy)*fs ;  } &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// fx = -dV/dx = -(x/r) (dV/dr)&lt;br /&gt;
// fx= 48x/r² (1/r^12 - 1/r^6) --  LJ in reduced Units&lt;br /&gt;
void compute_forces( double *ffx, double *ffy, double *xx, double *yy, double *eenergia ) &lt;br /&gt;
{&lt;br /&gt;
  int     i, j;&lt;br /&gt;
  double  x1, y1, x2, y2,dxx, dyy, r2, r2i, r6, ff, energia=0.0 ;&lt;br /&gt;
  &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {  ffx[i] = 0.0;    ffy[i] = 0.0; }&lt;br /&gt;
	    &lt;br /&gt;
  for( i=0; i &amp;lt; NP; i++ )&lt;br /&gt;
    {&lt;br /&gt;
      x1  = xx[i];    y1 = yy[i]; &lt;br /&gt;
     for( j=i+1; j &amp;lt; NP; j++ )&lt;br /&gt;
	{&lt;br /&gt;
	  x2  = xx[j];    y2 = yy[j];&lt;br /&gt;
	  &lt;br /&gt;
	  dxx = x1 - x2;          // compute the distance between particles taking into account the periodic boundary conditions   &lt;br /&gt;
	  dxx = fmod(dxx, Lx);  &lt;br /&gt;
	  dxx=dxx-rint(dxx/Lx)*Lx ;   //note: rint(arg) : rounds its argument to the nearest whole number&lt;br /&gt;
		  &lt;br /&gt;
	  dyy = y1 - y2;           &lt;br /&gt;
	  dyy = fmod(dyy, Ly);&lt;br /&gt;
	  dyy=dyy-rint(dyy/Ly)*Ly ;&lt;br /&gt;
	 	  &lt;br /&gt;
	  r2 = dxx*dxx + dyy*dyy ;&lt;br /&gt;
	  if(r2&amp;lt;RC2) // rc2: critical value or r&lt;br /&gt;
	    {&lt;br /&gt;
	      r2i = 1/r2 ;         &lt;br /&gt;
	      r6 = r2i*r2i*r2i;&lt;br /&gt;
	      ff = 48*r2i*r6*(r6-0.5);                         // LJ potential integrated                         &lt;br /&gt;
	      ffx[i] += ff* dxx ;   ffy[i] += ff* dyy   ;      // update forces&lt;br /&gt;
	      ffx[j] -= ff* dxx ;   ffy[j] -= ff* dyy   ;&lt;br /&gt;
	      energia += 4*r6*(r6-1) ;                         // compute energy&lt;br /&gt;
	    }&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
  *eenergia=energia;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void integrate_EqMotion( double *ffx, double *ffy, double *xx, double *yy,  double *xxp, double *yyp, double eenergia, double *energy_pp, double *vxm ) &lt;br /&gt;
{&lt;br /&gt;
  int     i; &lt;br /&gt;
  double  xp, yp, vxi, vyi,  vcmx, vcmy, v2, temp  ;&lt;br /&gt;
&lt;br /&gt;
  vcmx=0.0;  vcmy=0.0;   v2=0.0;&lt;br /&gt;
  for(i = 0; i &amp;lt; NP; i++)&lt;br /&gt;
    {&lt;br /&gt;
      xp = 2*xx[i] - xxp[i] + deltat2 * ffx[i] ;&lt;br /&gt;
      yp = 2*yy[i] - yyp[i] + deltat2 * ffy[i] ;&lt;br /&gt;
      vxi = (xp - xx[i]) / (2*deltat);&lt;br /&gt;
      vyi = (yp - yy[i]) / (2*deltat);&lt;br /&gt;
      &lt;br /&gt;
      vcmx += vxi;    vcmy += vyi;         // to monitor the average velocity&lt;br /&gt;
      v2 += vxi*vxi + vyi*vyi ;            // kinetic energy&lt;br /&gt;
      xxp[i] = xx[i] ;  yyp[i] = yy[i] ;   // update the &amp;quot;previous position&amp;quot;&lt;br /&gt;
      yyp[i] = yy[i] ; &lt;br /&gt;
      xx[i] = xp;                          // update the positions in a current time&lt;br /&gt;
      yy[i] = yp;&lt;br /&gt;
   } &lt;br /&gt;
  temp=v2/(2*NP) ;                         // kbT = &amp;lt; m*v^2 &amp;gt; per degree of freedom&lt;br /&gt;
  *energy_pp=(eenergia + 0.5*v2)/NP;        // energia total = ( U + K ) -- energy per particle =energia/NP&lt;br /&gt;
  *vxm = vcmx /NP ;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Gabrielcanova</name></author>
	</entry>
</feed>