def simulate(env, t=None, r=None): r = r if r is not None else (round(t[0]), round(t[1])) t = t if t is not None else (T(r[0]), T(r[1])) msg = 'Simulation for {}, from {}s ({}) to {}s ({})'.format( env, t[0], r[0], t[1], r[1]) print(msg) with timer() as elapsed_sim: for r in range(r[0], r[1]): if r % 2 == 0: enable_print() else: block_print() t = T(r) print('{}'.format(r)) with timer() as elapsed_loop: for x in env: with timer() as elapsed_calc: x.calculate(r=r) with numpy.printoptions(precision=4, suppress=True): print(' {:180}'.format(x.snapshot(r=r)), end='') print('{:.7f}ms'.format(elapsed_calc() / 1000)) print('{:184}'.format('{} ({}s)'.format(r, t)), end='') print('total: {:.7f}ms'.format(elapsed_loop() / 1000)) enable_print() print('\n', end='') print('ENDED {:178}'.format(msg), end='') print('sim: {:.7f}ms'.format(elapsed_sim() / 1000))
def influence(self, influence, source, t=None, r=None): r = round(t) if t is not None else r if influence not in INFLUENCES: raise NotImplementedError( 'Not implemented for influence "{}"'.format(influence)) if self._d_externals[r] is None: self._d_externals[r] = dict() if self._d_externals[r][influence] is None: self._d_externals[r][influence] = [] self._d_externals[r][influence].append(source)
def externals(self, t=None, r=None): r = round(t) if t is not None else r if r not in self._d_externals: return [] return self._d_externals[r]
def get_variable(self, variable, t=None, r=None): r = round(t) if t is not None else r return getattr(self, '_d_{}'.format(variable))[r]
def snapshot(self, t=None, r=None): r = round(t) if t is not None else r return '{} (pos (Å)={}, vel (Å/fs)={}, acc (Å/fs²)={})'.format( self.id, self.position(r=r, unit=ANGSTROM), self.speed(r=r, unit=ANGSTROM_FEMTOSECOND), self.acceleration(r=r, unit=ANGSTROM_FEMTOSECOND_2))
def calculate(self, t=None, r=None): t = round(t) if t is not None else r if t < 0: raise NotImplementedError('< 0 HAHA') externals = self.externals(r=t) m = self._mass if t == 0: r = self._position v = self._speed a = self._acceleration q = self._charge fi = array(0) else: ti = t - 1 ri = self.position(r=t - 1) vi = self.speed(r=t - 1) ai = self.acceleration(r=t - 1) qi = self.charge(r=t - 1) ''' acho que é a ideia aqui é: as forças intermoleculares - ??? - agem sobre a molecula força é massa vezes aceleração, então a força implica uma aceleracao a aceleracao implica uma velocidade que vai mudar a posicao da molecula ''' # para ligar com as forças intermoleculares eu preciso criar uma mesh # com todos os campos em atuação no instante # na verdade seria um loop por todas as moleculas vizinhas, juntando os vetores de potencial elétrico? # isso ai fi = [ potencial_lennard_jones( self.distance(other, r=t - 1, norm=False)) for other in self.environment if other.id != self.id ] fi = numpy.array(fi) fi = numpy.sum( fi, axis=0) if len(self.environment) > 0 else numpy.zeros(3) f = fi.copy() if 'force' in externals: fe = externals['force'] f += numpy.sum(fe, axis=0) # ok, mas e a carga??? # argonio é um gas inerte, entao ignora isso a = f / m v = vi + a * dt r = ri + v * dt q = qi self._d_position[t] = r self._d_speed[t] = v self._d_acceleration[t] = a self._d_charge[t] = q self._d_intermolecular_interaction[t] = fi
def distance(self, other, t=None, r=None, norm=True): r = round(t) if t is not None else r return self.position(r=r) - other.position( r=r) if not norm else distancia_euclidiana(self.position( r=r), other.position(r=r))