Example #1
0
static enum efp_result
check_opts(const struct efp_opts *opts)
{
	if (opts->enable_pbc) {
		if ((opts->terms & EFP_TERM_AI_ELEC) ||
		    (opts->terms & EFP_TERM_AI_POL) ||
		    (opts->terms & EFP_TERM_AI_DISP) ||
		    (opts->terms & EFP_TERM_AI_XR) ||
		    (opts->terms & EFP_TERM_AI_CHTR)) {
			efp_log("periodic calculations are not supported for QM/EFP");
			return EFP_RESULT_FATAL;
		}

		if (!opts->enable_cutoff) {
			efp_log("periodic calculations require interaction cutoff");
			return EFP_RESULT_FATAL;
		}
	}

	if (opts->enable_cutoff) {
		if (opts->swf_cutoff < 1.0) {
			efp_log("interaction cutoff is too small");
			return EFP_RESULT_FATAL;
		}
	}

	return EFP_RESULT_SUCCESS;
}
Example #2
0
static enum efp_result
set_coord_points(struct frag *frag, const double *coord)
{
	if (frag->n_atoms < 3) {
		efp_log("fragment must contain at least three atoms");
		return EFP_RESULT_FATAL;
	}

	double ref[9] = {
		frag->lib->atoms[0].x, frag->lib->atoms[0].y, frag->lib->atoms[0].z,
		frag->lib->atoms[1].x, frag->lib->atoms[1].y, frag->lib->atoms[1].z,
		frag->lib->atoms[2].x, frag->lib->atoms[2].y, frag->lib->atoms[2].z
	};

	vec_t p1;
	mat_t rot1, rot2;

	efp_points_to_matrix(coord, &rot1);
	efp_points_to_matrix(ref, &rot2);
	rot2 = mat_transpose(&rot2);
	frag->rotmat = mat_mat(&rot1, &rot2);
	p1 = mat_vec(&frag->rotmat, VEC(frag->lib->atoms[0].x));

	/* center of mass */
	frag->x = coord[0] - p1.x;
	frag->y = coord[1] - p1.y;
	frag->z = coord[2] - p1.z;

	update_fragment(frag);
	return EFP_RESULT_SUCCESS;
}
Example #3
0
enum efp_result
efp_compute_id_direct(struct efp *efp)
{
	double *c;
	size_t n;
	fortranint_t *ipiv;
	enum efp_result res;

	n = 3 * efp->n_polarizable_pts;
	c = (double *)calloc(n * n, sizeof *c);
	ipiv = (fortranint_t *)calloc(n, sizeof *ipiv);

	if (c == NULL || ipiv == NULL) {
		res = EFP_RESULT_NO_MEMORY;
		goto error;
	}

	/* induced dipoles */
	compute_lhs(efp, c, 0);
	compute_rhs(efp, efp->indip, 0);
	transpose_matrix(c, n);

	if (efp_dgesv((fortranint_t)n, 1, c, (fortranint_t)n, ipiv,
	    (double *)efp->indip, (fortranint_t)n) != 0) {
		efp_log("dgesv: error solving for induced dipoles");
		res = EFP_RESULT_FATAL;
		goto error;
	}

	/* conjugate induced dipoles */
	compute_lhs(efp, c, 1);
	compute_rhs(efp, efp->indipconj, 1);
	transpose_matrix(c, n);

	if (efp_dgesv((fortranint_t)n, 1, c, (fortranint_t)n, ipiv,
	    (double *)efp->indipconj, (fortranint_t)n) != 0) {
		efp_log("dgesv: error solving for conjugate induced dipoles");
		res = EFP_RESULT_FATAL;
		goto error;
	}
	res = EFP_RESULT_SUCCESS;
error:
	free(c);
	free(ipiv);
	return res;
}
Example #4
0
EFP_EXPORT enum efp_result
efp_compute(struct efp *efp, int do_gradient)
{
	enum efp_result res;

	assert(efp);

	if (efp->grad == NULL) {
		efp_log("call efp_prepare after all fragments are added");
		return (EFP_RESULT_FATAL);
	}

	efp->do_gradient = do_gradient;

	if ((res = check_params(efp)))
		return (res);

	memset(&efp->energy, 0, sizeof(struct efp_energy));
	memset(&efp->stress, 0, sizeof(mat_t));
	memset(efp->grad, 0, efp->n_frag * sizeof(six_t));
	memset(efp->ptc_grad, 0, efp->n_ptc * sizeof(vec_t));

	efp_balance_work(efp, compute_two_body_range, NULL);

	if ((res = efp_compute_pol(efp)))
		return res;

	if ((res = efp_compute_ai_elec(efp)))
		return res;

	if ((res = efp_compute_ai_disp(efp)))
		return res;

#ifdef WITH_MPI
	efp_allreduce(&efp->energy.electrostatic, 1);
	efp_allreduce(&efp->energy.dispersion, 1);
	efp_allreduce(&efp->energy.exchange_repulsion, 1);
	efp_allreduce(&efp->energy.charge_penetration, 1);

	if (efp->do_gradient) {
		efp_allreduce((double *)efp->grad, 6 * efp->n_frag);
		efp_allreduce((double *)efp->ptc_grad, 3 * efp->n_ptc);
		efp_allreduce((double *)&efp->stress, 9);
	}
#endif
	efp->energy.total = efp->energy.electrostatic +
			    efp->energy.charge_penetration +
			    efp->energy.electrostatic_point_charges +
			    efp->energy.polarization +
			    efp->energy.dispersion +
			    efp->energy.ai_dispersion +
			    efp->energy.exchange_repulsion;

	return EFP_RESULT_SUCCESS;
}
Example #5
0
EFP_EXPORT enum efp_result
efp_get_stress_tensor(struct efp *efp, double *stress)
{
	assert(efp);
	assert(stress);

	if (!efp->do_gradient) {
		efp_log("gradient calculation was not requested");
		return (EFP_RESULT_FATAL);
	}

	*(mat_t *)stress = efp->stress;

	return (EFP_RESULT_SUCCESS);
}
Example #6
0
EFP_EXPORT enum efp_result
efp_get_point_charge_gradient(struct efp *efp, double *grad)
{
	assert(efp);
	assert(grad);

	if (!efp->do_gradient) {
		efp_log("gradient calculation was not requested");
		return (EFP_RESULT_FATAL);
	}

	memcpy(grad, efp->ptc_grad, efp->n_ptc * sizeof(vec_t));

	return (EFP_RESULT_SUCCESS);
}
Example #7
0
static enum efp_result
set_coord_rotmat(struct frag *frag, const double *coord)
{
	if (!efp_check_rotation_matrix((const mat_t *)(coord + 3))) {
		efp_log("invalid rotation matrix specified");
		return EFP_RESULT_FATAL;
	}

	frag->x = coord[0];
	frag->y = coord[1];
	frag->z = coord[2];

	memcpy(&frag->rotmat, coord + 3, sizeof(mat_t));

	update_fragment(frag);
	return EFP_RESULT_SUCCESS;
}
Example #8
0
EFP_EXPORT enum efp_result
efp_set_periodic_box(struct efp *efp, double x, double y, double z)
{
	assert(efp);

	if (x < 2.0 * efp->opts.swf_cutoff ||
	    y < 2.0 * efp->opts.swf_cutoff ||
	    z < 2.0 * efp->opts.swf_cutoff) {
		efp_log("periodic box dimensions must be at least twice the cutoff");
		return EFP_RESULT_FATAL;
	}

	efp->box.x = x;
	efp->box.y = y;
	efp->box.z = z;

	return EFP_RESULT_SUCCESS;
}
Example #9
0
EFP_EXPORT enum efp_result
efp_get_xrfit(struct efp *efp, size_t frag_idx, double *xrfit)
{
	struct frag *frag;

	assert(efp != NULL);
	assert(frag_idx < efp->n_frag);
	assert(xrfit != NULL);

	frag = efp->frags + frag_idx;

	if (frag->xrfit == NULL) {
		efp_log("no XRFIT parameters for fragment %s", frag->name);
		return (EFP_RESULT_FATAL);
	}

	memcpy(xrfit, frag->xrfit, frag->n_lmo * 4 * sizeof(double));

	return (EFP_RESULT_SUCCESS);
}
Example #10
0
EFP_EXPORT enum efp_result
efp_get_lmo_coordinates(struct efp *efp, size_t frag_idx, double *xyz)
{
	struct frag *frag;

	assert(efp != NULL);
	assert(frag_idx < efp->n_frag);
	assert(xyz != NULL);

	frag = efp->frags + frag_idx;

	if (frag->lmo_centroids == NULL) {
		efp_log("no LMO centroids for fragment %s", frag->name);
		return (EFP_RESULT_FATAL);
	}

	memcpy(xyz, frag->lmo_centroids, frag->n_lmo * sizeof(vec_t));

	return (EFP_RESULT_SUCCESS);
}
Example #11
0
File: efp.c Project: psi4/libefp
EFP_EXPORT enum efp_result
efp_get_ai_screen(struct efp *efp, size_t frag_idx, double *screen)
{
	const struct frag *frag;
	size_t size;

	assert(efp);
	assert(screen);
	assert(frag_idx < efp->n_frag);

	frag = &efp->frags[frag_idx];

	if (frag->ai_screen_params == NULL) {
		efp_log("no screening parameters found for %s", frag->name);
		return (EFP_RESULT_FATAL);
	}

	size = frag->n_multipole_pts * sizeof(double);
	memcpy(screen, frag->ai_screen_params, size);

	return (EFP_RESULT_SUCCESS);
}
Example #12
0
File: efp.c Project: psi4/libefp
static enum efp_result
set_coord_points(struct frag *frag, const double *coord)
{
	/* allow fragments with less than 3 atoms by using multipole points of
	 * ghost atoms; multipole points have the same coordinates as atoms */
	if (frag->n_multipole_pts < 3) {
		efp_log("fragment must contain at least three atoms");
		return EFP_RESULT_FATAL;
	}

	double ref[9] = {
		frag->lib->multipole_pts[0].x,
		frag->lib->multipole_pts[0].y,
		frag->lib->multipole_pts[0].z,
		frag->lib->multipole_pts[1].x,
		frag->lib->multipole_pts[1].y,
		frag->lib->multipole_pts[1].z,
		frag->lib->multipole_pts[2].x,
		frag->lib->multipole_pts[2].y,
		frag->lib->multipole_pts[2].z
	};

	vec_t p1;
	mat_t rot1, rot2;

	efp_points_to_matrix(coord, &rot1);
	efp_points_to_matrix(ref, &rot2);
	rot2 = mat_transpose(&rot2);
	frag->rotmat = mat_mat(&rot1, &rot2);
	p1 = mat_vec(&frag->rotmat, VEC(frag->lib->multipole_pts[0].x));

	/* center of mass */
	frag->x = coord[0] - p1.x;
	frag->y = coord[1] - p1.y;
	frag->z = coord[2] - p1.z;

	update_fragment(frag);
	return EFP_RESULT_SUCCESS;
}
Example #13
0
File: efp.c Project: psi4/libefp
EFP_EXPORT enum efp_result
efp_add_fragment(struct efp *efp, const char *name)
{
	assert(efp);
	assert(name);

	enum efp_result res;
	const struct frag *lib = efp_find_lib(efp, name);

	if (!lib) {
		efp_log("unknown fragment \"%s\"; check its .efp file", name);
		return EFP_RESULT_UNKNOWN_FRAGMENT;
	}

	efp->n_frag++;
	efp->frags = (struct frag *)realloc(efp->frags,
		efp->n_frag * sizeof(struct frag));

	if (!efp->frags)
		return EFP_RESULT_NO_MEMORY;

	struct frag *frag = efp->frags + efp->n_frag - 1;

	if ((res = copy_frag(frag, lib)))
		return res;

	for (size_t a = 0; a < 3; a++) {
		size_t size = frag->xr_wf_size * frag->n_lmo;

		frag->xr_wf_deriv[a] = (double *)calloc(size, sizeof(double));

		if (!frag->xr_wf_deriv[a])
			return EFP_RESULT_NO_MEMORY;
	}

	return EFP_RESULT_SUCCESS;
}
Example #14
0
static enum efp_result
check_frag_params(const struct efp_opts *opts, const struct frag *frag)
{
	if ((opts->terms & EFP_TERM_ELEC) || (opts->terms & EFP_TERM_AI_ELEC)) {
		if (!frag->multipole_pts) {
			efp_log("electrostatic parameters are missing");
			return EFP_RESULT_FATAL;
		}

		if (opts->elec_damp == EFP_ELEC_DAMP_SCREEN && !frag->screen_params) {
			efp_log("screening parameters are missing");
			return EFP_RESULT_FATAL;
		}
	}
	if ((opts->terms & EFP_TERM_POL) || (opts->terms & EFP_TERM_AI_POL)) {
		if (!frag->polarizable_pts || !frag->multipole_pts) {
			efp_log("polarization parameters are missing");
			return EFP_RESULT_FATAL;
		}
	}
	if ((opts->terms & EFP_TERM_DISP) || (opts->terms & EFP_TERM_AI_DISP)) {
		if (!frag->dynamic_polarizable_pts) {
			efp_log("dispersion parameters are missing");
			return EFP_RESULT_FATAL;
		}

		if (opts->disp_damp == EFP_DISP_DAMP_OVERLAP &&
		    frag->n_lmo != frag->n_dynamic_polarizable_pts) {
			efp_log("number of polarization points does not match number of LMOs");
			return EFP_RESULT_FATAL;
		}
	}
	if ((opts->terms & EFP_TERM_XR) || (opts->terms & EFP_TERM_AI_XR)) {
		if (!frag->xr_atoms ||
		    !frag->xr_fock_mat ||
		    !frag->xr_wf ||
		    !frag->lmo_centroids) {
			efp_log("exchange repulsion parameters are missing");
			return EFP_RESULT_FATAL;
		}
	}
	return EFP_RESULT_SUCCESS;
}