@@ -9,7 +9,7 @@ from loguru import logger
99
1010from .. import name_patch
1111from ..model cimport Vector, Node, StateDict, null_
12- from ..language.functions cimport normal
12+ from ..language.functions cimport normal, uniform
1313
1414from libc.math cimport sqrt, isinf, isnan, abs , floor
1515from cpython cimport PyObject
@@ -28,8 +28,25 @@ cdef Vector VELOCITY = Vector._symbol('velocity')
2828cdef Vector CLOCK = Vector._symbol(' clock' )
2929cdef Vector RUN = Vector._symbol(' run' )
3030
31- cdef normal RandomSource = normal(' _physics' )
32- cdef unsigned long long RandomIndex = 0
31+ cdef normal NormalRandomSource = normal(Vector.symbol(' _physics_normal' ))
32+ cdef unsigned long long NormalRandomIndex = 0
33+
34+ cdef uniform UniformRandomSource = uniform(Vector.symbol(' _physics_uniform' ))
35+ cdef unsigned long long UniformRandomIndex = 0
36+
37+
38+ cdef inline double random_normal() nogil:
39+ global NormalRandomSource, NormalRandomIndex
40+ cdef double d = NormalRandomSource._item(NormalRandomIndex)
41+ NormalRandomIndex += 1
42+ return d
43+
44+
45+ cdef inline double random_uniform() nogil:
46+ global UniformRandomSource, UniformRandomIndex
47+ cdef double d = UniformRandomSource._item(UniformRandomIndex)
48+ UniformRandomIndex += 1
49+ return d
3350
3451
3552cdef class Particle:
@@ -252,8 +269,7 @@ cdef class RandomForceApplier(ParticleForceApplier):
252269 global RandomIndex
253270 cdef long i
254271 for i in range (particle.force.length):
255- particle.force.numbers[i] = particle.force.numbers[i] + self .strength * RandomSource._item(RandomIndex)
256- RandomIndex += 1
272+ particle.force.numbers[i] = particle.force.numbers[i] + self .strength * random_normal()
257273
258274
259275cdef class CollisionForceApplier(MatrixPairForceApplier):
@@ -446,7 +462,8 @@ cdef class PhysicsSystem:
446462 time_vector.allocate_numbers(1 )
447463 time_vector.numbers[0 ] = start_time
448464 state.set_item(state_prefix, time_vector)
449- cdef bint extra_frame = performance > 1 and not slow_frame
465+ cdef double behind = (time - start_time - clock) / resolution
466+ cdef bint extra_frame = performance > 1 and not slow_frame and random_uniform() > min (100 / behind, 0.9 )
450467 if time > start_time + clock:
451468 clock = await asyncio.to_thread(self .calculate, particles, non_anchors, particle_forces, matrix_forces, specific_forces, barriers,
452469 dimensions, engine.realtime, extra_frame, speed_of_light, time, start_time, resolution, clock)
0 commit comments