def bbgky_noneqm(self, times, **odeint_kwargs): """ Evolves the BBGKY dynamics for selected phase points call with bbgky(t), where t is an array of times returns the "nonequilibrium" field correlations i.e. correlations w.r.t. the initial field """ N = self.latsize if type(times).__module__ == np.__name__ : #An empty grid of size N X nalphas #Each element of this list is a dataset localdata = [[None for f in range(self.local_atoms.size)] \ for kvec in self.kvecs] if pbar_avail: if self.comm.rank == root and self.verbose: pbar_max = \ self.kvecs.shape[0] * self.local_atoms.size * nalphas - 1 bar = progressbar.ProgressBar(widgets=widgets_bbgky,\ max_value=pbar_max, redirect_stdout=False) bar_pos = 0 if self.verbose and pbar_avail and self.comm.rank == root: bar.update(bar_pos) for tpl, mth_atom in np.ndenumerate(self.local_atoms): (atom_count,) = tpl corrs_summedover_alpha = \ np.zeros((self.kvecs.shape[0], times.size), \ dtype=np.complex_) for alpha in xrange(nalphas): s_t = odeint(lindblad_bbgky_pywrap, \ mth_atom.state[alpha], times, args=(self,), Dfun=None, **odeint_kwargs) (s_t, info) = s_t if type(s_t) is tuple else (s_t, None) #Update the final state self.local_atoms[atom_count].state[alpha] = s_t[-1] for kcount in xrange(self.kvecs.shape[0]): self.kvec = self.kvecs[kcount] corrs_summedover_alpha[kcount] += \ self.field_correlations(times, alpha, s_t[:,0:3*N], mth_atom) if self.verbose and pbar_avail and self.comm.rank == root: bar.update(bar_pos) localdata[kcount][atom_count] = corrs_summedover_alpha[kcount] bar_pos += 1 duplicate_comm = Intracomm(self.comm) alldata = np.array([None for i in self.kvecs]) for kcount in xrange(self.kvecs.shape[0]): localsum_data = np.sum(np.array(localdata[kcount]), axis=0) if self.comm.size == 1: alldata[kcount] = localsum_data else: alldata[kcount] = duplicate_comm.reduce(localsum_data, root=root) if self.comm.rank == root: alldata /= self.corr_norm if self.verbose and self.comm.rank == root: print("Integrator info:") pprint(info) return alldata
def __init__(self): """Constructor, tries to import mpi4py and reductions.""" try: from mpi4py import MPI self.comm = MPI.COMM_WORLD self._node_ID = self.find_node_ID() node_IDs = self.comm.allgather(self._node_ID) node_IDs_no_duplicates = [] for ID in node_IDs: if not (ID in node_IDs_no_duplicates): node_IDs_no_duplicates.append(ID) self._num_nodes = len(node_IDs_no_duplicates) # Must use custom_comm for reduce commands! This is # more scalable, see reductions.py for more details from reductions import Intracomm self.custom_comm = Intracomm(self.comm) # To adjust number of procs, use submission script/mpiexec self._num_MPI_workers = self.comm.Get_size() self._rank = self.comm.Get_rank() if self._num_MPI_workers > 1: self.distributed = True else: self.distributed = False except ImportError: self._num_nodes = 1 self._num_MPI_workers = 1 self._rank = 0 self.comm = None self.distributed = False
def sum_reduce_all_data(param, datalist_loc, t, mpcomm): """ Does the parallel sum reduction of all data """ #Do local sums sx_locsum = np.sum(data.sx for data in datalist_loc) sy_locsum = np.sum(data.sy for data in datalist_loc) sz_locsum = np.sum(data.sz for data in datalist_loc) sxvar_locsum = np.sum(data.sxvar for data in datalist_loc) syvar_locsum = np.sum(data.syvar for data in datalist_loc) szvar_locsum = np.sum(data.szvar for data in datalist_loc) sxyvar_locsum = np.sum(data.sxyvar for data in datalist_loc) sxzvar_locsum = np.sum(data.sxzvar for data in datalist_loc) syzvar_locsum = np.sum(data.syzvar for data in datalist_loc) #Only root processor will actually get the data sx_totals = np.zeros_like(sx_locsum) if mpcomm.rank == root\ else None sy_totals = np.zeros_like(sy_locsum) if mpcomm.rank == root\ else None sz_totals = np.zeros_like(sz_locsum) if mpcomm.rank == root\ else None sxvar_totals = np.zeros_like(sxvar_locsum) if mpcomm.rank == root\ else None syvar_totals = np.zeros_like(syvar_locsum) if mpcomm.rank == root\ else None szvar_totals = np.zeros_like(szvar_locsum) if mpcomm.rank == root\ else None sxyvar_totals = np.zeros_like(sxyvar_locsum) if mpcomm.rank == root\ else None sxzvar_totals = np.zeros_like(sxzvar_locsum) if mpcomm.rank == root\ else None syzvar_totals = np.zeros_like(syzvar_locsum) if mpcomm.rank == root\ else None #To prevent conflicts with other comms duplicate_comm = Intracomm(mpcomm) sx_totals = duplicate_comm.reduce(sx_locsum, root=root) sy_totals = duplicate_comm.reduce(sy_locsum, root=root) sz_totals = duplicate_comm.reduce(sz_locsum, root=root) sxvar_totals = duplicate_comm.reduce(sxvar_locsum, root=root) syvar_totals = duplicate_comm.reduce(syvar_locsum, root=root) szvar_totals = duplicate_comm.reduce(szvar_locsum, root=root) sxyvar_totals = duplicate_comm.reduce(sxyvar_locsum, root=root) sxzvar_totals = duplicate_comm.reduce(sxzvar_locsum, root=root) syzvar_totals = duplicate_comm.reduce(syzvar_locsum, root=root) if mpcomm.rank == root: return OutData(t, sx_totals, sy_totals, sz_totals, sxvar_totals, \ syvar_totals, szvar_totals, sxyvar_totals, sxzvar_totals,\ syzvar_totals, param) else: return None
def sum_reduce_all_data(param, datalist_loc, t, mpcomm): """ Does the parallel sum reduction of all data """ # Do local sums sx_locsum = np.sum(data.sx for data in datalist_loc) sy_locsum = np.sum(data.sy for data in datalist_loc) sz_locsum = np.sum(data.sz for data in datalist_loc) sxvar_locsum = np.sum(data.sxvar for data in datalist_loc) syvar_locsum = np.sum(data.syvar for data in datalist_loc) szvar_locsum = np.sum(data.szvar for data in datalist_loc) sxyvar_locsum = np.sum(data.sxyvar for data in datalist_loc) sxzvar_locsum = np.sum(data.sxzvar for data in datalist_loc) syzvar_locsum = np.sum(data.syzvar for data in datalist_loc) # Only root processor will actually get the data sx_totals = np.zeros_like(sx_locsum) if mpcomm.rank == root else None sy_totals = np.zeros_like(sy_locsum) if mpcomm.rank == root else None sz_totals = np.zeros_like(sz_locsum) if mpcomm.rank == root else None sxvar_totals = np.zeros_like(sxvar_locsum) if mpcomm.rank == root else None syvar_totals = np.zeros_like(syvar_locsum) if mpcomm.rank == root else None szvar_totals = np.zeros_like(szvar_locsum) if mpcomm.rank == root else None sxyvar_totals = np.zeros_like(sxyvar_locsum) if mpcomm.rank == root else None sxzvar_totals = np.zeros_like(sxzvar_locsum) if mpcomm.rank == root else None syzvar_totals = np.zeros_like(syzvar_locsum) if mpcomm.rank == root else None # To prevent conflicts with other comms duplicate_comm = Intracomm(mpcomm) sx_totals = duplicate_comm.reduce(sx_locsum, root=root) sy_totals = duplicate_comm.reduce(sy_locsum, root=root) sz_totals = duplicate_comm.reduce(sz_locsum, root=root) sxvar_totals = duplicate_comm.reduce(sxvar_locsum, root=root) syvar_totals = duplicate_comm.reduce(syvar_locsum, root=root) szvar_totals = duplicate_comm.reduce(szvar_locsum, root=root) sxyvar_totals = duplicate_comm.reduce(sxyvar_locsum, root=root) sxzvar_totals = duplicate_comm.reduce(sxzvar_locsum, root=root) syzvar_totals = duplicate_comm.reduce(syzvar_locsum, root=root) if mpcomm.rank == root: return OutData( t, sx_totals, sy_totals, sz_totals, sxvar_totals, syvar_totals, szvar_totals, sxyvar_totals, sxzvar_totals, syzvar_totals, param, ) else: return None
def dtwa_bbgky(self, time_info, sampling, **odeint_kwargs): comm = self.comm old_settings = np.seterr(all='ignore') #Prevent overflow warnings N = self.latsize rank = comm.rank if rank == root and self.verbose: pprint("# Run parameters:") #Copy params to another object, then delete #the output that you don't want printed out = copy.copy(self) out.dsdotdg = 0.0 out.delta_eps_tensor = 0.0 out.jmat = 0.0 out.deltamn = 0.0 pprint(vars(out), depth=2) if rank == root and not self.verbose: pprint("# Starting run ...") if type(time_info) is tuple: (t_init, t_final, n_steps) = time_info dt = (t_final-t_init)/(n_steps-1.0) t_output = np.arange(t_init, t_final, dt) elif type(time_info) is list or np.ndarray: t_output = time_info elif rank == root: print("Please enter either a tuple or a list for the time interval") exit(0) else: exit(0) #Let each process get its chunk of n_t by round robin nt_loc = 0 iterator = rank while iterator < self.n_t: nt_loc += 1 iterator += comm.size if pbar_avail: if self.comm.rank == root and self.verbose: pbar_max = nt_loc-1 bar = progressbar.ProgressBar(widgets=widgets_bbgky,\ max_value=pbar_max, redirect_stdout=False) #Scatter unique seeds for generating unique random number arrays : #each processor gets its own nt_loc seeds, and allocates nt_loc #initial conditions. Each i.c. is a 2N sized array #now, each process sends its value of nt_loc to root all_ntlocs = comm.gather(nt_loc, root=root) #Let the root process initialize nt unique integers for random seeds if rank == root: all_seeds = np.arange(self.n_t, dtype=np.int64)+1 all_ntlocs = np.array(all_ntlocs) all_displacements = np.roll(np.cumsum(all_ntlocs), root+1) all_displacements[root] = 0 # First displacement else: all_seeds = None all_displacements = None local_seeds = np.zeros(nt_loc, dtype=np.int64) #Root scatters nt_loc sized seed data to that particular process comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\ MPI.DOUBLE],local_seeds) list_of_local_data = [] if self.verbose: list_of_dhwdt_abs2 = [] for runcount in xrange(0, nt_loc, 1): s_init_spins, s_init_corrs = sample(self, sampling, \ local_seeds[runcount] + self.seed_offset) #Redirect unwanted stdout warning messages to /dev/null with stdout_redirected(): if self.jac: s = odeint(func_dtwa_bbgky, \ np.concatenate((s_init_spins, s_init_corrs)), t_output, \ args=(self,), Dfun=jac_dtwa_bbgky, **odeint_kwargs) else: s = odeint(func_dtwa_bbgky, \ np.concatenate((s_init_spins, s_init_corrs)),t_output, \ args=(self,), Dfun=None, **odeint_kwargs) (s, info) = s if type(s) is tuple else (s, None) #Computes |dH/dt|^2 for a particular alphavec & weighes it #If the rms over alphavec of these are 0, then each H is const if self.verbose: hws = weyl_hamilt(s,t_output, self) dhwdt = np.array([t_deriv(hw, t_output) for hw in hws]) dhwdt_abs2 = np.square(dhwdt) list_of_dhwdt_abs2.extend(dhwdt_abs2) s = np.array(s, dtype="float128")#Widen memory to reduce overflows localdata = bbgky_observables(t_output, s, self) list_of_local_data.append(localdata) if self.verbose and pbar_avail and self.comm.rank == root: bar.update(runcount) #After loop above sum reduce (don't forget to average) all locally #calculated expectations at each time to root outdat = \ sum_reduce_all_data(self, list_of_local_data, t_output, comm) if self.verbose: dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0) dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\ if rank == root else None temp_comm = Intracomm(comm) dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root) if rank == root: dhwdt_abs2_totals = dhwdt_abs2_totals/(self.n_t * N * N) dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals) if rank == root: outdat.normalize_data(self.n_t, N) if self.verbose: print(" ") print("Integration output info:") pprint(info) print("\nt-deriv of Hamilt (abs square) with wigner avg: ") print(" ") print(tabulate({"time": t_output, \ "dhwdt_abs": dhwdt_abs_totals}, \ headers="keys", floatfmt=".6f")) if self.jac and self.verbose: print('# Cumulative number of Jacobian evaluations by root:', \ np.sum(info['nje'])) print('# Done!') np.seterr(**old_settings) # reset to default return outdat else: np.seterr(**old_settings) # reset to default return None
def setUp(self): self.comm = Intracomm(MPI.COMM_WORLD.Dup())
class TestWD(BaseTest, unittest.TestCase): def setUp(self): self.comm = Intracomm(MPI.COMM_WORLD.Dup()) def tearDown(self): self.comm.Free()
def setUp(self): self.comm = Intracomm(MPI.COMM_SELF.Dup())
def dtwa_bbgky(self, time_info, sampling, **odeint_kwargs): comm = self.comm old_settings = np.seterr(all='ignore') #Prevent overflow warnings N = self.latsize rank = comm.rank if rank == root and self.verbose: pprint("# Run parameters:") #Copy params to another object, then delete #the output that you don't want printed out = copy.copy(self) out.dsdotdg = 0.0 out.delta_eps_tensor = 0.0 out.jmat = 0.0 out.deltamn = 0.0 pprint(vars(out), depth=2) if rank == root and not self.verbose: pprint("# Starting run ...") if type(time_info) is tuple: (t_init, t_final, n_steps) = time_info dt = (t_final - t_init) / (n_steps - 1.0) t_output = np.arange(t_init, t_final, dt) elif type(time_info) is list or np.ndarray: t_output = time_info elif rank == root: print( "Please enter either a tuple or a list for the time interval") exit(0) else: exit(0) #Let each process get its chunk of n_t by round robin nt_loc = 0 iterator = rank while iterator < self.n_t: nt_loc += 1 iterator += comm.size if pbar_avail: if self.comm.rank == root and self.verbose: pbar_max = nt_loc - 1 bar = progressbar.ProgressBar(widgets=widgets_bbgky,\ max_value=pbar_max, redirect_stdout=False) #Scatter unique seeds for generating unique random number arrays : #each processor gets its own nt_loc seeds, and allocates nt_loc #initial conditions. Each i.c. is a 2N sized array #now, each process sends its value of nt_loc to root all_ntlocs = comm.gather(nt_loc, root=root) #Let the root process initialize nt unique integers for random seeds if rank == root: all_seeds = np.arange(self.n_t, dtype=np.int64) + 1 all_ntlocs = np.array(all_ntlocs) all_displacements = np.roll(np.cumsum(all_ntlocs), root + 1) all_displacements[root] = 0 # First displacement else: all_seeds = None all_displacements = None local_seeds = np.zeros(nt_loc, dtype=np.int64) #Root scatters nt_loc sized seed data to that particular process comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\ MPI.DOUBLE],local_seeds) list_of_local_data = [] if self.verbose: list_of_dhwdt_abs2 = [] for runcount in xrange(0, nt_loc, 1): s_init_spins, s_init_corrs = sample(self, sampling, \ local_seeds[runcount] + self.seed_offset) #Redirect unwanted stdout warning messages to /dev/null with stdout_redirected(): if self.jac: s = odeint(func_dtwa_bbgky, \ np.concatenate((s_init_spins, s_init_corrs)), t_output, \ args=(self,), Dfun=jac_dtwa_bbgky, **odeint_kwargs) else: s = odeint(func_dtwa_bbgky, \ np.concatenate((s_init_spins, s_init_corrs)),t_output, \ args=(self,), Dfun=None, **odeint_kwargs) (s, info) = s if type(s) is tuple else (s, None) #Computes |dH/dt|^2 for a particular alphavec & weighes it #If the rms over alphavec of these are 0, then each H is const if self.verbose: hws = weyl_hamilt(s, t_output, self) dhwdt = np.array([t_deriv(hw, t_output) for hw in hws]) dhwdt_abs2 = np.square(dhwdt) list_of_dhwdt_abs2.extend(dhwdt_abs2) s = np.array(s, dtype="float128") #Widen memory to reduce overflows localdata = bbgky_observables(t_output, s, self) list_of_local_data.append(localdata) if self.verbose and pbar_avail and self.comm.rank == root: bar.update(runcount) #After loop above sum reduce (don't forget to average) all locally #calculated expectations at each time to root outdat = \ sum_reduce_all_data(self, list_of_local_data, t_output, comm) if self.verbose: dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0) dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\ if rank == root else None temp_comm = Intracomm(comm) dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root) if rank == root: dhwdt_abs2_totals = dhwdt_abs2_totals / (self.n_t * N * N) dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals) if rank == root: outdat.normalize_data(self.n_t, N) if self.verbose: print(" ") print("Integration output info:") pprint(info) print("\nt-deriv of Hamilt (abs square) with wigner avg: ") print(" ") print(tabulate({"time": t_output, \ "dhwdt_abs": dhwdt_abs_totals}, \ headers="keys", floatfmt=".6f")) if self.jac and self.verbose: print('# Cumulative number of Jacobian evaluations by root:', \ np.sum(info['nje'])) print('# Done!') np.seterr(**old_settings) # reset to default return outdat else: np.seterr(**old_settings) # reset to default return None
def bbgky_eqm(self, times, **odeint_kwargs): """ Evolves the BBGKY dynamics for selected phase points call with bbgky(t), where t is an array of times returns the "equilibrium" field correlations i.e. correlations w.r.t. the final steady state """ r_t = [None, None, None, None] if self.comm.rank == root: verboseprint(self.verbose, "Starting up the BBGKY dynamics...") if type(times).__module__ == np.__name__ : #An empty grid of size N X nalphas #Each element of this list is a dataset localdata = [[None for f in range(self.local_atoms.size)] \ for kvec in self.kvecs] if pbar_avail and self.comm.rank == root and self.verbose: pbar_max = self.kvecs.shape[0] * self.local_atoms.size * nalphas - 1 bar = progressbar.ProgressBar(widgets=widgets_bbgky,\ max_value=pbar_max, redirect_stdout=False) bar_pos = 0 bar.update(bar_pos) for tpl, mth_atom in np.ndenumerate(self.local_atoms): (atom_count,) = tpl corrs_summedover_alpha = np.zeros((self.kvecs.shape[0], times.size),\ dtype=np.complex_) for alpha in xrange(nalphas): r_t[0] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][0],\ times, args=(self,), **odeint_kwargs) r_t[1] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][1],\ times, args=(self,), **odeint_kwargs) r_t[2] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][2],\ times, args=(self,), **odeint_kwargs) r_t[3] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][3],\ times, args=(self,), **odeint_kwargs) #Update the final state self.local_atoms[atom_count].state[alpha][0] = r_t[0][-1] self.local_atoms[atom_count].state[alpha][1] = r_t[1][-1] self.local_atoms[atom_count].state[alpha][2] = r_t[2][-1] self.local_atoms[atom_count].state[alpha][3] = r_t[3][-1] for kcount in xrange(self.kvecs.shape[0]): corrs_summedover_alpha[kcount] += \ self.field_correlations(self.kvecs[kcount], alpha,\ r_t, mth_atom) if self.verbose and pbar_avail and self.comm.rank == root: bar.update(bar_pos) bar_pos += 1 localdata[kcount][atom_count] = corrs_summedover_alpha[kcount] duplicate_comm = Intracomm(self.comm) alldata = np.array([None for i in self.kvecs]) for kcount in xrange(self.kvecs.shape[0]): localsum_data = np.sum(np.array(localdata[kcount]), axis=0) if self.comm.size == 1: alldata[kcount] = localsum_data else: alldata[kcount] = duplicate_comm.reduce(localsum_data, root=root) if self.comm.rank == root: alldata[kcount] = alldata[kcount]/self.norms[kcount] if self.comm.rank == root: alldata /= self.corr_norm return alldata
def dtwa_ising_longrange_2ndorder(self, time_info, sampling): old_settings = np.seterr(all='ignore') #Prevent overflow warnings comm = self.comm N = self.latsize (t_init, n_cycles, n_steps) = time_info rank = comm.rank if rank == root and self.verbose: pprint("# Run parameters:") #Copy params to another object, then delete #the output that you don't want printed out = copy.copy(self) out.dsdotdg = 0.0 out.delta_eps_tensor = 0.0 out.jmat = 0.0 out.deltamn = 0.0 pprint(vars(out), depth=2) if rank == root and not self.verbose: pprint("# Starting run ...") if self.omega == 0: t_final = t_init + n_cycles else: t_final = t_init + (n_cycles * (2.0 * np.pi / self.omega)) dt = (t_final - t_init) / (n_steps - 1.0) t_output = np.arange(t_init, t_final, dt) #Let each process get its chunk of n_t by round robin nt_loc = 0 iterator = rank while iterator < self.n_t: nt_loc += 1 iterator += comm.size #Scatter unique seeds for generating unique random number arrays : #each processor gets its own nt_loc seeds, and allocates nt_loc #initial conditions. Each i.c. is a 2N sized array #now, each process sends its value of nt_loc to root all_ntlocs = comm.gather(nt_loc, root=root) #Let the root process initialize nt unique integers for random seeds if rank == root: all_seeds = np.arange(self.n_t, dtype=np.int64) + 1 all_ntlocs = np.array(all_ntlocs) all_displacements = np.roll(np.cumsum(all_ntlocs), root + 1) all_displacements[root] = 0 # First displacement else: all_seeds = None all_displacements = None local_seeds = np.zeros(nt_loc, dtype=np.int64) #Root scatters nt_loc sized seed data to that particular process comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\ MPI.DOUBLE],local_seeds) list_of_local_data = [] if self.verbose: list_of_dhwdt_abs2 = [] if self.sitedata: list_of_local_ijdata = [] for runcount in xrange(0, nt_loc, 1): random.seed(local_seeds[runcount] + self.seed_offset) sx_init = np.ones(N) if sampling == "spr": #According to Schachenmayer, the wigner function of the quantum #state generates the below initial conditions classically sy_init = 2.0 * np.random.randint(0, 2, size=N) - 1.0 sz_init = 2.0 * np.random.randint(0, 2, size=N) - 1.0 #Set initial conditions for the dynamics locally to vector #s_init and store it as [s^x,s^x,s^x, .... s^y,s^y,s^y ..., #s^z,s^z,s^z, ...] s_init_spins = np.concatenate((sx_init, sy_init, sz_init)) elif sampling == "1-0": spin_choices = np.array([(1, 1, 0), (1, 0, 1), (1, -1, 0), (1, 0, -1)]) spins = np.array( [random.choice(spin_choices) for i in xrange(N)]) s_init_spins = spins.T.flatten() elif sampling == "all": spin_choices_spr = np.array([(1, 1, 1), (1, 1, -1), (1, -1, 1), (1, -1, -1)]) spin_choices_10 = np.array([(1, 1, 0), (1, 0, 1), (1, -1, 0), (1, 0, -1)]) spin_choices = np.concatenate( (spin_choices_10, spin_choices_spr)) spins = np.array( [random.choice(spin_choices) for i in xrange(N)]) s_init_spins = spins.T.flatten() else: pass # Set initial correlations to 0. s_init_corrs = np.zeros(9 * N * N) #Redirect unwanted stdout warning messages to /dev/null with stdout_redirected(): if self.verbose: if self.jac: s, info = odeint(func_2ndorder, \ np.concatenate((s_init_spins, s_init_corrs)), t_output, \ args=(self,), Dfun=jac_2ndorder, full_output=True) else: s, info = odeint(func_2ndorder, \ np.concatenate((s_init_spins, s_init_corrs)),t_output, \ args=(self,), Dfun=None, full_output=True) else: if self.jac: s = odeint(func_2ndorder, \ np.concatenate((s_init_spins, s_init_corrs)), \ t_output, args=(self,), Dfun=jac_2ndorder) else: s = odeint(func_2ndorder, \ np.concatenate((s_init_spins, s_init_corrs)), t_output, \ args=(self,), Dfun=None) #Computes |dH/dt|^2 for a particular alphavec & weighes it #If the rms over alphavec of these are 0, then each H is const if self.verbose: hws = weyl_hamilt(s, t_output, self) dhwdt = np.array([t_deriv(hw, t_output) for hw in hws]) dhwdt_abs2 = np.square(dhwdt) list_of_dhwdt_abs2.extend(dhwdt_abs2) s = np.array(s, dtype="float128") #Widen memory to reduce overflows #Compute expectations <sx> and \sum_{ij}<sx_i sx_j> -<sx>^2 with #wigner func at t_output values LOCALLY for each initcond and #store them sx_expectations = np.sum(s[:, 0:N], axis=1) sy_expectations = np.sum(s[:, N:2 * N], axis=1) sz_expectations = np.sum(s[:, 2 * N:3 * N], axis=1) if self.sitedata: (i, j) = self.tpnt_sites sxi, syi, szi = s[:, i], s[:, i + N], s[:, i + 2 * N] sxi, syi, szi = sxi , syi ,\ szi sxj, syj, szj = s[:, j], s[:, j + N], s[:, j + 2 * N] sxj, syj, szj = sxj , syj ,\ szj sview = s.view() gij = sview[:,3*N:].reshape(\ t_output.size,3, 3, N, N)[:, :, :, i, j] #Calculate Spatial Correlations sy_iplusk = s[:, N:2 * N][:, i:] #This is a matrix syy_k = np.array([sy_iplusk[t] * syi[t] \ for t in xrange(t_output.size)])# This is also a matrix localdataij = OutData_ij(t_output, self.tpnt_sites, \ sxi, syi, szi,\ sxj, syj, szj,\ sy_iplusk,\ syy_k,\ gij) list_of_local_ijdata.append(localdataij) #svec is the tensor s^l_\mu #G = s[3*N:].reshape(3,3,N,N) is the tensor g^{ab}_{\mu\nu}. s = np.array(s, dtype="float128") #Enlarge in mem sview = s.view() gt = sview[:, 3 * N:].reshape(s.shape[0], 3, 3, N, N) gt[:, :, :, range(N), range(N)] = 0.0 #Set diags to 0 #Quantum spin variance sx_var = np.sum(gt[:, 0, 0, :, :], axis=(-1, -2)) sx_var += (np.sum(s[:, 0:N], axis=1)**2 \ - np.sum(s[:, 0:N]**2, axis=1)) sy_var = np.sum(gt[:, 1, 1, :, :], axis=(-1, -2)) sy_var += (np.sum(s[:, N:2*N], axis=1)**2 \ - np.sum(s[:, N:2*N]**2, axis=1)) sz_var = np.sum(gt[:, 2, 2, :, :], axis=(-1, -2)) sz_var += (np.sum(s[:, 2*N:3*N], axis=1)**2 \ - np.sum(s[:, 2*N:3*N]**2, axis=1)) sxy_var = np.sum(gt[:, 0, 1, :, :], axis=(-1, -2)) sxy_var += np.sum([fftconvolve(s[m, 0:N], s[m, N:2*N]) \ for m in xrange(t_output.size)], axis=1) #Remove the diagonal parts sxy_var -= np.sum(s[:, 0:N] * s[:, N:2 * N], axis=1) sxz_var = np.sum(gt[:, 0, 2, :, :], axis=(-1, -2)) sxz_var += np.sum([fftconvolve(s[m, 0:N], s[m, 2*N:3*N]) \ for m in xrange(t_output.size)], axis=1) #Remove the diagonal parts sxz_var -= np.sum(s[:, 0:N] * s[:, 2 * N:3 * N], axis=1) syz_var = np.sum(gt[:, 1, 2, :, :], axis=(-1, -2)) syz_var += np.sum([fftconvolve(s[m, N:2*N], s[m, 2*N:3*N]) \ for m in xrange(t_output.size)], axis=1) #Remove the diagonal parts syz_var -= np.sum(s[:, N:2 * N] * s[:, 2 * N:3 * N], axis=1) localdata = OutData(t_output, sx_expectations, sy_expectations,\ sz_expectations, sx_var, sy_var, sz_var, sxy_var, sxz_var, \ syz_var, self) list_of_local_data.append(localdata) #After loop above sum reduce (don't forget to average) all locally #calculated expectations at each time to root outdat = \ self.sum_reduce_all_data(list_of_local_data, t_output, comm) if self.verbose: dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0) dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\ if rank == root else None if self.sitedata: sij = self.sum_reduce_site_data(list_of_local_ijdata, t_output,\ self.tpnt_sites, comm) if rank == root: sij.normalize_data(self.n_t) sij.dump_data() if self.verbose: temp_comm = Intracomm(comm) dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root) if rank == root: dhwdt_abs2_totals = dhwdt_abs2_totals / (self.n_t * N * N) dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals) #Dump to file if rank == root: outdat.normalize_data(self.n_t, N) if self.file_output: outdat.dump_data() if self.verbose: print("t-deriv of Hamilt (abs square) with wigner avg: ") print(" ") print(tabulate({"time": t_output, \ "dhwdt_abs": dhwdt_abs_totals}, \ headers="keys", floatfmt=".6f")) if self.jac and self.verbose: print('# Cumulative number of Jacobian evaluations by root:', \ np.sum(info['nje'])) print('# Done!') np.seterr(**old_settings) # reset to default return outdat else: np.seterr(**old_settings) # reset to default return None
def sum_reduce_site_data(self, datalist_loc, t, sites, mpcomm): """ Does the parallel sum reduction of site data """ sxi_locsum = np.sum(data.sxi for data in datalist_loc) syi_locsum = np.sum(data.syi for data in datalist_loc) szi_locsum = np.sum(data.szi for data in datalist_loc) sxj_locsum = np.sum(data.sxj for data in datalist_loc) syj_locsum = np.sum(data.syj for data in datalist_loc) szj_locsum = np.sum(data.szj for data in datalist_loc) sy_iplusk_locsum = np.sum(data.sy_iplusk for data in datalist_loc) syy_k_locsum = np.sum(data.syy_k for data in datalist_loc) try: #This is to take care of the case when gij = None gijs_locsum = np.sum(data.gij for data in datalist_loc) except AttributeError: gijs_locsum = None sxi_totals = np.zeros_like(sxi_locsum) if mpcomm.rank == root\ else None syi_totals = np.zeros_like(syi_locsum) if mpcomm.rank == root\ else None szi_totals = np.zeros_like(szi_locsum) if mpcomm.rank == root\ else None sxj_totals = np.zeros_like(sxj_locsum) if mpcomm.rank == root\ else None syj_totals = np.zeros_like(syj_locsum) if mpcomm.rank == root \ else None szj_totals = np.zeros_like(szj_locsum) if mpcomm.rank == root \ else None sy_iplusk_totals = np.zeros_like(sy_iplusk_locsum) \ if mpcomm.rank == root else None syy_k_totals = np.zeros_like(syy_k_locsum) \ if mpcomm.rank == root else None gijs_totals = np.zeros_like(gijs_locsum) if mpcomm.rank == root \ else None #To prevent conflicts with other comms duplicate_comm = Intracomm(mpcomm) #Broadcast these reductions to root sxi_totals = duplicate_comm.reduce(sxi_locsum, root=root) syi_totals = duplicate_comm.reduce(syi_locsum, root=root) szi_totals = duplicate_comm.reduce(szi_locsum, root=root) sxj_totals = duplicate_comm.reduce(sxj_locsum, root=root) syj_totals = duplicate_comm.reduce(syj_locsum, root=root) szj_totals = duplicate_comm.reduce(szj_locsum, root=root) sy_iplusk_totals = duplicate_comm.reduce(sy_iplusk_locsum, root=root) syy_k_totals = duplicate_comm.reduce(syy_k_locsum, root=root) if gijs_locsum is not None: gijs_totals = duplicate_comm.reduce(gijs_locsum, root=root) else: gijs_totals = None if mpcomm.rank == root: return OutData_ij(t, sites, sxi_totals, syi_totals, \ szi_totals, sxj_totals, syj_totals, szj_totals, \ sy_iplusk_totals, syy_k_totals, gijs_totals) else: return None