Created
December 23, 2011 20:51
-
-
Save michaelsbradleyjr/1515326 to your computer and use it in GitHub Desktop.
Monte Poly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Particle definitions | |
# "Particle" serves as the base class, and we'll define specific particle types | |
# as subclasses | |
exports.Particle = class Particle | |
constructor: (@id) -> | |
@alreadyCalcCE = {} | |
name: 'unnamed' | |
charge: 0 | |
dipole: 0 | |
class P extends Particle | |
name: 'p' | |
class Pplus extends Particle | |
name: 'p+' | |
charge: 1 | |
class N extends Particle | |
name: 'n' | |
charge: 1 | |
class C extends Particle | |
name: 'c' | |
charge: -1 | |
class U extends Particle | |
name: 'u' | |
dipole: 4.56 | |
# O is really an empty site, or water | |
# Do we need to consider its dipole moment? | |
class O extends Particle | |
name: 'o' | |
# Keep a "list" of all the types as an attribute of the Particle constructor | |
# If another subclass is defined above, remember to add it to this list | |
Particle.types = [ P, Pplus, N, C, U, O ] | |
# Lattice definition | |
exports.Lattice = class Lattice | |
constructor: (@h, @w) -> | |
@nextId = nextId = (-> | |
counter = 0 | |
-> ++counter | |
)() | |
@population = [] | |
for i in [0...@h] | |
@population.push [] | |
for j in [0...@w] | |
@population[i].push new Particle.types[ Math.floor ( Math.random() * Particle.types.length ) ] nextId() | |
coulombEnergy: -> | |
sum = 0 | |
counter = 0 | |
for i in [0...@h] | |
for j in [0...@w] | |
itself = @population[i][j] | |
iCharge = itself.charge | |
iId = itself.id | |
if iCharge isnt 0 | |
for k in [0...@h] | |
for l in [0...@w] | |
other = @population[k][l] | |
oCharge = other.charge | |
oId = other.id | |
if ((itself isnt other) and (oCharge isnt 0)) | |
if not other.alreadyCalcCE[iId]? | |
counter += 1 | |
itself.alreadyCalcCE[oId] = other | |
sum += ( iCharge * oCharge ) / ( Math.abs ( -10000 ) ) | |
else | |
delete other.alreadyCalcCE[iId] | |
null | |
null | |
null | |
null | |
console.log 'this many calcs: ' + counter | |
sum | |
# helpers for Duff's Device (experimental CoffeeScript adaptation) | |
# See: http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html | |
doWhile = (func, condition) -> | |
func() | |
func() while condition() | |
doWhile_8 = (func, condition) -> | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
while condition() | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
func() | |
# for larger lattices, this "Duff's Device" implementation is faster and more | |
# memory efficient | |
coulombEnergy_duff: -> | |
values = @population | |
sum = 0 | |
counter = 0 | |
i = 0 | |
inner_1 = -> | |
ival_1 = values[i++] | |
j = 0 | |
inner_2 = -> | |
itself = ival_1[j++] | |
iCharge = itself.charge | |
iId = itself.id | |
if iCharge isnt 0 | |
k = 0 | |
inner_3 = -> | |
ival_2 = values[k++] | |
l = 0 | |
inner_4 = -> | |
other = ival_2[l++] | |
oCharge = other.charge | |
oId = other.id | |
if ((itself isnt other) and (oCharge isnt 0)) | |
if not other.alreadyCalcCE[iId]? | |
counter += 1 | |
itself.alreadyCalcCE[oId] = other | |
sum += ( iCharge * oCharge ) / ( Math.abs ( -10000 ) ) | |
else | |
delete other.alreadyCalcCE[iId] | |
undefined | |
cond_4_a = -> | |
--lovr_4 > 0 | |
cond_4_b = -> | |
--iter_4 > 0 | |
iter_4 = Math.floor (ival_2.length / 8) | |
lovr_4 = ival_2.length % 8 | |
if lovr_4 > 0 | |
doWhile inner_4, cond_4_a | |
doWhile_8 inner_4, cond_4_b | |
undefined | |
cond_3_a = -> | |
--lovr_3 > 0 | |
cond_3_b = -> | |
--iter_3 > 0 | |
iter_3 = Math.floor (values.length / 8) | |
lovr_3 = values.length % 8 | |
if lovr_3 > 0 | |
doWhile inner_3, cond_3_a | |
doWhile_8 inner_3, cond_3_b | |
undefined | |
cond_2_a = -> | |
--lovr_2 > 0 | |
cond_2_b = -> | |
--iter_2 > 0 | |
iter_2 = Math.floor (ival_1.length / 8) | |
lovr_2 = ival_1.length % 8 | |
if lovr_2 > 0 | |
doWhile inner_2, cond_2_a | |
doWhile_8 inner_2, cond_2_b | |
undefined | |
cond_1_a = -> | |
--lovr_1 > 0 | |
cond_1_b = -> | |
--iter_1 > 0 | |
iter_1 = Math.floor (values.length / 8) | |
lovr_1 = values.length % 8 | |
if lovr_1 > 0 | |
doWhile inner_1, cond_1_a | |
doWhile_8 inner_1, cond_1_b | |
console.log 'this many calcs: ' + counter | |
sum |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment