Ejemplo n.º 1
0
Archivo: hess.c Proyecto: 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);
	}
}
Ejemplo n.º 2
0
Archivo: hess.c Proyecto: 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");
}
Ejemplo n.º 3
0
static struct md *md_create(struct state *state)
{
	struct md *md = xcalloc(1, sizeof(struct md));

	md->state = state;
	md->box = box_from_str(cfg_get_string(state->cfg, "periodic_box"));

	switch (cfg_get_enum(state->cfg, "ensemble")) {
		case ENSEMBLE_TYPE_NVE:
			md->get_invariant = get_invariant_nve;
			md->update_step = update_step_nve;
			break;
		case ENSEMBLE_TYPE_NVT:
			md->get_invariant = get_invariant_nvt;
			md->update_step = update_step_nvt;
			md->data = xcalloc(1, sizeof(struct nvt_data));
			break;
		case ENSEMBLE_TYPE_NPT:
			md->get_invariant = get_invariant_npt;
			md->update_step = update_step_npt;
			md->data = xcalloc(1, sizeof(struct npt_data));
			break;
		default:
			assert(0);
	}

	md->n_bodies = state->sys->n_frags;
	md->bodies = xcalloc(md->n_bodies, sizeof(struct body));

	double coord[6 * md->n_bodies];
	check_fail(efp_get_coordinates(state->efp, coord));

	for (size_t i = 0; i < md->n_bodies; i++) {
		struct body *body = md->bodies + i;

		body->pos.x = coord[6 * i + 0];
		body->pos.y = coord[6 * i + 1];
		body->pos.z = coord[6 * i + 2];

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

		euler_to_matrix(a, b, c, &body->rotmat);

		body->vel.x = md->state->sys->frags[i].vel[0];
		body->vel.y = md->state->sys->frags[i].vel[1];
		body->vel.z = md->state->sys->frags[i].vel[2];

		set_body_mass_and_inertia(state->efp, i, body);

		body->angmom.x = md->state->sys->frags[i].vel[3] * body->inertia.x;
		body->angmom.y = md->state->sys->frags[i].vel[4] * body->inertia.y;
		body->angmom.z = md->state->sys->frags[i].vel[5] * body->inertia.z;

		md->n_freedom += 3;

		if (body->inertia.x > EPSILON)
			md->n_freedom++;
		if (body->inertia.y > EPSILON)
			md->n_freedom++;
		if (body->inertia.z > EPSILON)
			md->n_freedom++;
	}

	return (md);
}