def _init_self_interaction_lib(self): if self.shared_memory in ('thread', 'omp'): PL = loop.ParticleLoopOMP else: PL = loop.ParticleLoop with open(str(_SRC_DIR) + '/EwaldOrthSource/SelfInteraction.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = (kernel.Header(block=_cont_header_src % self._subvars), ) with open(str(_SRC_DIR) + '/EwaldOrthSource/SelfInteraction.cpp', 'r') as fh: _cont_source = fh.read() _real_kernel = kernel.Kernel(name='self_interaction_part', code=_cont_source, headers=_cont_header) self._self_interaction_lib = PL( kernel=_real_kernel, dat_dict={ 'Q': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'u': self._vars['self_interaction_energy'](access.INC_ZERO) }) with open( str(_SRC_DIR) + '/EwaldOrthSource/SelfInteractionPot.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = (kernel.Header(block=_cont_header_src % self._subvars), ) with open( str(_SRC_DIR) + '/EwaldOrthSource/SelfInteractionPot.cpp', 'r') as fh: _cont_source = fh.read() _real_kernel = kernel.Kernel(name='self_interaction_part_pot', code=_cont_source, headers=_cont_header) self._self_interaction_pot_lib = PL( kernel=_real_kernel, dat_dict={ 'Q': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'UPP': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.INC), 'u': self._vars['self_interaction_energy'](access.INC_ZERO) })
def __init__(self, state, size=0, v0=None): self._state = state self._V0 = data.ParticleDat(self._state.npart_local, 3, name='v0') self._VT = state.velocities self._VO_SET = False if v0 is not None: self.set_v0(v0) else: self.set_v0(state=self._state) self._VAF = data.ScalarArray(ncomp=1) self._V = [] self._T = [] _headers = ['stdio.h'] _constants = None _kernel_code = ''' VAF(0) += (v0(0)*VT(0) + v0(1)*VT(1) + v0(2)*VT(2))*Ni; ''' _reduction = (kernel.Reduction('VAF', 'VAF[I]', '+'), ) _static_args = {'Ni': ctypes.c_double} _kernel = kernel.Kernel('VelocityAutocorrelation', _kernel_code, _constants, _headers, _reduction, _static_args) self._datdict = {'VAF': self._VAF, 'v0': self._V0, 'VT': self._VT} self._loop = loop.ParticleLoop(self._state.as_func('npart_local'), None, kernel=_kernel, dat_dict=self._datdict)
def _init_near_potential_lib(self): # real space energy and force kernel with open( str(_SRC_DIR) + '/EwaldOrthSource/EvaluateNearPotentialField.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = (kernel.Header(block=_cont_header_src % self._subvars), ) with open( str(_SRC_DIR) + '/EwaldOrthSource/EvaluateNearPotentialField.cpp', 'r') as fh: _cont_source = fh.read() _real_kernel = kernel.Kernel(name='real_space_part', code=_cont_source, headers=_cont_header) if self.shell_width is None: rn = self.real_cutoff * 1.05 else: rn = self.real_cutoff + self.shell_width PPL = pairloop.CellByCellOMP self._near_potential_field = PPL( kernel=_real_kernel, dat_dict={ 'P': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.READ), 'Q': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'M': data.ParticleDat(ncomp=1, dtype=ctypes.c_int)(access.READ), 'u': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.INC), }, shell_cutoff=rn)
def _init_real_space_lib(self): # real space energy and force kernel with open( str(_SRC_DIR) + '/EwaldOrthSource/RealSpaceForceEnergy.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = (kernel.Header(block=_cont_header_src % self._subvars), ) with open( str(_SRC_DIR) + '/EwaldOrthSource/RealSpaceForceEnergy.cpp', 'r') as fh: _cont_source = fh.read() _real_kernel = kernel.Kernel(name='real_space_part', code=_cont_source, headers=_cont_header) if self.shell_width is None: rn = self.real_cutoff * 1.05 else: rn = self.real_cutoff + self.shell_width if self.shared_memory in ('thread', 'omp'): PPL = pairloop.PairLoopNeighbourListNSOMP else: PPL = pairloop.PairLoopNeighbourListNS self._real_space_pairloop = PPL( kernel=_real_kernel, dat_dict={ 'P': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.READ), 'Q': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'F': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.INC), 'u': self._vars['real_space_energy'](access.INC_ZERO) }, shell_cutoff=rn) # real space energy and force kernel and per particle potential with open( str(_SRC_DIR) + '/EwaldOrthSource/RealSpaceForceEnergyPot.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = (kernel.Header(block=_cont_header_src % self._subvars), ) with open( str(_SRC_DIR) + '/EwaldOrthSource/RealSpaceForceEnergyPot.cpp', 'r') as fh: _cont_source = fh.read() _real_kernel = kernel.Kernel(name='real_space_part_pot', code=_cont_source, headers=_cont_header) self._real_space_pairloop_pot = PPL( kernel=_real_kernel, dat_dict={ 'P': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.READ), 'Q': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'UPP': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.INC), 'F': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.INC), 'u': self._vars['real_space_energy'](access.INC_ZERO) }, shell_cutoff=rn)
def _init_libs(self): # reciprocal contribution calculation with open(str(_SRC_DIR) + '/EwaldOrthSource/AccumulateRecip.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = kernel.Header(block=_cont_header_src % self._subvars) with open(str(_SRC_DIR) + '/EwaldOrthSource/AccumulateRecip.cpp', 'r') as fh: _cont_source = fh.read() _cont_kernel = kernel.Kernel(name='reciprocal_contributions', code=_cont_source, headers=_cont_header) if self.shared_memory in ('thread', 'omp'): PL = loop.ParticleLoopOMP else: PL = loop.ParticleLoop self._cont_lib = PL( kernel=_cont_kernel, dat_dict={ 'Positions': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.READ), 'Charges': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'RecipSpace': self._vars['recip_space_kernel'](access.INC_ZERO) }) # reciprocal extract forces plus energy with open( str(_SRC_DIR) + '/EwaldOrthSource/ExtractForceEnergy.h', 'r') as fh: _cont_header_src = fh.read() _cont_header = kernel.Header(block=_cont_header_src % self._subvars) with open( str(_SRC_DIR) + '/EwaldOrthSource/ExtractForceEnergy.cpp', 'r') as fh: _cont_source = fh.read() _cont_kernel = kernel.Kernel(name='reciprocal_force_energy', code=_cont_source, headers=_cont_header) self._extract_force_energy_lib = PL( kernel=_cont_kernel, dat_dict={ 'Positions': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.READ), 'Forces': data.ParticleDat(ncomp=3, dtype=ctypes.c_double)(access.INC), 'Energy': self._vars['recip_space_energy'](access.INC_ZERO), 'Charges': data.ParticleDat(ncomp=1, dtype=ctypes.c_double)(access.READ), 'RecipSpace': self._vars['recip_space_kernel'](access.READ), 'CoeffSpace': self._vars['coeff_space_kernel'](access.READ) }) self._extract_force_energy_pot_lib = None
def __init__(self, state, types, boundary_condition, cutoff, interaction_func): """ Main class for non-bonded interactions. Interactions are specificed by a C function that implements the following function. See DL_MONTE example for a Lennard-Jones example. double POINT_EVAL( const double rix, charge_i x component. const double riy, charge_i y component. const double riz, charge_i z component. const double rjx, charge_j x component. const double rjy, charge_j y component. const double rjz, charge_j z component. const double dt0, charge_i type (cast to double). const double dt1 charge_j type (cast to double). ); :arg state: PPMD State instance. :arg types: ParticleDat (ncomp=1, dtype=int64_t) of particle types. :arg boundary_condition: Currently only 'pbc' is implemented. :arg cutoff: float, Short range cutoff. :arg interaction_func: str, that implements the interaction function. """ self.group = state self.domain = state.domain # dats self.positions = state.get_position_dat() self.types = types state._nbd_cells = data.ParticleDat(ncomp=3, dtype=INT64) self.cells = state._nbd_cells self.cutoff = cutoff self.boundary_condition = BCType(boundary_condition) self.sh = pairloop.state_handler.StateHandler(state=state, shell_cutoff=cutoff, pair=False) self.interaction_func = interaction_func assert self.boundary_condition == BCType.PBC s = [int(math.floor(ex / (cutoff*1.01))) for ex in self.domain.extent] for sz in s: assert sz > 0, "cutoff larger than domain extent" assert len(s) == 3 self.s = s self.swidths = [ex / sx for ex, sx in zip(self.domain.extent, s)] self.cell_occupation = np.zeros((s[2], s[1], s[0]), INT64) self._ptr_cell_occupation = self.cell_occupation.ctypes.get_as_parameter() self.cell_indices = np.zeros((s[2], s[1], s[0], 10), INT64) self._ptr_cell_indices = self.cell_indices.ctypes.get_as_parameter() self.max_occupancy = None self._eval_pos = np.zeros(3, REAL) self._eval_cell = np.zeros(3, INT64) self._ptr_eval_pos = self._eval_pos.ctypes.get_as_parameter() self._ptr_eval_cell = self._eval_cell.ctypes.get_as_parameter() self.direct_map = {} self._offset_map = np.zeros((27, 3), INT64) o = (-1, 0, 1) self._offset_map[:] = tuple(product(o,o,o)) self._ptr_offset_map = self._offset_map.ctypes.get_as_parameter() self._ga_energy = data.GlobalArray(ncomp=1, dtype=REAL) self.energy = None self._energy_pairloop = self._generate_pairloop() self.lib = self._generate_lib()
def draw(self): """ Update current plot, use for real time plotting. """ if _GRAPHICS: self._N = self._state.npart_local self._NT = self._state.npart self._extents = self._state.domain.extent '''Case where all particles are local''' if _MPISIZE == 1: self._pos = self._state.positions self._gid = self._state.global_ids else: '''Need an mpi handle if not all particles are local''' '''Allocate if needed''' if self._Dat is None: self._Dat = data.ParticleDat(self._NT, 3) else: self._Dat.resize(self._NT) if self._gids is None: self._gids = data.ScalarArray(ncomp=self._NT, dtype=ctypes.c_int) else: self._gids.resize(self._NT) _MS = mpi.Status() if _MPIRANK == 0: '''Copy the local data.''' self._Dat.data[ 0:self._N:, ::] = self._state.positions.data[ 0:self._N:, ::] self._gids.data[0:self._N:] = self._state.global_ids.data[ 0:self._N:, 0] _i = self._N # starting point pos _ig = self._N # starting point gids for ix in range(1, _MPISIZE): _MPIWORLD.Recv(self._Dat.data[_i::, ::], ix, ix, _MS) _i += _MS.Get_count(mpi.mpi_map[self._Dat.dtype]) // 3 _MPIWORLD.Recv(self._gids.data[_ig::], ix, ix, _MS) _ig += _MS.Get_count(mpi.mpi_map[self._gids.dtype]) self._pos = self._Dat self._gid = self._gids else: _MPIWORLD.Send(self._state.positions.data[0:self._N:, ::], 0, _MPIRANK) _MPIWORLD.Send(self._state.global_ids.data[0:self._N:], 0, _MPIRANK) if _MPIRANK == 0: plt.cla() plt.ion() for ix in range(self._pos.npart_local): self._ax.scatter(self._pos.data[ix, 0], self._pos.data[ix, 1], self._pos.data[ix, 2], color=self._key[self._gid[ix] % 2]) if _MPISIZE == 1: self._ax.plot( (self._pos.data[ix, 0], self._pos.data[ix, 0] + self.norm_vec(self._state.forces.data[ix, 0])), (self._pos.data[ix, 1], self._pos.data[ix, 1] + self.norm_vec(self._state.forces.data[ix, 1])), (self._pos.data[ix, 2], self._pos.data[ix, 2] + self.norm_vec(self._state.forces.data[ix, 2])), color=self._key[self._gid[ix] % 2], linewidth=2) self._ax.set_xlim( [-0.5 * self._extents[0], 0.5 * self._extents[0]]) self._ax.set_ylim( [-0.5 * self._extents[1], 0.5 * self._extents[1]]) self._ax.set_zlim( [-0.5 * self._extents[2], 0.5 * self._extents[2]]) self._ax.set_xlabel('x') self._ax.set_ylabel('y') self._ax.set_zlabel('z') plt.draw() plt.show(block=False)