void calc_dipole_rrms(system_t *system) { int i, p; double carry; atom_t **aa = system->atom_array; /* get the dipole RRMS */ for (i = 0; i < system->natoms; i++) { /* mean square difference */ aa[i]->dipole_rrms = 0; for (p = 0; p < 3; p++) { carry = aa[i]->new_mu[p] - aa[i]->old_mu[p]; aa[i]->dipole_rrms += carry * carry; } /* normalize */ aa[i]->dipole_rrms /= dddotprod(aa[i]->new_mu, aa[i]->new_mu); aa[i]->dipole_rrms = sqrt(aa[i]->dipole_rrms); if (!isfinite(aa[i]->dipole_rrms)) aa[i]->dipole_rrms = 0; } #ifdef DEBUG /* double totalrms = 0; for ( i=0; i< system->natoms; i++ ) { totalrms += aa[i]->dipole_rrms; } fprintf(stderr,"TOTAL DIPOLE RRMS %lf\n", totalrms); */ #endif return; }
void contract_dipoles(system_t *system, int *ranked_array) { int i, j, ii, jj, p, index; atom_t **aa = system->atom_array; for (i = 0; i < system->natoms; i++) { index = ranked_array[i]; //do them in the order of the ranked index ii = index * 3; if (aa[index]->polarizability == 0) { //if not polar //aa[index]->ef_induced[p] is already 0 aa[index]->new_mu[0] = aa[index]->new_mu[1] = aa[index]->new_mu[2] = 0; //might be redundant? aa[index]->mu[0] = aa[index]->mu[1] = aa[index]->mu[2] = 0; //might be redundant? continue; } for (j = 0; j < system->natoms; j++) { jj = j * 3; if (index != j) for (p = 0; p < 3; p++) aa[index]->ef_induced[p] -= dddotprod((system->A_matrix[ii + p] + jj), aa[j]->mu); } /* end j */ /* dipole is the sum of the static and induced parts */ for (p = 0; p < 3; p++) { aa[index]->new_mu[p] = aa[index]->polarizability * (aa[index]->ef_static[p] + aa[index]->ef_static_self[p] + aa[index]->ef_induced[p]); /* Gauss-Seidel */ if (system->polar_gs || system->polar_gs_ranked) aa[index]->mu[p] = aa[index]->new_mu[p]; } } /* end matrix multiply */ return; }
void printboxdim ( pbc_t * pbc ) { char buffer[MAXLINE]; sprintf(buffer,"INPUT: unit cell volume = %.3f A^3 (cutoff = %.3f A)\n", pbc->volume, pbc->cutoff); output(buffer); sprintf(buffer,"INPUT: Basis vectors { a = %8.3lf \tb = %8.3lf \tc = %8.3lf }\n", sqrt(dddotprod(pbc->basis[0], pbc->basis[0])), sqrt(dddotprod(pbc->basis[1], pbc->basis[1])), sqrt(dddotprod(pbc->basis[2], pbc->basis[2]))); output(buffer); sprintf(buffer,"INPUT: Basis angles { α = %8.3lf \tβ = %8.3lf \tγ = %8.3lf }\n", 180.0/M_PI*acos( dddotprod(pbc->basis[1],pbc->basis[2]) / sqrt( dddotprod(pbc->basis[1], pbc->basis[1]) * dddotprod(pbc->basis[2], pbc->basis[2]) ) ), 180.0/M_PI*acos( dddotprod(pbc->basis[2],pbc->basis[0]) / sqrt( dddotprod(pbc->basis[2], pbc->basis[2]) * dddotprod(pbc->basis[0], pbc->basis[0]) ) ), 180.0/M_PI*acos( dddotprod(pbc->basis[0],pbc->basis[1]) / sqrt( dddotprod(pbc->basis[0], pbc->basis[0]) * dddotprod(pbc->basis[1], pbc->basis[1]) ) )); output(buffer); return; }
void palmo_contraction(system_t *system, int *ranked_array) { int i, j, ii, jj, index, p; int N = system->natoms; atom_t **aa = system->atom_array; /* calculate change in induced field due to this iteration */ for (i = 0; i < N; i++) { index = ranked_array[i]; ii = index * 3; for (p = 0; p < 3; p++) aa[index]->ef_induced_change[p] = -aa[index]->ef_induced[p]; for (j = 0; j < N; j++) { jj = j * 3; if (index != j) for (p = 0; p < 3; p++) aa[index]->ef_induced_change[p] -= dddotprod(system->A_matrix[ii + p] + jj, aa[j]->mu); } } return; }
/* get the induction energy */ double polar(system_t *system) { molecule_t *molecule_ptr; atom_t *atom_ptr; int num_iterations; double potential; char linebuf[MAXLINE]; /* take measures to let N fluctuate */ if( (system->ensemble == ENSEMBLE_UVT || system->ensemble == ENSEMBLE_REPLAY) && !system->polar_zodid ) thole_resize_matrices(system); /* get the A matrix */ if(!system->polar_zodid) { thole_amatrix(system); if(system->polarizability_tensor) { output("POLAR: A matrix:\n"); print_matrix(3*((int)system->checkpoint->thole_N_atom), system->A_matrix); } } /* find the dipoles */ if ( system->polar_ewald_full ) { //do a full-ewald polarization treatment ewald_full(system); } else if(system->polar_iterative) { //solve the self-consistent problem thole_field(system); //calc e-field num_iterations = thole_iterative(system); //calc dipoles system->nodestats->polarization_iterations = (double)num_iterations; //statistics system->observables->dipole_rrms = get_dipole_rrms(system); if ( system->iter_success ) { switch ( system->ensemble ) { case ENSEMBLE_UVT: case ENSEMBLE_NVT: case ENSEMBLE_NVE: case ENSEMBLE_NPT: sprintf(linebuf,"POLAR: polarization iterative solver convergence failure on mc step %d.\n", system->step); error(linebuf); break; case ENSEMBLE_REPLAY: sprintf(linebuf,"POLAR: polarization iterative solver convergence failure on configuration %d.\n", system->step); error(linebuf); break; case ENSEMBLE_SURF: case ENSEMBLE_SURF_FIT: case ENSEMBLE_TE: default: sprintf(linebuf,"POLAR: polarization iterative solver failed to reach convergence.\n"); error(linebuf); } } } else { //do matrix inversion thole_field(system); //calc e-field thole_bmatrix(system); //matrix inversion thole_bmatrix_dipoles(system); //get dipoles /* output the 3x3 molecular polarizability tensor */ if(system->polarizability_tensor) { output("POLAR: B matrix:\n"); print_matrix(3*((int)system->checkpoint->thole_N_atom), system->B_matrix); thole_polarizability_tensor(system); die(0); } } /* calculate the polarization energy as 1/2 mu*E */ potential = 0; for(molecule_ptr = system->molecules; molecule_ptr; molecule_ptr = molecule_ptr->next) { for(atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next) { potential += dddotprod(atom_ptr->mu,atom_ptr->ef_static); if(system->polar_palmo) potential += dddotprod(atom_ptr->mu,atom_ptr->ef_induced_change); } } potential *= -0.5; #ifdef DEBUG fprintf(stderr,"mu MOLECULE ATOM * DIPOLES * STATIC * INDUCED * pot/atom -0.5*mu*E_s\n"); for(molecule_ptr = system->molecules; molecule_ptr; molecule_ptr = molecule_ptr->next) { for(atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next) { fprintf(stderr,"mu %4d %4d * %8.5lf %8.5lf %8.5lf * %8.5lf %8.5lf %8.5lf * %8.5lf %8.5lf %8.5lf * %lf %lf\n", molecule_ptr->id, atom_ptr->id, atom_ptr->mu[0], atom_ptr->mu[1], atom_ptr->mu[2], atom_ptr->ef_static[0], atom_ptr->ef_static[1], atom_ptr->ef_static[2], atom_ptr->ef_induced[0], atom_ptr->ef_induced[1], atom_ptr->ef_induced[2], potential/system->natoms, -0.5*atom_ptr->mu[0]*atom_ptr->ef_static[0]); } } #endif return(potential); }