double Geo_Constraint_Dihedral(unsigned n, const double *x, double *grad, void *data) { int ia, ib, ic, id, iPos; double phi, phi0, d_phi, g[4][3]; CMol* pMol; GEO_FIX_DIHEDRAL *Geo_Fix_phi; Geo_Fix_phi = (GEO_FIX_DIHEDRAL*)data; pMol = (CMol*)(Geo_Fix_phi->pMol); ia = Geo_Fix_phi->ia; ib = Geo_Fix_phi->ib; ic = Geo_Fix_phi->ic; id = Geo_Fix_phi->id; phi0 = Geo_Fix_phi->phi0; if(grad) { phi = pMol->Query_Dihedral(ia, ib, ic, id, 1, g); memset(grad, 0, sizeof(double)*n); iPos = 3 * ia; grad[iPos ] = g[0][0]; grad[iPos+1] = g[0][1]; grad[iPos+2] = g[0][2]; iPos = 3 * ib; grad[iPos ] = g[1][0]; grad[iPos+1] = g[1][1]; grad[iPos+2] = g[1][2]; iPos = 3 * ic; grad[iPos ] = g[2][0]; grad[iPos+1] = g[2][1]; grad[iPos+2] = g[2][2]; iPos = 3 * id; grad[iPos ] = g[3][0]; grad[iPos+1] = g[3][1]; grad[iPos+2] = g[3][2]; } else { phi = pMol->Query_Dihedral(ia, ib, ic, id, 0, g); } d_phi = phi - phi0; if(d_phi < -PI) { d_phi += PI2; } else if(d_phi > PI) { d_phi -= PI2; } return d_phi; }
void To_Setup_All_Dihedral_Constraint(void) { int i; Mol_ESP.nPhi_Fixed = 0; for(i=0; i<n_Phi; i++) { Mol_ESP.To_Fix_Dihedral(DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], Mol_ESP.Query_Dihedral(DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], 0, NULL)); } }
double Geoometry_Optimization_With_Constraint(CMol *pMol) { return (pMol->Cal_E(0)); nlopt_opt opt, opt_AugLag; int Return_Opt, nAtom, nDim, i, iPos; double E_min, x[MAX_NUM_ATOM*3]; Mol_ESP.Restrain_All_Torsions(1); // apply soft restraints on all soft dihedrals nAtom = pMol->nAtom; nDim = 3 * nAtom; printf("\nMM before:\t"); for(i=0; i<n_Phi; i++) { printf("%3d %3d %3d %3d %8.4lf\n", DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], Mol_ESP.Query_Dihedral(DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], 0, NULL)); } double AUG_LAG_ICM_TOL = 1.0E-17; opt_AugLag = nlopt_create(NLOPT_LD_LBFGS_GEO, nDim); nlopt_set_min_objective(opt_AugLag, func_Geo_Opt_Constraint, pMol); // pMol->SavePdb("opt-free.pdb"); for(i=0; i<pMol->nBond_Fixed; i++) { int ret=0; pMol->Geo_Fix_r0[i].pMol = pMol; ret =nlopt_add_equality_constraint(opt_AugLag, Geo_Constraint_Bond, &(pMol->Geo_Fix_r0[i]), 2.0E-6); printf(" Fixing bond %d\n", i ); } for(i=0; i<pMol->nAngle_Fixed; i++) { int ret=0; pMol->Geo_Fix_theta0[i].pMol = pMol; ret=nlopt_add_equality_constraint(opt_AugLag, Geo_Constraint_Angle, &(pMol->Geo_Fix_theta0[i]), 2.0E-6); printf(" Fixing angle %d\n", i ); } for(i=0; i<pMol->nPhi_Fixed; i++) { int ret=0; pMol->Geo_Fix_phi0[i].pMol = pMol; ret=nlopt_add_equality_constraint(opt_AugLag, Geo_Constraint_Dihedral, &(pMol->Geo_Fix_phi0[i]), 2.0E-6); printf(" Fixing phi %d : %d\n", i, ret ); } nlopt_set_xtol_rel(opt_AugLag, 2E-7); // opt = nlopt_create(NLOPT_LD_LBFGS_GEO, nDim); // opt = nlopt_create(NLOPT_LN_COBYLA, nDim); // nlopt_set_min_objective(opt, func_Geo_Opt_Constraint, pMol); // nlopt_set_xtol_rel(opt, 1E-7); // nlopt_set_local_optimizer(opt_AugLag, opt); // nlopt_destroy(opt); for(i=0; i<nAtom; i++) { iPos = 3*i; x[iPos ] = pMol->x[i]; x[iPos+1] = pMol->y[i]; x[iPos+2] = pMol->z[i]; } Iter_Opt_Constrained = 0; Return_Opt = nlopt_optimize(opt_AugLag, x, &E_min); if (Return_Opt < 0) { printf("nlopt failed : %d\n", Return_Opt); } // else { // printf("After constrained optimization, E = %12.6lf\n", E_min); // } nlopt_destroy(opt_AugLag); printf("MM after:\t"); for(i=0; i<n_Phi; i++) { printf("%3d %3d %3d %3d %8.4lf\n", DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], Mol_ESP.Query_Dihedral(DihList[i][0], DihList[i][1], DihList[i][2], DihList[i][3], 0, NULL)); } Mol_ESP.Restrain_All_Torsions(0); // lift soft restraints on all soft dihedrals return (pMol->Cal_E(0)); }