4#include <thrust/device_ptr.h>
5#include <thrust/reduce.h>
6static inline size_t SelectTrialPosition(std::vector <double> LogBoltzmannFactors)
8 std::vector<double> ShiftedBoltzmannFactors(LogBoltzmannFactors.size());
12 double largest_value = *std::max_element(LogBoltzmannFactors.begin(), LogBoltzmannFactors.end());
16 double SumShiftedBoltzmannFactors = 0.0;
17 for (
size_t i = 0; i < LogBoltzmannFactors.size(); ++i)
19 ShiftedBoltzmannFactors[i] = exp(LogBoltzmannFactors[i] - largest_value);
20 SumShiftedBoltzmannFactors += ShiftedBoltzmannFactors[i];
25 double cumw = ShiftedBoltzmannFactors[0];
26 double ws = Get_Uniform_Random() * SumShiftedBoltzmannFactors;
28 cumw += ShiftedBoltzmannFactors[++selected];
34inline void Host_sum_Widom_HGGG_SEPARATE(
size_t NumberWidomTrials,
double Beta, T* energy_array,
bool* flag,
size_t HG_Nblock,
size_t HGGG_Nblock, std::vector<MoveEnergy>& energies, std::vector<size_t>& Trialindex, std::vector<double>& Rosen,
size_t Cycle)
36 std::vector<size_t>reasonable_trials;
37 for(
size_t i = 0; i < NumberWidomTrials; i++){
39 reasonable_trials.push_back(i);}}
40 T host_array[HGGG_Nblock * 2];
41 for(
size_t i = 0; i < reasonable_trials.size(); i++)
43 size_t trial = reasonable_trials[i];
44 cudaMemcpy(host_array, &energy_array[trial*HGGG_Nblock * 2], 2 * HGGG_Nblock*
sizeof(T), cudaMemcpyDeviceToHost);
45 T HG_vdw = 0.0; T HG_real = 0.0;
46 T GG_vdw = 0.0; T GG_real = 0.0;
50 for(
size_t ijk=0; ijk < HG_Nblock; ijk++) HG_vdw+=host_array[ijk];
51 for(
size_t ijk=HG_Nblock; ijk < HGGG_Nblock; ijk++) GG_vdw+=host_array[ijk];
53 for(
size_t ijk=HGGG_Nblock; ijk < HG_Nblock + HGGG_Nblock; ijk++) HG_real+=host_array[ijk];
54 for(
size_t ijk=HG_Nblock + HGGG_Nblock; ijk < HGGG_Nblock + HGGG_Nblock; ijk++) GG_real+=host_array[ijk];
56 double tot =
static_cast<double>(HG_vdw + GG_vdw + HG_real + GG_real);
59 E.HGVDW =
static_cast<double>(HG_vdw);
60 E.HGReal=
static_cast<double>(HG_real);
61 E.GGVDW =
static_cast<double>(GG_vdw);
62 E.GGReal=
static_cast<double>(GG_real);
64 energies.push_back(E);
65 Trialindex.push_back(trial);
66 Rosen.push_back(-Beta*tot);
71__global__
void get_random_trial_position(
Boxsize Box,
Atoms* d_a,
Atoms NewMol,
bool* device_flag,
RandomNumber Random,
size_t start_position,
size_t SelectedComponent,
size_t MolID,
int MoveType, double2 proposed_scale)
73 double3* random = Random.device_random;
74 size_t offset = Random.offset;
76 const size_t i = blockIdx.x * blockDim.x + threadIdx.x;
77 const size_t random_index = i + offset;
78 const Atoms AllData = d_a[SelectedComponent];
79 double scale=0.0;
double scaleCoul = 0.0;
85 scale = proposed_scale.x; scaleCoul = proposed_scale.y;
86 double3 BoxLength = {Box.Cell[0], Box.Cell[4], Box.Cell[8]};
87 NewMol.pos[i] = BoxLength * random[random_index];
92 scale = AllData.scale[start_position]; scaleCoul = AllData.scaleCoul[start_position];
95 NewMol.pos[i] = AllData.pos[start_position];
99 double3 BoxLength = {Box.Cell[0], Box.Cell[4], Box.Cell[8]};
100 NewMol.pos[i] = BoxLength * random[random_index];
106 case REINSERTION_INSERTION:
108 scale = AllData.scale[start_position];
109 scaleCoul = AllData.scaleCoul[start_position];
110 double3 BoxLength = {Box.Cell[0], Box.Cell[4], Box.Cell[8]};
111 NewMol.pos[i] = BoxLength * random[random_index];
114 case REINSERTION_RETRACE:
116 scale = AllData.scale[start_position]; scaleCoul = AllData.scaleCoul[start_position];
119 NewMol.pos[i] = AllData.pos[start_position];
123 double3 BoxLength = {Box.Cell[0], Box.Cell[4], Box.Cell[8]};
124 NewMol.pos[i] = BoxLength * random[random_index];
128 case IDENTITY_SWAP_NEW:
131 scale = proposed_scale.x; scaleCoul = proposed_scale.y;
134 case IDENTITY_SWAP_OLD:
136 scale = AllData.scale[start_position]; scaleCoul = AllData.scaleCoul[start_position];
139 NewMol.pos[i] = AllData.pos[start_position];
143 NewMol.scale[i] = scale;
144 NewMol.charge[i] = AllData.charge[start_position];
145 NewMol.scaleCoul[i] = scaleCoul;
146 NewMol.Type[i] = AllData.Type[start_position];
147 NewMol.MolID[i] = MolID;
154 device_flag[i] =
false;
157__global__
void get_random_trial_orientation(
Boxsize Box,
Atoms* d_a,
Atoms Mol,
Atoms NewMol,
bool* device_flag, double3* random,
size_t offset,
size_t FirstBeadTrial,
size_t start_position,
size_t SelectedComponent,
size_t MolID,
size_t chainsize,
int MoveType, double2 proposed_scale,
size_t Cycle)
165 const size_t i = blockIdx.x * blockDim.x + threadIdx.x;
170 Mol.pos[0] = NewMol.pos[FirstBeadTrial];
171 Mol.scale[0] = NewMol.scale[FirstBeadTrial];
172 Mol.charge[0] = NewMol.charge[FirstBeadTrial];
173 Mol.scaleCoul[0] = NewMol.scaleCoul[FirstBeadTrial];
174 Mol.Type[0] = NewMol.Type[FirstBeadTrial];
175 Mol.MolID[0] = NewMol.MolID[FirstBeadTrial];
178 size_t random_index = i + offset;
179 const Atoms AllData = d_a[SelectedComponent];
184 double scale = 0.0;
double scaleCoul = 0.0;
185 for(
size_t a = 0; a < chainsize; a++)
188 Vec = AllData.pos[1+a] - AllData.pos[0];
195 case CBMC_INSERTION:
case IDENTITY_SWAP_NEW:
197 scale = proposed_scale.x; scaleCoul = proposed_scale.y;
198 Rotate_Quaternions(Vec, random[random_index]);
199 NewMol.pos[i*chainsize+a] = Mol.pos[0] + Vec;
204 scale = AllData.scale[start_position+a]; scaleCoul = AllData.scaleCoul[start_position+a];
207 NewMol.pos[i*chainsize+a] = AllData.pos[start_position+a];
211 Rotate_Quaternions(Vec, random[random_index]);
212 NewMol.pos[i*chainsize+a] = Mol.pos[0] + Vec;
218 case REINSERTION_INSERTION:
220 scale = AllData.scale[start_position+a]; scaleCoul = AllData.scaleCoul[start_position+a];
221 Rotate_Quaternions(Vec, random[random_index]);
222 NewMol.pos[i*chainsize+a] = Mol.pos[0] + Vec;
225 case REINSERTION_RETRACE:
case IDENTITY_SWAP_OLD:
227 scale = AllData.scale[start_position+a]; scaleCoul = AllData.scaleCoul[start_position+a];
230 NewMol.pos[i*chainsize+a] = AllData.pos[start_position+a];
234 Rotate_Quaternions(Vec, random[random_index]);
235 NewMol.pos[i*chainsize+a] = Mol.pos[0] + Vec;
240 NewMol.scale[i*chainsize+a] = scale; NewMol.charge[i*chainsize+a] = AllData.charge[start_position+a];
241 NewMol.scaleCoul[i*chainsize+a] = scaleCoul;
242 NewMol.Type[i*chainsize+a] = AllData.Type[start_position+a]; NewMol.MolID[i*chainsize+a] = MolID;
244 device_flag[i] =
false;
248static inline double Widom_Move_FirstBead_PARTIAL(
Components& SystemComponents,
Simulations& Sims,
ForceField& FF,
RandomNumber& Random,
WidomStruct& Widom,
size_t SelectedMolInComponent,
size_t SelectedComponent,
int MoveType,
double &StoredR,
size_t *REAL_Selected_Trial,
bool *SuccessConstruction,
MoveEnergy *energy, double2 proposed_scale)
251 bool Goodconstruction =
false;
size_t SelectedTrial = 0;
double Rosenbluth = 0.0;
253 for(
size_t ijk = 0; ijk < SystemComponents.NComponents.x; ijk++)
255 Atomsize += SystemComponents.Moleculesize[ijk] * SystemComponents.NumberOfMolecule_for_Component[ijk];
257 std::vector<double>Rosen; std::vector<MoveEnergy>energies; std::vector<size_t>Trialindex;
262 size_t NumberOfTrials = Widom.NumberWidomTrials;
263 size_t start_position = SelectedMolInComponent*SystemComponents.Moleculesize[SelectedComponent];
264 size_t SelectedMolID = SelectedMolInComponent;
270 SelectedMolID = SystemComponents.NumberOfMolecule_for_Component[SelectedComponent];
273 case CBMC_DELETION:
case REINSERTION_INSERTION:
277 case REINSERTION_RETRACE:
case IDENTITY_SWAP_OLD:
283 case IDENTITY_SWAP_NEW:
287 SelectedMolID = SystemComponents.NumberOfMolecule_for_Component[SelectedComponent];
291 size_t threadsNeeded = Atomsize * NumberOfTrials;
293 Random.Check(NumberOfTrials);
297 get_random_trial_position<<<1,NumberOfTrials>>>(Sims.Box, Sims.d_a, Sims.New, Sims.device_flag, Random, start_position, SelectedComponent, SelectedMolID, MoveType, proposed_scale); checkCUDAError(
"error getting random trials");
298 Random.Update(NumberOfTrials);
304 size_t NHostAtom = 0;
size_t NGuestAtom = 0;
305 for(
size_t i = 0; i < SystemComponents.NComponents.y; i++)
306 NHostAtom += SystemComponents.Moleculesize[i] * SystemComponents.NumberOfMolecule_for_Component[i];
307 for(
size_t i = SystemComponents.NComponents.y; i < SystemComponents.NComponents.x; i++)
308 NGuestAtom+= SystemComponents.Moleculesize[i] * SystemComponents.NumberOfMolecule_for_Component[i];
310 size_t HG_Nthread=0;
size_t HG_Nblock=0; Setup_threadblock(NHostAtom * 1, &HG_Nblock, &HG_Nthread);
311 size_t GG_Nthread=0;
size_t GG_Nblock=0; Setup_threadblock(NGuestAtom * 1, &GG_Nblock, &GG_Nthread);
312 size_t HGGG_Nthread = std::max(HG_Nthread, GG_Nthread);
313 size_t HGGG_Nblock = HG_Nblock + GG_Nblock;
316 Calculate_Multiple_Trial_Energy_SEPARATE_HostGuest_VDWReal<<<HGGG_Nblock * NumberOfTrials, HGGG_Nthread, 2 * HGGG_Nthread *
sizeof(double)>>>(Sims.Box, Sims.d_a, Sims.New, FF, Sims.Blocksum, SelectedComponent, Atomsize, Sims.device_flag, threadsNeeded,1, HGGG_Nblock, HG_Nblock, SystemComponents.NComponents, Sims.ExcludeList); checkCUDAError(
"Error calculating energies (PARTIAL SUM HGGG)");
317 cudaMemcpy(SystemComponents.flag, Sims.device_flag, NumberOfTrials*
sizeof(
bool), cudaMemcpyDeviceToHost);
322 Host_sum_Widom_HGGG_SEPARATE(NumberOfTrials, SystemComponents.Beta, Sims.Blocksum, SystemComponents.flag, HG_Nblock, HGGG_Nblock, energies, Trialindex, Rosen, SystemComponents.CURRENTCYCLE);
324 double averagedRosen = 0.0;
325 size_t REALselected = 0;
329 case CBMC_INSERTION:
case REINSERTION_INSERTION:
331 if(Rosen.size() == 0)
break;
332 SelectedTrial = SelectTrialPosition(Rosen);
333 for(
size_t a = 0; a < Rosen.size(); a++) Rosen[a] = std::exp(Rosen[a]);
334 Rosenbluth =std::accumulate(Rosen.begin(), Rosen.end(),
decltype(Rosen)::value_type(0));
335 if(Rosenbluth < 1e-150)
break;
336 Goodconstruction =
true;
339 case IDENTITY_SWAP_NEW:
341 if(Rosen.size() == 0)
break;
343 for(
size_t a = 0; a < Rosen.size(); a++) Rosen[a] = std::exp(Rosen[a]);
344 Rosenbluth =std::accumulate(Rosen.begin(), Rosen.end(),
decltype(Rosen)::value_type(0));
345 if(Rosenbluth < 1e-150)
break;
346 Goodconstruction =
true;
349 case CBMC_DELETION:
case REINSERTION_RETRACE:
case IDENTITY_SWAP_OLD:
352 for(
size_t a = 0; a < Rosen.size(); a++) Rosen[a] = std::exp(Rosen[a]);
353 Rosenbluth =std::accumulate(Rosen.begin(), Rosen.end(),
decltype(Rosen)::value_type(0));
354 Goodconstruction =
true;
359 if(!Goodconstruction)
return 0.0;
360 REALselected = Trialindex[SelectedTrial];
362 if(MoveType == REINSERTION_INSERTION) StoredR = Rosenbluth - Rosen[SelectedTrial];
363 if(MoveType == REINSERTION_RETRACE) Rosenbluth += StoredR;
365 averagedRosen = Rosenbluth;
366 if(MoveType != IDENTITY_SWAP_OLD && MoveType != IDENTITY_SWAP_NEW)
367 averagedRosen /= double(Widom.NumberWidomTrials);
369 *REAL_Selected_Trial = REALselected;
370 *SuccessConstruction = Goodconstruction;
371 *energy = energies[SelectedTrial];
372 return averagedRosen;
375static inline double Widom_Move_Chain_PARTIAL(
Components& SystemComponents,
Simulations& Sims,
ForceField& FF,
RandomNumber& Random,
WidomStruct& Widom,
size_t SelectedMolInComponent,
size_t SelectedComponent,
int MoveType,
size_t *REAL_Selected_Trial,
bool *SuccessConstruction,
MoveEnergy *energy,
size_t FirstBeadTrial, double2 proposed_scale)
381 size_t chainsize = SystemComponents.Moleculesize[SelectedComponent]-1;
382 bool Goodconstruction =
false;
size_t SelectedTrial = 0;
double Rosenbluth = 0.0;
385 for(
size_t ijk = 0; ijk < SystemComponents.NComponents.x; ijk++)
387 Atomsize += SystemComponents.Moleculesize[ijk] * SystemComponents.NumberOfMolecule_for_Component[ijk];
390 std::vector<double>Rosen; std::vector<MoveEnergy>energies; std::vector<size_t>Trialindex;
395 size_t start_position = SelectedMolInComponent*SystemComponents.Moleculesize[SelectedComponent] + 1;
396 size_t SelectedMolID = SelectedMolInComponent;
402 SelectedMolID = SystemComponents.NumberOfMolecule_for_Component[SelectedComponent];
405 case CBMC_DELETION:
case REINSERTION_INSERTION:
case REINSERTION_RETRACE:
case IDENTITY_SWAP_OLD:
409 case IDENTITY_SWAP_NEW:
412 SelectedMolID = SystemComponents.NumberOfMolecule_for_Component[SelectedComponent];
417 size_t threadsNeeded = Atomsize*Widom.NumberWidomTrialsOrientations*chainsize;
419 Random.Check(Widom.NumberWidomTrialsOrientations);
421 get_random_trial_orientation<<<1,Widom.NumberWidomTrialsOrientations>>>(Sims.Box, Sims.d_a, Sims.Old, Sims.New, Sims.device_flag, Random.device_random, Random.offset, FirstBeadTrial, start_position, SelectedComponent, SelectedMolID, chainsize, MoveType, proposed_scale, SystemComponents.CURRENTCYCLE); checkCUDAError(
"error getting random trials orientations");
423 Random.Update(Widom.NumberWidomTrialsOrientations);
427 size_t NHostAtom = 0;
size_t NGuestAtom = 0;
428 for(
size_t i = 0; i < SystemComponents.NComponents.y; i++)
429 NHostAtom += SystemComponents.Moleculesize[i] * SystemComponents.NumberOfMolecule_for_Component[i];
430 for(
size_t i = SystemComponents.NComponents.y; i < SystemComponents.NComponents.x; i++)
431 NGuestAtom+= SystemComponents.Moleculesize[i] * SystemComponents.NumberOfMolecule_for_Component[i];
433 size_t HG_Nthread=0;
size_t HG_Nblock=0; Setup_threadblock(NHostAtom * chainsize, &HG_Nblock, &HG_Nthread);
434 size_t GG_Nthread=0;
size_t GG_Nblock=0; Setup_threadblock(NGuestAtom * chainsize, &GG_Nblock, &GG_Nthread);
435 size_t HGGG_Nthread = std::max(HG_Nthread, GG_Nthread);
436 size_t HGGG_Nblock = HG_Nblock + GG_Nblock;
441 Calculate_Multiple_Trial_Energy_SEPARATE_HostGuest_VDWReal<<<HGGG_Nblock * Widom.NumberWidomTrialsOrientations, HGGG_Nthread, 2 * HGGG_Nthread *
sizeof(double)>>>(Sims.Box, Sims.d_a, Sims.New, FF, Sims.Blocksum, SelectedComponent, Atomsize, Sims.device_flag, threadsNeeded, chainsize, HGGG_Nblock, HG_Nblock, SystemComponents.NComponents, Sims.ExcludeList); checkCUDAError(
"Error calculating energies (PARTIAL SUM HGGG Orientation)");
443 cudaMemcpy(SystemComponents.flag, Sims.device_flag, Widom.NumberWidomTrialsOrientations*
sizeof(
bool), cudaMemcpyDeviceToHost);
447 Host_sum_Widom_HGGG_SEPARATE(Widom.NumberWidomTrialsOrientations, SystemComponents.Beta, Sims.Blocksum, SystemComponents.flag, HG_Nblock, HGGG_Nblock, energies, Trialindex, Rosen, SystemComponents.CURRENTCYCLE);
449 double averagedRosen= 0.0;
450 size_t REALselected = 0;
455 case CBMC_INSERTION:
case REINSERTION_INSERTION:
case IDENTITY_SWAP_NEW:
457 if(Rosen.size() == 0)
break;
458 SelectedTrial = SelectTrialPosition(Rosen);
460 for(
size_t a = 0; a < Rosen.size(); a++) Rosen[a] = std::exp(Rosen[a]);
461 Rosenbluth =std::accumulate(Rosen.begin(), Rosen.end(),
decltype(Rosen)::value_type(0));
462 if(Rosenbluth < 1e-150)
break;
463 Goodconstruction =
true;
466 case CBMC_DELETION:
case REINSERTION_RETRACE:
case IDENTITY_SWAP_OLD:
469 for(
size_t a = 0; a < Rosen.size(); a++) Rosen[a] = std::exp(Rosen[a]);
470 Rosenbluth =std::accumulate(Rosen.begin(), Rosen.end(),
decltype(Rosen)::value_type(0));
471 Goodconstruction =
true;
475 if(!Goodconstruction)
return 0.0;
476 REALselected = Trialindex[SelectedTrial];
479 averagedRosen = Rosenbluth/double(Widom.NumberWidomTrialsOrientations);
480 *REAL_Selected_Trial = REALselected;
481 *SuccessConstruction = Goodconstruction;
482 *energy = energies[SelectedTrial];
484 return averagedRosen;
Definition data_struct.h:746
Definition data_struct.h:819
Definition data_struct.h:843
Definition data_struct.h:794
Definition data_struct.h:615
Definition data_struct.h:1053
Definition data_struct.h:1027
Definition data_struct.h:1044