double CalObjectiveFunction(double Para_List[], int Get_E_Rotamer) { int i, j, nAtom, time_1, time_2; double d_E, E_Shift, w_1D; double Chi_SQ_Rotamer_Local; double E_Rotamer_MM_Local[MAX_ROTAMER]; double E_Min_1D_MM_Mean, E_Min_1D_QM_Mean, E_Min_1D_QM_MM_Shift, Weight_Sum; Chi_SQ = Chi_SQ_1D = Chi_SQ_Rotamer = 0.0; Chi_SQ_Rotamer_Local = 0.0; w_1D = 1.0 - w_Rotamer; time_1 = time(NULL); Distribute_Torsion_Parameters(); Assign_Torsion_Parameters(); E_Shift = Para_List[10*n_Phi]; nAtom = Mol_ESP.nAtom; for(i=0; i<n_Phi; i++) { for(j=0; j<nScan_List[i]; j++) { memcpy(Mol_ESP.x, x_Scan_list[i][j], sizeof(double)*nAtom); memcpy(Mol_ESP.y, y_Scan_list[i][j], sizeof(double)*nAtom); memcpy(Mol_ESP.z, z_Scan_list[i][j], sizeof(double)*nAtom); E_Scan_MM[i][j] = Mol_ESP.Cal_E(0); } E_Min_1D_MM_Mean = E_Min_1D_QM_Mean = 0.0; Weight_Sum = 0.0; for(j=0; j<nScan_List[i]; j++) { Weight_Sum += w_Scan_List[i][j]; E_Min_1D_MM_Mean += (w_Scan_List[i][j] * E_Scan_MM[i][j] ); E_Min_1D_QM_Mean += (w_Scan_List[i][j] * E_Scan_QM[i][j] ); } E_Min_1D_QM_MM_Shift = (E_Min_1D_QM_Mean - E_Min_1D_MM_Mean)/Weight_Sum; for(j=0; j<nScan_List[i]; j++) { d_E = (E_Scan_QM[i][j] - E_Scan_MM[i][j] - E_Min_1D_QM_MM_Shift); // fit the relative 1D energy profile Chi_SQ_1D += (d_E*d_E*w_Scan_List[i][j]); } } Chi_SQ_1D *= (w_1D/w_Scan_Sum); for(i=0; i<nRotamer; i++) { E_Rotamer_MM[i] = E_Rotamer_MM_Local[i] = 0.0; if(i%nProc != ProgID) { //only proceed when i%nProc == ProgID, do job decomposition continue; } memcpy(Mol_ESP.x, x_Rotamer_Opt[i], sizeof(double)*nAtom); memcpy(Mol_ESP.y, y_Rotamer_Opt[i], sizeof(double)*nAtom); memcpy(Mol_ESP.z, z_Rotamer_Opt[i], sizeof(double)*nAtom); Mol_ESP.FullGeometryOptimization_LBFGS_step(1); E_Rotamer_MM_Local[i] = Mol_ESP.Cal_E(0); d_E = E_Rotamer_QM[i] - E_Rotamer_MM_Local[i] - E_Shift; Chi_SQ_Rotamer_Local += (d_E*d_E*w_rotamer_List[i]); } if(Get_E_Rotamer) { //eliot (from Matt Harvey) for( int i = 0 ; i < nRotamer; i++ ) { E_Rotamer_MM[i] += E_Rotamer_MM_Local[i]; } Chi_SQ_Rotamer = Chi_SQ_Rotamer_Local; //eliot MPI_Allreduce(E_Rotamer_MM_Local, E_Rotamer_MM, nRotamer, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); } //eliot MPI_Allreduce(&Chi_SQ_Rotamer_Local, &Chi_SQ_Rotamer, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); // MPI_Bcast(&Chi_SQ_Rotamer, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); printf(" w_rotamer_Sum = %f\n", w_rotamer_Sum ); Chi_SQ_Rotamer *= (w_Rotamer/w_rotamer_Sum); Chi_SQ = Chi_SQ_1D + Chi_SQ_Rotamer; // MPI_Barrier(MPI_COMM_WORLD); // printf("%lf\n", Chi_SQ); // MPI_Finalize(); time_2 = time(NULL); /* if(ProgID == 0) { FILE *fOut; fOut = fopen("time-rec.txt", "a+"); fseek(fOut, 0, SEEK_END); fprintf(fOut, "%d\n", time_2-time_1); fclose(fOut); } */ printf("Chi_SQ=%f\n", Chi_SQ ); return Chi_SQ; }