示例#1
0
bool VECTOR_ensure_not_complex(CVECTOR *_object)
{
	gsl_vector *v;
	int size = SIZE(THIS);
	int i;
	gsl_complex c;
	
	if (!COMPLEX(THIS))
		return FALSE;
	
	for (i = 0; i < size; i++)
	{
		c = gsl_vector_complex_get(CVEC(THIS), i);
		if (GSL_IMAG(c) != 0.0)
			return TRUE;
	}
	
	v = gsl_vector_alloc(size);
	
	for (i = 0; i < size; i++)
		gsl_vector_set(v, i, GSL_REAL(gsl_vector_complex_get(CVEC(THIS), i)));
	
	gsl_vector_complex_free(CVEC(THIS));
	THIS->vector = v;
	THIS->complex = FALSE;
	return FALSE;
}
示例#2
0
static CVECTOR *VECTOR_copy(CVECTOR *_object)
{
	CVECTOR *copy = VECTOR_create(SIZE(THIS), COMPLEX(THIS), FALSE);
	if (!COMPLEX(THIS))
		gsl_vector_memcpy(VEC(copy), VEC(THIS));
	else
		gsl_vector_complex_memcpy(CVEC(copy), CVEC(THIS));
	
	return copy;
}
示例#3
0
static int _equal(CVECTOR *a, CVECTOR *b, bool invert)
{
	if (COMPLEX(a) || COMPLEX(b))
	{
		VECTOR_ensure_complex(a);
		VECTOR_ensure_complex(b);
		return gsl_vector_complex_equal(CVEC(a), CVEC(b));
	}
	else
		return gsl_vector_equal(VEC(a), VEC(b));
}
示例#4
0
文件: efp.c 项目: SahanGH/psi4public
static void
update_fragment(struct frag *frag)
{
	/* update atoms */
	for (size_t i = 0; i < frag->n_atoms; i++)
		efp_move_pt(CVEC(frag->x), &frag->rotmat,
			CVEC(frag->lib->atoms[i].x), VEC(frag->atoms[i].x));

	efp_update_elec(frag);
	efp_update_pol(frag);
	efp_update_disp(frag);
	efp_update_xr(frag);
}
示例#5
0
文件: pol.c 项目: SahanGH/psi4public
void
efp_update_pol(struct frag *frag)
{
	for (size_t i = 0; i < frag->n_polarizable_pts; i++) {
		efp_move_pt(CVEC(frag->x), &frag->rotmat,
			CVEC(frag->lib->polarizable_pts[i].x),
			VEC(frag->polarizable_pts[i].x));

		const mat_t *in = &frag->lib->polarizable_pts[i].tensor;
		mat_t *out = &frag->polarizable_pts[i].tensor;

		efp_rotate_t2(&frag->rotmat, (const double *)in, (double *)out);
	}
}
示例#6
0
static CVECTOR *_sub(CVECTOR *a, CVECTOR *b, bool invert)
{
	CVECTOR *v = VECTOR_make(a);
	
	if (COMPLEX(v) || COMPLEX(b))
	{
		VECTOR_ensure_complex(v);
		VECTOR_ensure_complex(b);
		gsl_vector_complex_sub(CVEC(v), CVEC(b));
	}
	else
		gsl_vector_sub(VEC(v), VEC(b));
	
	return v;
}
示例#7
0
static char *_to_string(CVECTOR *_object, bool local)
{
	char *result = NULL;
	int i;
	int size = SIZE(THIS);
	char *str;
	int len;
	
	result = GB.AddChar(result, '[');
	
	for (i = 0; i < size; i++)
	{
		if (i)
			result = GB.AddChar(result, local ? ' ' : ',');
		
		if (!COMPLEX(THIS))
		{
			GB.NumberToString(local, gsl_vector_get(VEC(THIS), i), NULL, &str, &len);
			result = GB.AddString(result, str, len);
		}
		else
		{
			str = COMPLEX_to_string(gsl_vector_complex_get(CVEC(THIS), i), local);
			result = GB.AddString(result, str, GB.StringLength(str));
			GB.FreeString(&str);
		}
	}
	
	result = GB.AddChar(result, ']');
	
	return result;
}
示例#8
0
文件: disp.c 项目: psi4/libefp
static double
disp_tt(struct efp *efp, size_t fr_i_idx, size_t fr_j_idx,
	size_t pt_i_idx, size_t pt_j_idx, double sum, const struct swf *swf)
{
	const struct frag *fr_i = efp->frags + fr_i_idx;
	const struct frag *fr_j = efp->frags + fr_j_idx;

	const struct dynamic_polarizable_pt *pt_i =
				fr_i->dynamic_polarizable_pts + pt_i_idx;
	const struct dynamic_polarizable_pt *pt_j =
				fr_j->dynamic_polarizable_pts + pt_j_idx;

	vec_t dr = {
		pt_j->x - pt_i->x - swf->cell.x,
		pt_j->y - pt_i->y - swf->cell.y,
		pt_j->z - pt_i->z - swf->cell.z
	};

	double r = vec_len(&dr);
	double r2 = r * r;
	double r6 = r2 * r2 * r2;

	double damp = get_damp_tt(r);
	double energy = -4.0 / 3.0 * sum * damp / r6;

	if (efp->do_gradient) {
		double gdamp = get_damp_tt_grad(r);
		double g = 4.0 / 3.0 * sum * (gdamp / r - 6.0 * damp / r2) / r6;

		vec_t force = {
			g * dr.x * swf->swf,
			g * dr.y * swf->swf,
			g * dr.z * swf->swf
		};

		efp_add_force(efp->grad + fr_i_idx, CVEC(fr_i->x),
				CVEC(pt_i->x), &force, NULL);
		efp_sub_force(efp->grad + fr_j_idx, CVEC(fr_j->x),
				CVEC(pt_j->x), &force, NULL);
		efp_add_stress(&swf->dr, &force, &efp->stress);
	}

	return energy;
}
示例#9
0
文件: disp.c 项目: psi4/libefp
void
efp_update_disp(struct frag *frag)
{
	for (size_t i = 0; i < frag->n_dynamic_polarizable_pts; i++) {
		const struct dynamic_polarizable_pt *pt_in =
					frag->lib->dynamic_polarizable_pts + i;
		struct dynamic_polarizable_pt *pt_out =
					frag->dynamic_polarizable_pts + i;

		efp_move_pt(CVEC(frag->x), &frag->rotmat, CVEC(pt_in->x), VEC(pt_out->x));

		for (size_t j = 0; j < 12; j++) {
			const mat_t *in = pt_in->tensor + j;
			mat_t *out = pt_out->tensor + j;

			efp_rotate_t2(&frag->rotmat, (const double *)in, (double *)out);
		}
	}
}
示例#10
0
static CVECTOR *_mulf(CVECTOR *a, double f, bool invert)
{
	CVECTOR *v = VECTOR_make(a);
	
	if (COMPLEX(v))
		gsl_vector_complex_scale(CVEC(v), gsl_complex_rect(f, 0));
	else
		gsl_vector_scale(VEC(v), f);
	
	return v;
}
示例#11
0
static CVECTOR *_mulo(CVECTOR *a, void *b, bool invert)
{
	CVECTOR *v = VECTOR_make(a);
	
	if (!GB.Is(b, CLASS_Complex))
		return NULL;
	
	VECTOR_ensure_complex(v);
	gsl_vector_complex_scale(CVEC(v), ((CCOMPLEX *)b)->number);
	
	return v;
}
示例#12
0
static CVECTOR *_divo(CVECTOR *a, void *b, bool invert)
{
	if (!GB.Is(b, CLASS_Complex))
		return NULL;
	
	CCOMPLEX *c = (CCOMPLEX *)b;
	
	if (invert)
		return NULL;
	
	if (GSL_REAL(c->number) == 0 && GSL_IMAG(c->number) == 0)
	{
		GB.Error(GB_ERR_ZERO);
		return NULL;
	}

	CVECTOR *v = VECTOR_make(a);

	VECTOR_ensure_complex(v);
	gsl_vector_complex_scale(CVEC(v), gsl_complex_inverse(c->number));
	
	return v;
}
示例#13
0
文件: disp.c 项目: psi4/libefp
static double
disp_overlap(struct efp *efp, size_t fr_i_idx, size_t fr_j_idx,
	     size_t pt_i_idx, size_t pt_j_idx, double s_ij, six_t ds_ij,
	     double sum, const struct swf *swf)
{
	const struct frag *fr_i = efp->frags + fr_i_idx;
	const struct frag *fr_j = efp->frags + fr_j_idx;

	const struct dynamic_polarizable_pt *pt_i =
				fr_i->dynamic_polarizable_pts + pt_i_idx;
	const struct dynamic_polarizable_pt *pt_j =
				fr_j->dynamic_polarizable_pts + pt_j_idx;

	vec_t dr = {
		pt_j->x - pt_i->x - swf->cell.x,
		pt_j->y - pt_i->y - swf->cell.y,
		pt_j->z - pt_i->z - swf->cell.z
	};

	double r = vec_len(&dr);
	double r2 = r * r;
	double r6 = r2 * r2 * r2;

	double ln_s = 0.0;
	double damp = 1.0;

	if (fabs(s_ij) > 1.0e-5) {
		ln_s = log(fabs(s_ij));
		damp = 1.0 - s_ij * s_ij * (1.0 - 2.0 * ln_s + 2.0 * ln_s * ln_s);
	}

	double energy = -4.0 / 3.0 * sum * damp / r6;

	if (efp->do_gradient) {
		vec_t force, torque_i, torque_j;

		double t1 = -8.0 * sum / r6 / r2 * damp;
		double t2 = -16.0 / 3.0 * sum / r6 * ln_s * ln_s * s_ij;

		vec_t dr_i = vec_sub(CVEC(pt_i->x), CVEC(fr_i->x));
		vec_t dr_j = vec_sub(CVEC(pt_j->x), CVEC(fr_j->x));

		force.x = (t1 * dr.x - t2 * ds_ij.x) * swf->swf;
		force.y = (t1 * dr.y - t2 * ds_ij.y) * swf->swf;
		force.z = (t1 * dr.z - t2 * ds_ij.z) * swf->swf;

		torque_i.x = swf->swf * (t1 * (dr.z * dr_i.y - dr.y * dr_i.z) +
						t2 * ds_ij.a);
		torque_i.y = swf->swf * (t1 * (dr.x * dr_i.z - dr.z * dr_i.x) +
						t2 * ds_ij.b);
		torque_i.z = swf->swf * (t1 * (dr.y * dr_i.x - dr.x * dr_i.y) +
						t2 * ds_ij.c);

		torque_j.x = swf->swf * (t1 * (dr.z * dr_j.y - dr.y * dr_j.z) +
			     t2 * (ds_ij.z * swf->dr.y - ds_ij.y * swf->dr.z) +
			     t2 * ds_ij.a);
		torque_j.y = swf->swf * (t1 * (dr.x * dr_j.z - dr.z * dr_j.x) +
			     t2 * (ds_ij.x * swf->dr.z - ds_ij.z * swf->dr.x) +
			     t2 * ds_ij.b);
		torque_j.z = swf->swf * (t1 * (dr.y * dr_j.x - dr.x * dr_j.y) +
			     t2 * (ds_ij.y * swf->dr.x - ds_ij.x * swf->dr.y) +
			     t2 * ds_ij.c);

		six_atomic_add_xyz(efp->grad + fr_i_idx, &force);
		six_atomic_add_abc(efp->grad + fr_i_idx, &torque_i);

		six_atomic_sub_xyz(efp->grad + fr_j_idx, &force);
		six_atomic_sub_abc(efp->grad + fr_j_idx, &torque_j);

		efp_add_stress(&swf->dr, &force, &efp->stress);
	}

	return energy;
}
示例#14
0
void efp_st_int(size_t n_atoms_i, const struct xr_atom *atoms_i,
		size_t n_atoms_j, const struct xr_atom *atoms_j,
		size_t stride, double *s, double *t)
{
	double xin[90];
	double yin[90];
	double zin[90];

	double ft[100], dij[100];
	double sblk[100], tblk[100];

	for (size_t iii = 0, loc_i = 0; iii < n_atoms_i; iii++) {
		const struct xr_atom *at_i = atoms_i + iii;

	/* shell i */
	for (size_t ii = 0; ii < at_i->n_shells; ii++) {
		const struct shell *sh_i = at_i->shells + ii;

		size_t type_i = get_shell_idx(sh_i->type);
		size_t start_i = get_shell_start(type_i);
		size_t end_i = get_shell_end(type_i);
		size_t sl_i = get_shell_sl(type_i);
		size_t count_i = end_i - start_i;

		for (size_t jjj = 0, loc_j = 0; jjj < n_atoms_j; jjj++) {
			const struct xr_atom *at_j = atoms_j + jjj;

		/* shell j */
		for (size_t jj = 0; jj < at_j->n_shells; jj++) {
			const struct shell *sh_j = at_j->shells + jj;

			size_t type_j = get_shell_idx(sh_j->type);
			size_t start_j = get_shell_start(type_j);
			size_t end_j = get_shell_end(type_j);
			size_t sl_j = get_shell_sl(type_j);
			size_t count_j = end_j - start_j;

			size_t count = count_i * count_j;

			memset(sblk, 0, count * sizeof(double));
			memset(tblk, 0, count * sizeof(double));

			init_ft(count_i, sh_j->type, ft);

			double rr = vec_dist_2(CVEC(at_i->x), CVEC(at_j->x));

			const size_t *shift_x = shift_table_x[type_i * 5 + type_j];
			const size_t *shift_y = shift_table_y[type_i * 5 + type_j];
			const size_t *shift_z = shift_table_z[type_i * 5 + type_j];

			const double *coef_i = sh_i->coef;

			/* primitive i */
			for (size_t ig = 0; ig < sh_i->n_funcs; ig++) {
				double ai = *coef_i++;

				double con_i[20];
				set_coef(con_i, sh_i->type, coef_i);

				coef_i++;
				if (sh_i->type == 'L')
					coef_i++;

				const double *coef_j = sh_j->coef;

				/* primitive j */
				for (size_t jg = 0; jg < sh_j->n_funcs; jg++) {
					double aj = *coef_j++;

					double aa = 1.0 / (ai + aj);
					double tmp = aj * ai * rr * aa;

					if (tmp > int_tol) {
						coef_j++;
						if (sh_j->type == 'L')
							coef_j++;

						continue;
					}

					double con_j[20];
					set_coef(con_j, sh_j->type, coef_j);

					coef_j++;
					if (sh_j->type == 'L')
						coef_j++;

					vec_t a = {
						(ai * at_i->x + aj * at_j->x) * aa,
						(ai * at_i->y + aj * at_j->y) * aa,
						(ai * at_i->z + aj * at_j->z) * aa
					};

					double fac = exp(-tmp);

					for (size_t i = start_i, idx = 0; i < end_i; i++)
						for (size_t j = start_j; j < end_j; j++, idx++)
							dij[idx] = fac * con_i[i] * int_norm[i] * con_j[j] * int_norm[j];

					double taa = sqrt(aa);
					double t1 = -2.0 * aj * aj * taa;
					double t2 = -0.5 * taa;

					for (size_t i = 0, idx = 0; i < sl_i; i++, idx += 5) {
						for (size_t j = 0; j < sl_j; j++) {
							vec_t iout;

							make_int(i, j, taa, &a, CVEC(at_i->x), CVEC(at_j->x), &iout);
							xin[idx + j] = iout.x * taa;
							yin[idx + j] = iout.y * taa;
							zin[idx + j] = iout.z * taa;

							make_int(i, j + 2, taa, &a, CVEC(at_i->x), CVEC(at_j->x), &iout);
							xin[idx + j + 30] = iout.x * t1;
							yin[idx + j + 30] = iout.y * t1;
							zin[idx + j + 30] = iout.z * t1;

							if (j >= 2) {
								make_int(i, j - 2, taa, &a, CVEC(at_i->x), CVEC(at_j->x), &iout);
								double t3 = j * (j - 1) * t2;
								xin[idx + j + 60] = iout.x * t3;
								yin[idx + j + 60] = iout.y * t3;
								zin[idx + j + 60] = iout.z * t3;
							}
							else {
								xin[idx + j + 60] = 0.0;
								yin[idx + j + 60] = 0.0;
								zin[idx + j + 60] = 0.0;
							}
						}
					}
					for (size_t i = 0; i < count; i++) {
						size_t nx = shift_x[i];
						size_t ny = shift_y[i];
						size_t nz = shift_z[i];
						double xyz = xin[nx] * yin[ny] * zin[nz];
						double add = (xin[nx + 30] + xin[nx + 60]) * yin[ny] * zin[nz] +
							     (yin[ny + 30] + yin[ny + 60]) * xin[nx] * zin[nz] +
							     (zin[nz + 30] + zin[nz + 60]) * xin[nx] * yin[ny];
						sblk[i] = sblk[i] + dij[i] * xyz;
						tblk[i] = tblk[i] + dij[i] * (xyz * aj * ft[i] + add);
					}
				}
			}

			/* store integrals */
			for (size_t i = 0, idx = 0; i < count_i; i++) {
				size_t idx2 = (loc_i + i) * stride + loc_j;

				for (size_t j = 0; j < count_j; j++, idx++, idx2++) {
					s[idx2] = sblk[idx];
					t[idx2] = tblk[idx];
				}
			}
			loc_j += count_j;
		}}
		loc_i += count_i;
	}}
}
示例#15
0
文件: pol.c 项目: SahanGH/psi4public
static void
compute_grad_point(struct efp *efp, size_t frag_idx, size_t pt_idx)
{
	const struct frag *fr_i = efp->frags + frag_idx;
	const struct polarizable_pt *pt_i = fr_i->polarizable_pts + pt_idx;
	size_t idx_i = fr_i->polarizable_offset + pt_idx;

	vec_t dipole_i = {
		0.5 * (efp->indip[idx_i].x + efp->indipconj[idx_i].x),
		0.5 * (efp->indip[idx_i].y + efp->indipconj[idx_i].y),
		0.5 * (efp->indip[idx_i].z + efp->indipconj[idx_i].z)
	};

	for (size_t j = 0; j < efp->n_frag; j++) {
		if (j == frag_idx || efp_skip_frag_pair(efp, frag_idx, j))
			continue;

		struct frag *fr_j = efp->frags + j;
		struct swf swf = efp_make_swf(efp, fr_i, fr_j);

		/* energy without switching applied */
		double energy = 0.0;

		/* induced dipole - nuclei */
		for (size_t k = 0; k < fr_j->n_atoms; k++) {
			struct efp_atom *at_j = fr_j->atoms + k;

			vec_t dr = {
				at_j->x - pt_i->x - swf.cell.x,
				at_j->y - pt_i->y - swf.cell.y,
				at_j->z - pt_i->z - swf.cell.z
			};

			double p1 = 1.0, p2 = 0.0;

			if (efp->opts.pol_damp == EFP_POL_DAMP_TT) {
				double r = vec_len(&dr);

				p1 = efp_get_pol_damp_tt(r, fr_i->pol_damp,
						fr_j->pol_damp);
				p2 = efp_get_pol_damp_tt_grad(r, fr_i->pol_damp,
						fr_j->pol_damp);
			}

			vec_t force, add_i, add_j;

			double e = -efp_charge_dipole_energy(at_j->znuc, &dipole_i, &dr);

			efp_charge_dipole_grad(at_j->znuc, &dipole_i, &dr,
					       &force, &add_j, &add_i);
			vec_negate(&force);

			vec_scale(&force, p1);
			vec_scale(&add_i, p1);
			vec_scale(&add_j, p1);

			force.x += p2 * e * dr.x;
			force.y += p2 * e * dr.y;
			force.z += p2 * e * dr.z;

			vec_scale(&force, swf.swf);
			vec_scale(&add_i, swf.swf);
			vec_scale(&add_j, swf.swf);

			efp_add_force(efp->grad + frag_idx, CVEC(fr_i->x),
					CVEC(pt_i->x), &force, &add_i);
			efp_sub_force(efp->grad + j, CVEC(fr_j->x),
					CVEC(at_j->x), &force, &add_j);
			efp_add_stress(&swf.dr, &force, &efp->stress);

			energy += p1 * e;
		}

		/* induced dipole - multipoles */
		for (size_t k = 0; k < fr_j->n_multipole_pts; k++) {
			struct multipole_pt *pt_j = fr_j->multipole_pts + k;

			vec_t dr = {
				pt_j->x - pt_i->x - swf.cell.x,
				pt_j->y - pt_i->y - swf.cell.y,
				pt_j->z - pt_i->z - swf.cell.z
			};

			double p1 = 1.0, p2 = 0.0;

			if (efp->opts.pol_damp == EFP_POL_DAMP_TT) {
				double r = vec_len(&dr);

				p1 = efp_get_pol_damp_tt(r, fr_i->pol_damp,
						fr_j->pol_damp);
				p2 = efp_get_pol_damp_tt_grad(r, fr_i->pol_damp,
						fr_j->pol_damp);
			}

			double e = 0.0;

			vec_t force_, add_i_, add_j_;
			vec_t force = vec_zero, add_i = vec_zero, add_j = vec_zero;

			/* induced dipole - charge */
			e -= efp_charge_dipole_energy(pt_j->monopole, &dipole_i, &dr);

			efp_charge_dipole_grad(pt_j->monopole, &dipole_i, &dr,
					       &force_, &add_j_, &add_i_);
			vec_negate(&force_);
			add_3(&force, &force_, &add_i, &add_i_, &add_j, &add_j_);

			/* induced dipole - dipole */
			e += efp_dipole_dipole_energy(&dipole_i, &pt_j->dipole, &dr);

			efp_dipole_dipole_grad(&dipole_i, &pt_j->dipole, &dr,
					       &force_, &add_i_, &add_j_);
			vec_negate(&add_j_);
			add_3(&force, &force_, &add_i, &add_i_, &add_j, &add_j_);

			/* induced dipole - quadrupole */
			e += efp_dipole_quadrupole_energy(&dipole_i, pt_j->quadrupole, &dr);

			efp_dipole_quadrupole_grad(&dipole_i, pt_j->quadrupole, &dr,
						   &force_, &add_i_, &add_j_);
			add_3(&force, &force_, &add_i, &add_i_, &add_j, &add_j_);

			/* induced dipole - octupole interactions are ignored */

			vec_scale(&force, p1);
			vec_scale(&add_i, p1);
			vec_scale(&add_j, p1);

			force.x += p2 * e * dr.x;
			force.y += p2 * e * dr.y;
			force.z += p2 * e * dr.z;

			vec_scale(&force, swf.swf);
			vec_scale(&add_i, swf.swf);
			vec_scale(&add_j, swf.swf);

			efp_add_force(efp->grad + frag_idx, CVEC(fr_i->x),
					CVEC(pt_i->x), &force, &add_i);
			efp_sub_force(efp->grad + j, CVEC(fr_j->x),
					CVEC(pt_j->x), &force, &add_j);
			efp_add_stress(&swf.dr, &force, &efp->stress);

			energy += p1 * e;
		}

		/* induced dipole - induced dipoles */
		for (size_t jj = 0; jj < fr_j->n_polarizable_pts; jj++) {
			struct polarizable_pt *pt_j = fr_j->polarizable_pts + jj;
			size_t idx_j = fr_j->polarizable_offset + jj;

			vec_t dr = {
				pt_j->x - pt_i->x - swf.cell.x,
				pt_j->y - pt_i->y - swf.cell.y,
				pt_j->z - pt_i->z - swf.cell.z
			};

			vec_t half_dipole_i = {
				0.5 * efp->indip[idx_i].x,
				0.5 * efp->indip[idx_i].y,
				0.5 * efp->indip[idx_i].z
			};

			double p1 = 1.0, p2 = 0.0;

			if (efp->opts.pol_damp == EFP_POL_DAMP_TT) {
				double r = vec_len(&dr);

				p1 = efp_get_pol_damp_tt(r, fr_i->pol_damp,
						fr_j->pol_damp);
				p2 = efp_get_pol_damp_tt_grad(r, fr_i->pol_damp,
						fr_j->pol_damp);
			}

			vec_t force, add_i, add_j;

			double e = efp_dipole_dipole_energy(&half_dipole_i,
						&efp->indipconj[idx_j], &dr);

			efp_dipole_dipole_grad(&half_dipole_i, &efp->indipconj[idx_j],
						&dr, &force, &add_i, &add_j);
			vec_negate(&add_j);

			vec_scale(&force, p1);
			vec_scale(&add_i, p1);
			vec_scale(&add_j, p1);

			force.x += p2 * e * dr.x;
			force.y += p2 * e * dr.y;
			force.z += p2 * e * dr.z;

			vec_scale(&force, swf.swf);
			vec_scale(&add_i, swf.swf);
			vec_scale(&add_j, swf.swf);

			efp_add_force(efp->grad + frag_idx, CVEC(fr_i->x),
					CVEC(pt_i->x), &force, &add_i);
			efp_sub_force(efp->grad + j, CVEC(fr_j->x),
					CVEC(pt_j->x), &force, &add_j);
			efp_add_stress(&swf.dr, &force, &efp->stress);

			energy += p1 * e;
		}

		vec_t force = {
			swf.dswf.x * energy,
			swf.dswf.y * energy,
			swf.dswf.z * energy
		};

		six_atomic_add_xyz(efp->grad + frag_idx, &force);
		six_atomic_sub_xyz(efp->grad + j, &force);
		efp_add_stress(&swf.dr, &force, &efp->stress);
	}

	/* induced dipole - ab initio nuclei */
	if (efp->opts.terms & EFP_TERM_AI_POL) {
		for (size_t j = 0; j < efp->n_ptc; j++) {
			vec_t dr = vec_sub(efp->ptc_xyz + j, CVEC(pt_i->x));
			vec_t force, add_i, add_j;

			efp_charge_dipole_grad(efp->ptc[j], &dipole_i, &dr,
					       &force, &add_j, &add_i);
			vec_negate(&add_i);

			vec_atomic_add(efp->ptc_grad + j, &force);
			efp_sub_force(efp->grad + frag_idx, CVEC(fr_i->x),
					CVEC(pt_i->x), &force, &add_i);
		}
	}
}
示例#16
0
文件: pol.c 项目: SahanGH/psi4public
static vec_t
get_elec_field(const struct efp *efp, size_t frag_idx, size_t pt_idx)
{
	const struct frag *fr_j = efp->frags + frag_idx;
	const struct polarizable_pt *pt = fr_j->polarizable_pts + pt_idx;
	vec_t elec_field = vec_zero;

	for (size_t i = 0; i < efp->n_frag; i++) {
		if (i == frag_idx || efp_skip_frag_pair(efp, i, frag_idx))
			continue;

		const struct frag *fr_i = efp->frags + i;
		struct swf swf = efp_make_swf(efp, fr_i, fr_j);

		/* field due to nuclei */
		for (size_t j = 0; j < fr_i->n_atoms; j++) {
			const struct efp_atom *at = fr_i->atoms + j;

			vec_t dr = {
				pt->x - at->x - swf.cell.x,
				pt->y - at->y - swf.cell.y,
				pt->z - at->z - swf.cell.z
			};

			double r = vec_len(&dr);
			double r3 = r * r * r;
			double p1 = 1.0;

			if (efp->opts.pol_damp == EFP_POL_DAMP_TT)
				p1 = efp_get_pol_damp_tt(r, fr_i->pol_damp, fr_j->pol_damp);

			elec_field.x += swf.swf * at->znuc * dr.x / r3 * p1;
			elec_field.y += swf.swf * at->znuc * dr.y / r3 * p1;
			elec_field.z += swf.swf * at->znuc * dr.z / r3 * p1;
		}

		/* field due to multipoles */
		for (size_t j = 0; j < fr_i->n_multipole_pts; j++) {
			const struct multipole_pt *mult_pt = fr_i->multipole_pts + j;
			vec_t mult_field = get_multipole_field(CVEC(pt->x), mult_pt, &swf);

			vec_t dr = {
				pt->x - mult_pt->x - swf.cell.x,
				pt->y - mult_pt->y - swf.cell.y,
				pt->z - mult_pt->z - swf.cell.z
			};

			double r = vec_len(&dr);
			double p1 = 1.0;

			if (efp->opts.pol_damp == EFP_POL_DAMP_TT)
				p1 = efp_get_pol_damp_tt(r, fr_i->pol_damp, fr_j->pol_damp);

			elec_field.x += mult_field.x * p1;
			elec_field.y += mult_field.y * p1;
			elec_field.z += mult_field.z * p1;
		}
	}

	if (efp->opts.terms & EFP_TERM_AI_POL) {
		/* field due to nuclei from ab initio subsystem */
		for (size_t i = 0; i < efp->n_ptc; i++) {
			vec_t dr = vec_sub(CVEC(pt->x), efp->ptc_xyz + i);

			double r = vec_len(&dr);
			double r3 = r * r * r;

			elec_field.x += efp->ptc[i] * dr.x / r3;
			elec_field.y += efp->ptc[i] * dr.y / r3;
			elec_field.z += efp->ptc[i] * dr.z / r3;
		}
	}

	return (elec_field);
}
示例#17
0
static bool _convert(CVECTOR *_object, GB_TYPE type, GB_VALUE *conv)
{
	if (THIS)
	{
		if (!COMPLEX(THIS))
		{
			switch (type)
			{
				case GB_T_FLOAT:
					conv->_float.value = gsl_blas_dnrm2(VEC(THIS));
					return FALSE;
					
				case GB_T_SINGLE:
					conv->_single.value = gsl_blas_dnrm2(VEC(THIS));
					return FALSE;
					
				case GB_T_INTEGER:
				case GB_T_SHORT:
				case GB_T_BYTE:
					conv->_integer.value = gsl_blas_dnrm2(VEC(THIS));
					return FALSE;
					
				case GB_T_LONG:
					conv->_long.value = gsl_blas_dnrm2(VEC(THIS));
					return FALSE;
					
				case GB_T_STRING:
				case GB_T_CSTRING:
					conv->_string.value.addr = _to_string(THIS, type == GB_T_CSTRING);
					conv->_string.value.start = 0;
					conv->_string.value.len = GB.StringLength(conv->_string.value.addr);
					return FALSE;
					
				default:
					break;
			}
		}
		else
		{
			switch (type)
			{
				case GB_T_FLOAT:
					conv->_float.value = gsl_blas_dznrm2(CVEC(THIS));
					return FALSE;
					
				case GB_T_SINGLE:
					conv->_single.value = gsl_blas_dznrm2(CVEC(THIS));
					return FALSE;
					
				case GB_T_INTEGER:
				case GB_T_SHORT:
				case GB_T_BYTE:
					conv->_integer.value = gsl_blas_dznrm2(CVEC(THIS));
					return FALSE;
					
				case GB_T_LONG:
					conv->_long.value = gsl_blas_dznrm2(CVEC(THIS));
					return FALSE;
					
				case GB_T_STRING:
				case GB_T_CSTRING:
					conv->_string.value.addr = _to_string(THIS, type == GB_T_CSTRING);
					conv->_string.value.start = 0;
					conv->_string.value.len = GB.StringLength(conv->_string.value.addr);
					return FALSE;
					
				default:
					break;
			}
		}
		
		// Vector ---> Float[]
		if ((type == GB.FindClass("Float[]") || type == CLASS_Polynomial) && !COMPLEX(THIS))
		{
			GB_ARRAY a;
			int i;
			double *data;
			
			GB.Array.New(&a, GB_T_FLOAT, SIZE(THIS));
			data = (double *)GB.Array.Get(a, 0);
			for(i = 0; i < SIZE(THIS); i++)
				data[i] = gsl_vector_get(VEC(THIS), i);
			
			conv->_object.value = a;
			if (type != CLASS_Polynomial)
				return FALSE;
		}
		// Vector ---> Complex[]
		else if (type == GB.FindClass("Complex[]") || type == CLASS_Polynomial)
		{
			GB_ARRAY a;
			int i;
			void **data;
			CCOMPLEX *c;
			
			GB.Array.New(&a, CLASS_Complex, SIZE(THIS));
			data = (void **)GB.Array.Get(a, 0);
			for(i = 0; i < SIZE(THIS); i++)
			{
				c = COMPLEX_create(COMPLEX(THIS) ? gsl_vector_complex_get(CVEC(THIS), i) : gsl_complex_rect(gsl_vector_get(VEC(THIS), i), 0));
				data[i] = c;
				GB.Ref(c);
			}
			
			conv->_object.value = a;
			if (type != CLASS_Polynomial)
				return FALSE;
		}
		else
			return TRUE;
		
		// Vector ---> Polynomial
		if (type == CLASS_Polynomial)
		{
			void *unref = conv->_object.value;
			GB.Ref(unref); // Will be unref by the next GB.Conv()
			POLYNOMIAL_convert(FALSE, type, conv);
			GB.Unref(&unref); // Will be unref by the next GB.Conv()
			//GB.Conv(conv, type);
			//GB.UnrefKeep(&conv->_object.value, FALSE); // Will be ref again after the current GB.Conv()
			return FALSE;
		}
		
	}
	else if (type >= GB_T_OBJECT)
	{
		if (GB.Is(conv->_object.value, CLASS_Array))
		{
			GB_ARRAY array = (GB_ARRAY)conv->_object.value;
			int size = GB.Array.Count(array);
			CVECTOR *v;
			int i;
			GB_VALUE temp;
			void *data;
			GB_TYPE atype = GB.Array.Type(array);
			
			// Float[] Integer[] ... ---> Vector
			if (atype > GB_T_BOOLEAN && atype <= GB_T_FLOAT)
			{
				v = VECTOR_create(size, FALSE, FALSE);
				
				for (i = 0; i < size; i++)
				{
					data = GB.Array.Get(array, i);
					GB.ReadValue(&temp, data, atype);
					GB.Conv(&temp, GB_T_FLOAT);
					gsl_vector_set(VEC(v), i, temp._float.value);
				}
				
				conv->_object.value = v;
				return FALSE;
			}
			// Variant[] ---> Vector
			else if (atype == GB_T_VARIANT)
			{
				CCOMPLEX *c;
				v = VECTOR_create(size, TRUE, FALSE);
				
				for (i = 0; i < size; i++)
				{
					GB.ReadValue(&temp, GB.Array.Get(array, i), atype);
					GB.BorrowValue(&temp);
					GB.Conv(&temp, CLASS_Complex);
					c = temp._object.value;
					if (c)
						gsl_vector_complex_set(CVEC(v), i, c->number);
					else
						gsl_vector_complex_set(CVEC(v), i, COMPLEX_zero);
					GB.ReleaseValue(&temp);
				}
				
				conv->_object.value = v;
				return FALSE;
			}
			// Complex[] ---> Vector
			else if (atype == CLASS_Complex)
			{
				CCOMPLEX *c;
				v = VECTOR_create(size, TRUE, FALSE);
				
				for (i = 0; i < size; i++)
				{
					c = *((CCOMPLEX **)GB.Array.Get(array, i));
					if (c)
						gsl_vector_complex_set(CVEC(v), i, c->number);
					else
						gsl_vector_complex_set(CVEC(v), i, COMPLEX_zero);
				}
				
				conv->_object.value = v;
				return FALSE;
			}
		}
		// Float Integer... ---> Vector
		else if (type > GB_T_BOOLEAN && type <= GB_T_FLOAT)
		{
			CVECTOR *v = VECTOR_create(1, FALSE, FALSE);
			if (type == GB_T_FLOAT)
				gsl_vector_set(VEC(v), 0, conv->_float.value);
			else if (type == GB_T_SINGLE)
				gsl_vector_set(VEC(v), 0, conv->_single.value);
			else
				gsl_vector_set(VEC(v), 0, conv->_integer.value);
			conv->_object.value = v;
			return FALSE;
		}
		// Complex ---> Vector
		else if (type == CLASS_Complex)
		{
			CCOMPLEX *c = (CCOMPLEX *)conv->_object.value;
			CVECTOR *v = VECTOR_create(1, TRUE, FALSE);
			gsl_vector_complex_set(CVEC(v), 0, c->number);
			conv->_object.value = v;
			return FALSE;
		}
	}
	
	return TRUE;
}
示例#18
0
void efp_st_int_deriv(size_t n_atoms_i, const struct xr_atom *atoms_i,
		      size_t n_atoms_j, const struct xr_atom *atoms_j,
		      const vec_t *com_i, size_t size_i, size_t size_j,
		      six_t *ds, six_t *dt)
{
	static const size_t shift_x[] = { 0, 1, 0, 0, 2, 0, 0, 1, 1, 0,
					  3, 0, 0, 2, 2, 1, 0, 1, 0, 1 };

	static const size_t shift_y[] = { 0, 0, 1, 0, 0, 2, 0, 1, 0, 1,
					  0, 3, 0, 1, 0, 2, 2, 0, 1, 1 };

	static const size_t shift_z[] = { 0, 0, 0, 1, 0, 0, 2, 0, 1, 1,
					  0, 0, 3, 0, 1, 0, 1, 2, 2, 1 };

	double dij[100];
	double xs[5][6], ys[5][6], zs[5][6];
	double xt[5][4], yt[5][4], zt[5][4];
	double dxs[4][4], dys[4][4], dzs[4][4];
	double dxt[4][4], dyt[4][4], dzt[4][4];

	memset(ds, 0, size_i * size_j * sizeof(six_t));
	memset(dt, 0, size_i * size_j * sizeof(six_t));

	for (size_t iii = 0, loc_i = 0; iii < n_atoms_i; iii++) {
		const struct xr_atom *at_i = atoms_i + iii;

	/* shell i */
	for (size_t ii = 0; ii < at_i->n_shells; ii++) {
		const struct shell *sh_i = at_i->shells + ii;

		size_t type_i = get_shell_idx(sh_i->type);
		size_t start_i = get_shell_start(type_i);
		size_t end_i = get_shell_end(type_i);
		size_t sl_i = get_shell_sl(type_i);
		size_t count_i = end_i - start_i;

		for (size_t jjj = 0, loc_j = 0; jjj < n_atoms_j; jjj++) {
			const struct xr_atom *at_j = atoms_j + jjj;

		/* shell j */
		for (size_t jj = 0; jj < at_j->n_shells; jj++) {
			const struct shell *sh_j = at_j->shells + jj;

			size_t type_j = get_shell_idx(sh_j->type);
			size_t start_j = get_shell_start(type_j);
			size_t end_j = get_shell_end(type_j);
			size_t sl_j = get_shell_sl(type_j);
			size_t count_j = end_j - start_j;

			double rr = vec_dist_2(CVEC(at_i->x), CVEC(at_j->x));

			const double *coef_i = sh_i->coef;

			/* primitive i */
			for (size_t ig = 0; ig < sh_i->n_funcs; ig++) {
				double ai = *coef_i++;

				double con_i[20];
				set_coef(con_i, sh_i->type, coef_i);

				coef_i++;
				if (sh_i->type == 'L')
					coef_i++;

				const double *coef_j = sh_j->coef;

				/* primitive j */
				for (size_t jg = 0; jg < sh_j->n_funcs; jg++) {
					double aj = *coef_j++;

					double aa = 1.0 / (ai + aj);
					double tmp = ai * aj * rr * aa;

					if (tmp > int_tol) {
						coef_j++;
						if (sh_j->type == 'L')
							coef_j++;

						continue;
					}

					double con_j[20];
					set_coef(con_j, sh_j->type, coef_j);

					coef_j++;
					if (sh_j->type == 'L')
						coef_j++;

					double fac = exp(-tmp);

					for (size_t i = start_i, idx = 0; i < end_i; i++)
						for (size_t j = start_j; j < end_j; j++, idx++)
							dij[idx] = fac * con_i[i] * int_norm[i] * con_j[j] * int_norm[j];

					double taa = sqrt(aa);

					vec_t a = {
						(ai * at_i->x + aj * at_j->x) * aa,
						(ai * at_i->y + aj * at_j->y) * aa,
						(ai * at_i->z + aj * at_j->z) * aa
					};

					for (size_t i = 0; i < sl_i + 1; i++) {
						for (size_t j = 0; j < sl_j + 2; j++) {
							vec_t iout;
							make_int(i, j, taa, &a, CVEC(at_i->x), CVEC(at_j->x), &iout);
							xs[i][j] = iout.x * taa;
							ys[i][j] = iout.y * taa;
							zs[i][j] = iout.z * taa;
						}
					}

					double ai2 = 2.0 * ai;
					double aj2 = 2.0 * aj;

					for (size_t i = 0; i < sl_i + 1; i++) {
						xt[i][0] = (xs[i][0] - xs[i][2] * aj2) * aj;
						yt[i][0] = (ys[i][0] - ys[i][2] * aj2) * aj;
						zt[i][0] = (zs[i][0] - zs[i][2] * aj2) * aj;
					}

					if (sl_j > 1) {
						for (size_t i = 0; i < sl_i + 1; i++) {
							xt[i][1] = (xs[i][1] * 3.0 - xs[i][3] * aj2) * aj;
							yt[i][1] = (ys[i][1] * 3.0 - ys[i][3] * aj2) * aj;
							zt[i][1] = (zs[i][1] * 3.0 - zs[i][3] * aj2) * aj;
						}

						for (size_t j = 2; j < sl_j; j++) {
							for (size_t i = 0; i < sl_i + 1; i++) {
								size_t n1 = 2 * j + 1;
								size_t n2 = j * (j - 1) / 2;
								xt[i][j] = (xs[i][j] * n1 - xs[i][j + 2] * aj2) * aj - xs[i][j - 2] * n2;
								yt[i][j] = (ys[i][j] * n1 - ys[i][j + 2] * aj2) * aj - ys[i][j - 2] * n2;
								zt[i][j] = (zs[i][j] * n1 - zs[i][j + 2] * aj2) * aj - zs[i][j - 2] * n2;
							}
						}
					}

					for (size_t j = 0; j < sl_j; j++) {
						dxs[0][j] = xs[1][j] * ai2;
						dys[0][j] = ys[1][j] * ai2;
						dzs[0][j] = zs[1][j] * ai2;

						dxt[0][j] = xt[1][j] * ai2;
						dyt[0][j] = yt[1][j] * ai2;
						dzt[0][j] = zt[1][j] * ai2;
					}

					for (size_t i = 1; i < sl_i; i++) {
						for (size_t j = 0; j < sl_j; j++) {
							dxs[i][j] = xs[i + 1][j] * ai2 - xs[i - 1][j] * i;
							dys[i][j] = ys[i + 1][j] * ai2 - ys[i - 1][j] * i;
							dzs[i][j] = zs[i + 1][j] * ai2 - zs[i - 1][j] * i;

							dxt[i][j] = xt[i + 1][j] * ai2 - xt[i - 1][j] * i;
							dyt[i][j] = yt[i + 1][j] * ai2 - yt[i - 1][j] * i;
							dzt[i][j] = zt[i + 1][j] * ai2 - zt[i - 1][j] * i;
						}
					}

					for (size_t i = start_i, idx = 0; i < end_i; i++) {
						size_t ix = shift_x[i];
						size_t iy = shift_y[i];
						size_t iz = shift_z[i];

						for (size_t j = start_j; j < end_j; j++, idx++) {
							size_t jx = shift_x[j];
							size_t jy = shift_y[j];
							size_t jz = shift_z[j];

							double txs = dxs[ix][jx] * ys[iy][jy] * zs[iz][jz];
							double tys = xs[ix][jx] * dys[iy][jy] * zs[iz][jz];
							double tzs = xs[ix][jx] * ys[iy][jy] * dzs[iz][jz];

							double txt = dxt[ix][jx] * ys[iy][jy] * zs[iz][jz] +
								     dxs[ix][jx] * yt[iy][jy] * zs[iz][jz] +
								     dxs[ix][jx] * ys[iy][jy] * zt[iz][jz];
							double tyt = xt[ix][jx] * dys[iy][jy] * zs[iz][jz] +
								     xs[ix][jx] * dyt[iy][jy] * zs[iz][jz] +
								     xs[ix][jx] * dys[iy][jy] * zt[iz][jz];
							double tzt = xt[ix][jx] * ys[iy][jy] * dzs[iz][jz] +
								     xs[ix][jx] * yt[iy][jy] * dzs[iz][jz] +
								     xs[ix][jx] * ys[iy][jy] * dzt[iz][jz];

							size_t idx2 = (loc_i + i - start_i) * size_j + (loc_j + j - start_j);

							ds[idx2].x += txs * dij[idx];
							ds[idx2].y += tys * dij[idx];
							ds[idx2].z += tzs * dij[idx];
							ds[idx2].a += (tys * (at_i->z - com_i->z) - tzs * (at_i->y - com_i->y)) * dij[idx];
							ds[idx2].b += (tzs * (at_i->x - com_i->x) - txs * (at_i->z - com_i->z)) * dij[idx];
							ds[idx2].c += (txs * (at_i->y - com_i->y) - tys * (at_i->x - com_i->x)) * dij[idx];

							dt[idx2].x += txt * dij[idx];
							dt[idx2].y += tyt * dij[idx];
							dt[idx2].z += tzt * dij[idx];
							dt[idx2].a += (tyt * (at_i->z - com_i->z) - tzt * (at_i->y - com_i->y)) * dij[idx];
							dt[idx2].b += (tzt * (at_i->x - com_i->x) - txt * (at_i->z - com_i->z)) * dij[idx];
							dt[idx2].c += (txt * (at_i->y - com_i->y) - tyt * (at_i->x - com_i->x)) * dij[idx];
						}
					}
				}
			}
			loc_j += count_j;
		}}
		loc_i += count_i;
	}}
}