コード例 #1
0
ファイル: hess.c プロジェクト: psi4/libefp
static void mass_weight_hessian(struct efp *efp, const double *in, double *out)
{
	size_t n_frags, n_coord;

	check_fail(efp_get_frag_count(efp, &n_frags));
	n_coord = 6 * n_frags;

	double mass_fact[n_frags];
	mat_t inertia_fact[n_frags];

	get_weight_factor(efp, mass_fact, inertia_fact);

	for (size_t i = 0; i < n_frags; i++) {
		for (size_t j = 0; j < n_frags; j++) {
			size_t offset = 6 * n_coord * i + 6 * j;

			w_tr_tr(mass_fact[i], mass_fact[j], n_coord,
					in + offset,
					out + offset);

			w_tr_rot(mass_fact[i], inertia_fact + j, n_coord,
					in + offset + 3,
					out + offset + 3);

			w_rot_tr(inertia_fact + i, mass_fact[j], n_coord,
					in + offset + 3 * n_coord,
					out + offset + 3 * n_coord);

			w_rot_rot(inertia_fact + i, inertia_fact + j, n_coord,
					in + offset + 3 * n_coord + 3,
					out + offset + 3 * n_coord + 3);
		}
	}
}
コード例 #2
0
ファイル: hess.c プロジェクト: psi4/libefp
static void get_weight_factor(struct efp *efp, double *mass_fact, mat_t *inertia_fact)
{
	size_t n_frags;
	check_fail(efp_get_frag_count(efp, &n_frags));

	double xyzabc[6 * n_frags];
	check_fail(efp_get_coordinates(efp, xyzabc));

	for (size_t i = 0; i < n_frags; i++) {
		double mass;
		check_fail(efp_get_frag_mass(efp, i, &mass));

		double inertia[3];
		check_fail(efp_get_frag_inertia(efp, i, inertia));

		double a = xyzabc[6 * i + 3];
		double b = xyzabc[6 * i + 4];
		double c = xyzabc[6 * i + 5];

		mat_t rotmat;
		euler_to_matrix(a, b, c, &rotmat);

		mass_fact[i] = 1.0 / sqrt(mass);
		get_inertia_factor(inertia, &rotmat, inertia_fact + i);
	}
}
コード例 #3
0
ファイル: hess.c プロジェクト: psi4/libefp
void sim_hess(struct state *state)
{
	msg("HESSIAN JOB\n\n\n");

	print_geometry(state->efp);
	compute_energy(state, true);
	print_energy(state);
	print_gradient(state);

	size_t n_frags, n_coord;
	double *hess, *mass_hess, *eigen;

	check_fail(efp_get_frag_count(state->efp, &n_frags));
	n_coord = 6 * n_frags;

	hess = xmalloc(n_coord * n_coord * sizeof(double));
	compute_hessian(state, hess);

	msg("    HESSIAN MATRIX\n\n");
	print_matrix(n_coord, n_coord, hess);

	mass_hess = xmalloc(n_coord * n_coord * sizeof(double));
	mass_weight_hessian(state->efp, hess, mass_hess);

	msg("    MASS-WEIGHTED HESSIAN MATRIX\n\n");
	print_matrix(n_coord, n_coord, mass_hess);

	msg("    NORMAL MODE ANALYSIS\n\n");

	eigen = xmalloc(n_coord * sizeof(double));

	if (efp_dsyev('V', 'U', (int)n_coord, mass_hess, (int)n_coord, eigen))
		error("unable to diagonalize mass-weighted hessian matrix");

	for (size_t i = 0; i < n_coord; i++) {
		print_mode(i + 1, eigen[i]);
		print_vector(n_coord, mass_hess + i * n_coord);
	}

	free(hess);
	free(mass_hess);
	free(eigen);

	msg("HESSIAN JOB COMPLETED SUCCESSFULLY\n");
}
コード例 #4
0
ファイル: hess.c プロジェクト: psi4/libefp
static void compute_hessian(struct state *state, double *hess)
{
	size_t n_frags, n_coord;
	double *xyzabc, *grad_f, *grad_b;
	bool central = cfg_get_bool(state->cfg, "hess_central");

	check_fail(efp_get_frag_count(state->efp, &n_frags));
	n_coord = 6 * n_frags;

	xyzabc = xmalloc(n_coord * sizeof(double));
	grad_f = xmalloc(n_coord * sizeof(double));
	grad_b = xmalloc(n_coord * sizeof(double));

	check_fail(efp_get_coordinates(state->efp, xyzabc));

	if (!central) {
		memcpy(grad_b, state->grad, n_frags * 6 * sizeof(double));

		for (size_t i = 0; i < n_frags; i++) {
			const double *euler = xyzabc + 6 * i + 3;
			double *gradptr = grad_b + 6 * i + 3;

			efp_torque_to_derivative(euler, gradptr, gradptr);
		}
	}

	for (size_t i = 0; i < n_coord; i++) {
		double save = xyzabc[i];
		double step = i % 6 < 3 ? cfg_get_double(state->cfg, "num_step_dist") :
					  cfg_get_double(state->cfg, "num_step_angle");

		show_progress(i + 1, n_coord, "FORWARD");
		xyzabc[i] = save + step;
		compute_gradient(state, n_frags, xyzabc, grad_f);

		if (central) {
			show_progress(i + 1, n_coord, "BACKWARD");
			xyzabc[i] = save - step;
			compute_gradient(state, n_frags, xyzabc, grad_b);
		}

		double delta = central ? 2.0 * step : step;

		for (size_t j = 0; j < n_coord; j++)
			hess[i * n_coord + j] = (grad_f[j] - grad_b[j]) / delta;

		xyzabc[i] = save;
	}

	/* restore original coordinates */
	check_fail(efp_set_coordinates(state->efp, EFP_COORD_TYPE_XYZABC, xyzabc));

	/* reduce error by computing the average of H(i,j) and H(j,i) */
	for (size_t i = 0; i < n_coord; i++) {
		for (size_t j = i + 1; j < n_coord; j++) {
			double sum = hess[i * n_coord + j] + hess[j * n_coord + i];

			hess[i * n_coord + j] = 0.5 * sum;
			hess[j * n_coord + i] = hess[i * n_coord + j];
		}
	}

	free(xyzabc);
	free(grad_f);
	free(grad_b);

	msg("\n\n");
}
コード例 #5
0
ファイル: energy.c プロジェクト: psi4/libefp
/* current coordinates from efp struct are used */
void compute_energy(struct state *state, bool do_grad)
{
	struct efp_atom *atoms;
	struct efp_energy efp_energy;
	double xyz[3], xyzabc[6], *grad;
	size_t ifrag, nfrag, iatom, natom;
	int itotal;

	/* EFP part */
	check_fail(efp_compute(state->efp, do_grad));
	check_fail(efp_get_energy(state->efp, &efp_energy));
	check_fail(efp_get_frag_count(state->efp, &nfrag));

	if (do_grad) {
		check_fail(efp_get_gradient(state->efp, state->grad));
		check_fail(efp_get_point_charge_gradient(state->efp,
		    state->grad + 6 * nfrag));
	}

	state->energy = efp_energy.total;

	/* constraints */
	for (ifrag = 0; ifrag < nfrag; ifrag++) {
		const struct frag *frag = state->sys->frags + ifrag;

		check_fail(efp_get_frag_xyzabc(state->efp, ifrag, xyzabc));

		if (frag->constraint_enable) {
			double dr2, drx, dry, drz;

			drx = xyzabc[0] - frag->constraint_xyz.x;
			dry = xyzabc[1] - frag->constraint_xyz.y;
			drz = xyzabc[2] - frag->constraint_xyz.z;

			dr2 = drx * drx + dry * dry + drz * drz;
			state->energy += 0.5 * frag->constraint_k * dr2;

			if (do_grad) {
				grad = state->grad + 6 * ifrag;
				grad[0] += frag->constraint_k * drx;
				grad[1] += frag->constraint_k * dry;
				grad[2] += frag->constraint_k * drz;
			}
		}
	}

	/* MM force field part */
	if (state->ff == NULL)
		return;

	for (ifrag = 0, itotal = 0; ifrag < nfrag; ifrag++) {
		check_fail(efp_get_frag_atom_count(state->efp, ifrag, &natom));
		atoms = malloc(natom * sizeof(struct efp_atom));
		check_fail(efp_get_frag_atoms(state->efp, ifrag, natom, atoms));

		for (iatom = 0; iatom < natom; iatom++, itotal++)
			ff_set_atom_xyz(state->ff, itotal, &atoms[iatom].x);

		free(atoms);
	}

	ff_compute(state->ff, do_grad);

	if (do_grad) {
		for (ifrag = 0, itotal = 0, grad = state->grad; ifrag < nfrag; ifrag++, grad += 6) {
			check_fail(efp_get_frag_xyzabc(state->efp, ifrag, xyzabc));
			check_fail(efp_get_frag_atom_count(state->efp, ifrag, &natom));
			atoms = malloc(natom * sizeof(struct efp_atom));
			check_fail(efp_get_frag_atoms(state->efp, ifrag, natom, atoms));

			for (iatom = 0; iatom < natom; iatom++, itotal++) {
				ff_get_atom_gradient(state->ff, itotal, xyz);

				grad[0] += xyz[0];
				grad[1] += xyz[1];
				grad[2] += xyz[2];

				grad[3] += (atoms[iatom].y - xyzabc[1]) * xyz[2] -
					   (atoms[iatom].z - xyzabc[2]) * xyz[1];
				grad[4] += (atoms[iatom].z - xyzabc[2]) * xyz[0] -
					   (atoms[iatom].x - xyzabc[0]) * xyz[2];
				grad[5] += (atoms[iatom].x - xyzabc[0]) * xyz[1] -
					   (atoms[iatom].y - xyzabc[1]) * xyz[0];
			}

			free(atoms);
		}
	}

	state->energy += ff_get_energy(state->ff);
}
コード例 #6
0
ファイル: energy.c プロジェクト: SahanGH/psi4public
/* current coordinates from efp struct are used */
void compute_energy(struct state *state, bool do_grad)
{
	struct efp_atom *atoms;
	struct efp_energy efp_energy;
	double xyz[3], xyzabc[6], *grad;
	size_t ifrag, nfrag, iatom, natom;
	int itotal;

	check_fail(efp_compute(state->efp, do_grad));
	check_fail(efp_get_energy(state->efp, &efp_energy));
	check_fail(efp_get_frag_count(state->efp, &nfrag));

	if (do_grad) {
		check_fail(efp_get_gradient(state->efp, state->grad));
		check_fail(efp_get_point_charge_gradient(state->efp, state->grad + 6 * nfrag));
	}

	state->energy = efp_energy.total;

	if (state->ff == NULL)
		return;

	for (ifrag = 0, itotal = 0; ifrag < nfrag; ifrag++) {
		check_fail(efp_get_frag_atom_count(state->efp, ifrag, &natom));
		atoms = malloc(natom * sizeof(struct efp_atom));
		check_fail(efp_get_frag_atoms(state->efp, ifrag, natom, atoms));

		for (iatom = 0; iatom < natom; iatom++, itotal++)
			ff_set_atom_xyz(state->ff, itotal, &atoms[iatom].x);

		free(atoms);
	}

	ff_compute(state->ff, do_grad);

	if (do_grad) {
		for (ifrag = 0, itotal = 0, grad = state->grad; ifrag < nfrag; ifrag++, grad += 6) {
			check_fail(efp_get_frag_xyzabc(state->efp, ifrag, xyzabc));
			check_fail(efp_get_frag_atom_count(state->efp, ifrag, &natom));
			atoms = malloc(natom * sizeof(struct efp_atom));
			check_fail(efp_get_frag_atoms(state->efp, ifrag, natom, atoms));

			for (iatom = 0; iatom < natom; iatom++, itotal++) {
				ff_get_atom_gradient(state->ff, itotal, xyz);

				grad[0] += xyz[0];
				grad[1] += xyz[1];
				grad[2] += xyz[2];

				grad[3] += (atoms[iatom].y - xyzabc[1]) * xyz[2] -
					   (atoms[iatom].z - xyzabc[2]) * xyz[1];
				grad[4] += (atoms[iatom].z - xyzabc[2]) * xyz[0] -
					   (atoms[iatom].x - xyzabc[0]) * xyz[2];
				grad[5] += (atoms[iatom].x - xyzabc[0]) * xyz[1] -
					   (atoms[iatom].y - xyzabc[1]) * xyz[0];
			}

			free(atoms);
		}
	}

	state->energy += ff_get_energy(state->ff);
}