//Calculate OldMol Bond Energy & //Calculate phi weight for nTrials using actual theta of OldMol void DCHedron::ConstrainedAnglesOld(uint nTrials, TrialMol& oldMol, uint molIndex) { IncorporateOld(oldMol, molIndex); for (uint b = 1; b < nBonds; ++b) { double stepWeight = 0.0; //pick "twist" angles for (uint i = 0; i < nTrials; ++i) { double angles = data->prng.rand(M_PI * 2); double energies = 0.0; double nonbondedEng = 0.0; //compare to angles determined in previous iterations for (uint c = 0; c < b; ++c) { if(!data->ff.angles->AngleFixed(angleKinds[b][c])) { double cosTerm = cos(theta[b]) * cos(theta[c]); double sinTerm = sin(theta[b]) * sin(theta[c]); double bfcTheta = acos(sinTerm * cos(angles - phi[c]) + cosTerm); double distSq = oldMol.AngleDist(bondLengthOld[b], bondLengthOld[c], bfcTheta); nonbondedEng += data->calc.IntraEnergy_1_3(distSq, bonded[b], bonded[c], molIndex); energies += data->ff.angles->Calc(angleKinds[b][c], bfcTheta); } else { double cosTerm = cos(theta[b]) * cos(theta[c]); double sinTerm = sin(theta[b]) * sin(theta[c]); double bfcTheta = data->ff.angles->Angle(angleKinds[b][c]); angles = acos((cos(bfcTheta) - cosTerm) / sinTerm) + phi[c]; double distSq = oldMol.AngleDist(bondLengthOld[b], bondLengthOld[c], bfcTheta); nonbondedEng += data->calc.IntraEnergy_1_3(distSq, bonded[b], bonded[c], molIndex); energies += data->ff.angles->Calc(angleKinds[b][c], bfcTheta); if(abs(angles) > 2.0 * M_PI) { std::cout << "Error: Cannot constrain fix angle for " << oldMol.GetKind().atomTypeNames[bonded[b]] << " " << oldMol.GetKind().atomTypeNames[focus] << " " << oldMol.GetKind().atomTypeNames[bonded[c]] << " !\n"; exit(EXIT_FAILURE); } } } //calculate weights from combined energy double weights = exp(-1 * data->ff.beta * (energies + nonbondedEng)); stepWeight += weights; } phiWeight[b] += stepWeight; } }
void DCHedron::ConstrainedAngles(TrialMol& newMol, uint molIndex, uint nTrials) { double* angles = data->angles; double* energies = data->angleEnergy; double* weights = data->angleWeights; double* nonbonded_1_3 = data->nonbonded_1_3; std::fill_n(nonbonded_1_3, nTrials, 0.0); phi[0] = 0.0; for (uint b = 1; b < nBonds; ++b) { //pick "twist" angles for (uint i = 0; i < nTrials; ++i) { angles[i] = data->prng.rand(M_PI * 2); energies[i] = 0.0; nonbonded_1_3[i] = 0.0; } //compare to angles determined in previous iterations for (uint c = 0; c < b; ++c) { double cosTerm = cos(theta[b]) * cos(theta[c]); double sinTerm = sin(theta[b]) * sin(theta[c]); for (uint i = 0; i < nTrials; ++i) { if(!data->ff.angles->AngleFixed(angleKinds[b][c])) { double bfcTheta = acos(sinTerm * cos(angles[i] - phi[c]) + cosTerm); double distSq = newMol.AngleDist(bondLength[b], bondLength[c], bfcTheta); double tempEn = data->calc.IntraEnergy_1_3(distSq, bonded[b], bonded[c], molIndex); nonbonded_1_3[i] += tempEn; energies[i] += data->ff.angles->Calc(angleKinds[b][c], bfcTheta); } else { double bfcTheta = data->ff.angles->Angle(angleKinds[b][c]); angles[i] = acos((cos(bfcTheta) - cosTerm) / sinTerm) + phi[c]; double distSq = newMol.AngleDist(bondLength[b], bondLength[c], bfcTheta); double tempEn = data->calc.IntraEnergy_1_3(distSq, bonded[b], bonded[c], molIndex); nonbonded_1_3[i] += tempEn; energies[i] += data->ff.angles->Calc(angleKinds[b][c], bfcTheta); if(abs(angles[i]) > 2.0 * M_PI) { std::cout << "Error: Cannot constrain fix angle for " << newMol.GetKind().atomTypeNames[bonded[b]] << " " << newMol.GetKind().atomTypeNames[focus] << " " << newMol.GetKind().atomTypeNames[bonded[c]] << " !\n"; exit(EXIT_FAILURE); } } } } //calculate weights from combined energy double stepWeight = 0.0; int i; #ifdef _OPENMP #pragma omp parallel for default(shared) private(i) reduction(+:stepWeight) #endif for (i = 0; i < nTrials; ++i) { weights[i] = exp(-1 * data->ff.beta * (energies[i] + nonbonded_1_3[i])); stepWeight += weights[i]; } uint winner = data->prng.PickWeighted(weights, nTrials, stepWeight); phi[b] = angles[winner]; bendEnergy += energies[winner]; oneThree += nonbonded_1_3[winner]; phiWeight[b] = stepWeight; } }