I have a part of a program that I have to repeatedly call many times (about 2000 to 10000 times)
f = Reap[Do[Sow[{0, 0, 0}], {i, 1, nparticle}];][[2, 1]];
vir = 0.;
hL = L/2.;
e = 0.;
Do[
Do[
dr = r[[i]] - r[[j]];
dr = Map[If[# > hL, # - L, If[# < -hL, # + L, #]] &, dr];
r2 = Dot[dr, dr];
If[r2 < rc2,
r6i = 1./(r2^3);
e += 4*(r6i*r6i - r6i) - ecut;
valuef = 48*(r6i*r6i - 0.5*r6i);
df = dr*valuef/r2;
f[[i]] += df;
f[[j]] -= df;
vir += valuef;
];
If[r2 <= rc^2,
gr[[IntegerPart[Sqrt[r2]/dh]]] += 2;
]
, {j, i + 1, nparticle}
];
, {i, 1, nparticle - 1}
];
r is a list of the form {{3,4,6},{5,7,8},.....}.
hL, L, rc2 are parameter I initialize at the start.
Is there any ways I can optimize the code like using compile
or parallelization
? I have tried these but always getting various kinds of errors or wrong calculations.
Is the two Do
loops avoidable in this case?
As requested, here is the value of parameters:
rc = 2.5;
rc2 = rc^2;
nparticle = 108;
rho = 0.4;
L = (nparticle/rho)^(1./3.);
hL = 0.5*L;
rr3 = 1/(rc^3);
ecut = 4.*(rr3^4 - rr3^2);
The initialization of r:
LinCell = Round[(nparticle/4.)^(1./3.)];
lattconst = L/LinCell;
r = Reap[
Do[
Do[
Do[
Sow[{ix + 0.25, iy + 0.25, iz + 0.25}*lattconst];
Sow[{ix + 0.75, iy + 0.75, iz + 0.25}*lattconst];
Sow[{ix + 0.75, iy + 0.25, iz + 0.75}*lattconst];
Sow[{ix + 0.25, iy + 0.75, iz + 0.75}*lattconst];
, {iz, 0, LinCell - 1}
];
, {iy, 0, LinCell - 1}
];
, {ix, 0, LinCell - 1}
];
][[2, 1]];
--edit-- Now I need to add an output to the program
If[r2 <= rc^2,
gr[[IntegerPart[Sqrt[r2]/dh]]] += 2;
]
which is added to the inner the Do
loop. (I have modified the above code)
gr is initialized to {0,0,0,...}.
dh=0.02