Example #1
0
void
efp_charge_quadrupole_grad(double q1, const double *quad2, const vec_t *dr,
			   vec_t *force, vec_t *add1, vec_t *add2)
{
	double r = vec_len(dr);
	double r2 = r * r;
	double r5 = r2 * r2 * r;
	double r7 = r5 * r2;

	double t1x = q1 / r5 * -2.0 * (dr->x * quad2[quad_idx(0, 0)] +
				       dr->y * quad2[quad_idx(0, 1)] +
				       dr->z * quad2[quad_idx(0, 2)]);
	double t1y = q1 / r5 * -2.0 * (dr->x * quad2[quad_idx(1, 0)] +
				       dr->y * quad2[quad_idx(1, 1)] +
				       dr->z * quad2[quad_idx(1, 2)]);
	double t1z = q1 / r5 * -2.0 * (dr->x * quad2[quad_idx(2, 0)] +
				       dr->y * quad2[quad_idx(2, 1)] +
				       dr->z * quad2[quad_idx(2, 2)]);

	double g = 5.0 * q1 / r7 * quadrupole_sum(quad2, dr);

	force->x = g * dr->x + t1x;
	force->y = g * dr->y + t1y;
	force->z = g * dr->z + t1z;

	add1->x = 0.0;
	add1->y = 0.0;
	add1->z = 0.0;

	add2->x = t1z * dr->y - t1y * dr->z;
	add2->y = t1x * dr->z - t1z * dr->x;
	add2->z = t1y * dr->x - t1x * dr->y;
}
Example #2
0
double
efp_quadrupole_quadrupole_energy(const double *quad1, const double *quad2, const vec_t *dr)
{
	double r = vec_len(dr);
	double r2 = r * r;
	double r5 = r2 * r2 * r;
	double r7 = r5 * r2;
	double r9 = r7 * r2;

	double q1dr = quadrupole_sum(quad1, dr);
	double q2dr = quadrupole_sum(quad2, dr);

	double q1q2 = 0.0;
	double q1q2dr = 0.0;

	for (size_t a = 0; a < 3; a++) {
		double t1 = 0.0;
		double t2 = 0.0;

		for (size_t b = 0; b < 3; b++) {
			size_t idx = quad_idx(a, b);

			t1 += quad1[idx] * vec_get(dr, b);
			t2 += quad2[idx] * vec_get(dr, b);

			q1q2 += quad1[idx] * quad2[idx];
		}

		q1q2dr += t1 * t2;
	}

	return (2.0 / r5 * q1q2 - 20.0 / r7 * q1q2dr + 35.0 / r9 * q1dr * q2dr) / 3.0;
}
Example #3
0
static vec_t
get_multipole_field(const vec_t *xyz, const struct multipole_pt *mult_pt,
			const struct swf *swf)
{
	vec_t field = vec_zero;

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

	double t1, t2;
	double r = vec_len(&dr);
	double r3 = r * r * r;
	double r5 = r3 * r * r;
	double r7 = r5 * r * r;

	/* charge */
	field.x += swf->swf * mult_pt->monopole * dr.x / r3;
	field.y += swf->swf * mult_pt->monopole * dr.y / r3;
	field.z += swf->swf * mult_pt->monopole * dr.z / r3;

	/* dipole */
	t1 = vec_dot(&mult_pt->dipole, &dr);

	field.x += swf->swf * (3.0 / r5 * t1 * dr.x - mult_pt->dipole.x / r3);
	field.y += swf->swf * (3.0 / r5 * t1 * dr.y - mult_pt->dipole.y / r3);
	field.z += swf->swf * (3.0 / r5 * t1 * dr.z - mult_pt->dipole.z / r3);

	/* quadrupole */
	t1 = quadrupole_sum(mult_pt->quadrupole, &dr);

	t2 = mult_pt->quadrupole[quad_idx(0, 0)] * dr.x +
	     mult_pt->quadrupole[quad_idx(1, 0)] * dr.y +
	     mult_pt->quadrupole[quad_idx(2, 0)] * dr.z;
	field.x += swf->swf * (-2.0 / r5 * t2 + 5.0 / r7 * t1 * dr.x);

	t2 = mult_pt->quadrupole[quad_idx(0, 1)] * dr.x +
	     mult_pt->quadrupole[quad_idx(1, 1)] * dr.y +
	     mult_pt->quadrupole[quad_idx(2, 1)] * dr.z;
	field.y += swf->swf * (-2.0 / r5 * t2 + 5.0 / r7 * t1 * dr.y);

	t2 = mult_pt->quadrupole[quad_idx(0, 2)] * dr.x +
	     mult_pt->quadrupole[quad_idx(1, 2)] * dr.y +
	     mult_pt->quadrupole[quad_idx(2, 2)] * dr.z;
	field.z += swf->swf * (-2.0 / r5 * t2 + 5.0 / r7 * t1 * dr.z);

	/* octupole-polarizability interactions are ignored */

	return (field);
}
Example #4
0
double
efp_dipole_quadrupole_energy(const vec_t *d1, const double *quad2, const vec_t *dr)
{
	double r = vec_len(dr);
	double r2 = r * r;
	double r5 = r2 * r2 * r;
	double r7 = r5 * r2;

	double d1dr = vec_dot(d1, dr);
	double q2dr = quadrupole_sum(quad2, dr);
	double d1q2dr = 0.0;

	for (size_t a = 0; a < 3; a++)
		for (size_t b = 0; b < 3; b++) {
			size_t idx = quad_idx(a, b);
			d1q2dr += quad2[idx] * vec_get(d1, a) * vec_get(dr, b);
		}

	return 5.0 / r7 * q2dr * d1dr - 2.0 / r5 * d1q2dr;
}
Example #5
0
void DeformToFit::registerAndDeformNodes(Structure::Node * snode, Structure::Node * tnode)
{
    auto scenter = snode->position(Eigen::Vector4d(0.5, 0.5, 0, 0));
    auto tcenter = tnode->position(Eigen::Vector4d(0.5, 0.5, 0, 0));

    auto translation = Vector3(tcenter - scenter);

	if (snode->type() == tnode->type())
	{
		if (snode->type() == Structure::CURVE)
		{
			auto scpts = snode->controlPoints();
			auto tcpts = tnode->controlPoints();

			for (auto & p : tcpts) p -= translation;

			// Register
			Vector3 sfront = scpts.front();
			Vector3 tfront = tcpts.front();
			Vector3 tback = tcpts.back();
			bool isReverse = (sfront - tfront).norm() > (sfront - tback).norm() ? true : false;
			if (isReverse) std::reverse(tcpts.begin(), tcpts.end());

			// Encode target curve as deltas from center
			std::map < double, Vector3 > deltas;
			for (size_t i = 0; i < tcpts.size(); i++){
				double t = double(i) / (tcpts.size() - 1);
				deltas[t] = tcpts[i] - scenter;
			}

			// Deform source curve from deltas
			for (size_t i = 0; i < scpts.size(); i++){
				double t = double(i) / (scpts.size() - 1);
				scpts[i] = (scenter + translation) + linear_interpolate<Vector3>(t, deltas);
			}

			// Apply deformed control points
			snode->setControlPoints(scpts);
		}

		if (snode->type() == Structure::SHEET)
		{
			Structure::Sheet * ssheet = (Structure::Sheet*) snode;
			Structure::Sheet * tsheet = (Structure::Sheet*) tnode;

			auto ssurface = ssheet->surface;
			auto tsurface = tsheet->surface;

			// Remove translation
			tsurface.translate(-translation);
			
			// Minimize rotation
			Vector3 tpos, tu, tv, tnormal;
			tsurface.GetFrame(0.5, 0.5, tpos, tu, tv, tnormal);
			Vector3 spos, su, sv, snormal;
			ssurface.GetFrame(0.5, 0.5, spos, su, sv, snormal);

			if (snormal.dot(tnormal) < 0) 
				tnormal *= -1;

			Eigen::Quaterniond q = Eigen::Quaterniond::FromTwoVectors(snormal, tnormal);
			for (auto & row : tsurface.mCtrlPoint) for (auto & p : row) p = (q.inverse() * (p - scenter)) + scenter;

			QMap < double, QVector<double> > dists;
			for (double u = 0; u <= 1.0; u += 1.0){
				for (double v = 0; v <= 1.0; v += 1.0){
					for (double i = 0; i <= 1.0; i += 1.0){
						for (double j = 0; j <= 1.0; j += 1.0){
							dists[(ssurface.P(u, v) - tsurface.P(i, j)).norm()] = (QVector<double>() << u << v << i << j);
						}
					}
				}
			}

			auto bestChoice = dists.values().front();
			bool isReverseU = bestChoice[0] != bestChoice[2], isReverseV = bestChoice[1] != bestChoice[3];

			// Reverse if needed
			if ( isReverseV ){
				for (int i = 0; i < (int)tsurface.mCtrlPoint.size(); i++){
					std::reverse(tsurface.mCtrlPoint[i].begin(), tsurface.mCtrlPoint[i].end());
					std::reverse(tsurface.mCtrlWeight[i].begin(), tsurface.mCtrlWeight[i].end());
				}
			}
			if( isReverseU ){
				std::reverse(tsurface.mCtrlPoint.begin(), tsurface.mCtrlPoint.end());
				std::reverse(tsurface.mCtrlWeight.begin(), tsurface.mCtrlWeight.end());
			}

			std::map < double, size_t > mapU, mapV;
			for (size_t i = 0; i < tsurface.mNumUCtrlPoints; i++) mapU[double(i) / (tsurface.mNumUCtrlPoints - 1)] = i;
			for (size_t j = 0; j < tsurface.mNumVCtrlPoints; j++) mapV[double(j) / (tsurface.mNumVCtrlPoints - 1)] = j;

			auto getQuad = [&](size_t u, size_t v, Array2D_Vector3& cpts){ 
				return QVector<Vector3>() << cpts[u][v] << cpts[u+1][v] << cpts[u][v+1] << cpts[u+1][v+1];
			};

			for (size_t i = 0; i < ssurface.mNumUCtrlPoints; i++){
				for (size_t j = 0; j < ssurface.mNumVCtrlPoints; j++){
					double u = double(i) / (ssurface.mNumUCtrlPoints-1);
					double v = double(j) / (ssurface.mNumVCtrlPoints-1);

					auto weight_u = linear_interpolate_weight<size_t>(u, mapU);
					auto weight_v = linear_interpolate_weight<size_t>(v, mapV);

					std::pair <size_t, size_t> quad_idx(std::get<0>(weight_u), std::get<0>(weight_v));
					std::pair <double, double> quad_uv(std::get<2>(weight_u), std::get<2>(weight_v));

					auto quad = getQuad(quad_idx.first, quad_idx.second, tsurface.mCtrlPoint);

					auto interp = quad_interpolate(quad[0], quad[1], quad[2], quad[3], quad_uv.first, quad_uv.second);

					ssurface.mCtrlPoint[i][j] = interp;
				}
			}

			// Apply rotation
			for (auto & row : ssurface.mCtrlPoint) for (auto & p : row) p = (q * (p - scenter)) + tcenter;

			ssheet->surface.mCtrlPoint = ssurface.mCtrlPoint;
			ssheet->surface.quads.clear();
        }
    }
    else
    {
		Structure::Curve curve((snode->type() == Structure::CURVE) ? (*(Structure::Curve*)snode) : (*(Structure::Curve*)tnode));
		Structure::Sheet sheet((snode->type() == Structure::SHEET) ? (*(Structure::Sheet*)snode) : (*(Structure::Sheet*)tnode));

		double minU = std::min((sheet.surface.P(0, 0) - sheet.surface.P(1, 0)).norm(), (sheet.surface.P(0, 1) - sheet.surface.P(1, 1)).norm());
		double minV = std::min((sheet.surface.P(0, 0) - sheet.surface.P(0, 1)).norm(), (sheet.surface.P(1, 0) - sheet.surface.P(1, 1)).norm());
		bool isProjectAlongU = minU < minV;

		// Roll up sheet
		int idx = (isProjectAlongU) ? (sheet.surface.mNumUCtrlPoints - 1) * 0.5 : (sheet.surface.mNumVCtrlPoints - 1) * 0.5;
		Array1D_Vector3 projection = (isProjectAlongU) ? sheet.surface.GetControlPointsV(idx) : sheet.surface.GetControlPointsU(idx);
		Array2D_Vector3 ctrlPnts(sheet.surface.mNumUCtrlPoints);
		if (isProjectAlongU){
			ctrlPnts = Array2D_Vector3(sheet.surface.mNumUCtrlPoints, projection);
		}else{
			for (size_t i = 0; i < sheet.surface.mNumUCtrlPoints; i++)
				ctrlPnts[i] = Array1D_Vector3(sheet.surface.mNumVCtrlPoints, projection[i]);
		}
		sheet.surface.mCtrlPoint = ctrlPnts;

		Structure::Curve curveFromSheet(NURBS::NURBSCurved::createCurveFromPoints(isProjectAlongU ?
			sheet.surface.GetControlPointsV(0) : sheet.surface.GetControlPointsU(0)), "temp");

		// Sheet to curve case:
		if (snode->type() == Structure::SHEET)
		{
			DeformToFit::registerAndDeformNodes(&curveFromSheet, &curve);

			if (isProjectAlongU)
				sheet.surface.mCtrlPoint = Array2D_Vector3(sheet.surface.mNumUCtrlPoints, curveFromSheet.curve.mCtrlPoint);
			else{
				for (size_t i = 0; i < sheet.surface.mNumUCtrlPoints; i++)
					sheet.surface.mCtrlPoint[i] = Array1D_Vector3(sheet.surface.mNumVCtrlPoints, curveFromSheet.curve.mCtrlPoint[i]);
			}

			((Structure::Sheet*)snode)->surface.mCtrlPoint = sheet.surface.mCtrlPoint;
		}

		// Curve to sheet case:
		if (snode->type() == Structure::CURVE)
		{
			DeformToFit::registerAndDeformNodes(snode, &curveFromSheet);
		}
    }
}
Example #6
0
void
efp_quadrupole_quadrupole_grad(const double *quad1, const double *quad2,
			       const vec_t *dr, vec_t *force, vec_t *add1,
			       vec_t *add2)
{
	double r = vec_len(dr);
	double r2 = r * r;
	double r5 = r2 * r2 * r;
	double r7 = r5 * r2;
	double r9 = r7 * r2;
	double r11 = r9 * r2;

	double q1ss = quadrupole_sum(quad1, dr);
	double q2ss = quadrupole_sum(quad2, dr);

	double q1s[3] = { 0.0, 0.0, 0.0 };
	double q2s[3] = { 0.0, 0.0, 0.0 };

	double q1sq2s = 0.0;

	for (size_t a = 0; a < 3; a++) {
		for (size_t b = 0; b < 3; b++) {
			q1s[a] += quad1[quad_idx(a, b)] * vec_get(dr, b);
			q2s[a] += quad2[quad_idx(a, b)] * vec_get(dr, b);
		}
		q1sq2s += q1s[a] * q2s[a];
	}

	double q1q2 = 0.0;

	for (size_t a = 0; a < 3; a++)
		for (size_t b = 0; b < 3; b++)
			q1q2 += quad1[quad_idx(a, b)] * quad2[quad_idx(a, b)];

	double g = 30.0 / r7 * q1q2 - 420.0 / r9 * q1sq2s +
			945.0 / r11 * q1ss * q2ss;

	double t1x = 0.0, t1y = 0.0, t1z = 0.0;

	for (size_t a = 0; a < 3; a++)
		for (size_t b = 0; b < 3; b++) {
			size_t ab = quad_idx(a, b);
			double dra = vec_get(dr, a);
			t1x += (quad1[quad_idx(0, b)] * quad2[ab] +
				quad1[ab] * quad2[quad_idx(0, b)]) * dra;
			t1y += (quad1[quad_idx(1, b)] * quad2[ab] +
				quad1[ab] * quad2[quad_idx(1, b)]) * dra;
			t1z += (quad1[quad_idx(2, b)] * quad2[ab] +
				quad1[ab] * quad2[quad_idx(2, b)]) * dra;
		}

	force->x = (g * dr->x + 60.0 / r7 * t1x -
			210.0 / r9 * (q1s[0] * q2ss + q2s[0] * q1ss)) / 9.0;
	force->y = (g * dr->y + 60.0 / r7 * t1y -
			210.0 / r9 * (q1s[1] * q2ss + q2s[1] * q1ss)) / 9.0;
	force->z = (g * dr->z + 60.0 / r7 * t1z -
			210.0 / r9 * (q1s[2] * q2ss + q2s[2] * q1ss)) / 9.0;

	double q1q2tt[3][3];
	memset(q1q2tt, 0, 9 * sizeof(double));

	for (size_t a = 0; a < 3; a++)
	for (size_t b = 0; b < 3; b++)
	for (size_t c = 0; c < 3; c++) {
		double dra = vec_get(dr, a);
		double drc = vec_get(dr, c);
		q1q2tt[b][c] += quad1[quad_idx(a, b)] *
				(-10.0 / r7 * (drc * q2s[a] + dra * q2s[c]) +
				  35.0 / r9 * dra * drc * q2ss +
				   2.0 / r5 * quad2[quad_idx(a, c)]);
	}

	add1->x = 2.0 / 3.0 * (q1q2tt[1][2] - q1q2tt[2][1]);
	add1->y = 2.0 / 3.0 * (q1q2tt[2][0] - q1q2tt[0][2]);
	add1->z = 2.0 / 3.0 * (q1q2tt[0][1] - q1q2tt[1][0]);

	double q2q1tt[3][3];
	memset(q2q1tt, 0, 9 * sizeof(double));

	for (size_t a = 0; a < 3; a++)
	for (size_t b = 0; b < 3; b++)
	for (size_t c = 0; c < 3; c++) {
		double dra = vec_get(dr, a);
		double drc = vec_get(dr, c);
		q2q1tt[b][c] += quad2[quad_idx(a, b)] *
				(-10.0 / r7 * (drc * q1s[a] + dra * q1s[c]) +
				  35.0 / r9 * dra * drc * q1ss +
				   2.0 / r5 * quad1[quad_idx(a, c)]);
	}

	add2->x = 2.0 / 3.0 * (q2q1tt[1][2] - q2q1tt[2][1]);
	add2->y = 2.0 / 3.0 * (q2q1tt[2][0] - q2q1tt[0][2]);
	add2->z = 2.0 / 3.0 * (q2q1tt[0][1] - q2q1tt[1][0]);
}
Example #7
0
void
efp_dipole_quadrupole_grad(const vec_t *d1, const double *quad2,
			   const vec_t *dr, vec_t *force, vec_t *add1,
			   vec_t *add2)
{
	double r = vec_len(dr);
	double r2 = r * r;
	double r3 = r2 * r;
	double r5 = r3 * r2;
	double r7 = r5 * r2;
	double r9 = r7 * r2;

	double q2sx = 0.0;
	double q2sy = 0.0;
	double q2sz = 0.0;

	for (size_t a = 0; a < 3; a++) {
		q2sx += quad2[quad_idx(0, a)] * vec_get(dr, a);
		q2sy += quad2[quad_idx(1, a)] * vec_get(dr, a);
		q2sz += quad2[quad_idx(2, a)] * vec_get(dr, a);
	}

	double d1dr = vec_dot(d1, dr);
	double q2s = quadrupole_sum(quad2, dr);

	double t1 = d1->x * q2sx + d1->y * q2sy + d1->z * q2sz;
	double t2 = -10.0 / r7 * t1 + 35.0 / r9 * q2s * d1dr;

	double d1q2x = d1->x * quad2[quad_idx(0, 0)] +
		       d1->y * quad2[quad_idx(0, 1)] +
		       d1->z * quad2[quad_idx(0, 2)];
	double d1q2y = d1->x * quad2[quad_idx(1, 0)] +
		       d1->y * quad2[quad_idx(1, 1)] +
		       d1->z * quad2[quad_idx(1, 2)];
	double d1q2z = d1->x * quad2[quad_idx(2, 0)] +
		       d1->y * quad2[quad_idx(2, 1)] +
		       d1->z * quad2[quad_idx(2, 2)];

	double q2xdr = dr->x * quad2[quad_idx(0, 0)] +
		       dr->y * quad2[quad_idx(0, 1)] +
		       dr->z * quad2[quad_idx(0, 2)];
	double q2ydr = dr->x * quad2[quad_idx(1, 0)] +
		       dr->y * quad2[quad_idx(1, 1)] +
		       dr->z * quad2[quad_idx(1, 2)];
	double q2zdr = dr->x * quad2[quad_idx(2, 0)] +
		       dr->y * quad2[quad_idx(2, 1)] +
		       dr->z * quad2[quad_idx(2, 2)];

	force->x = t2 * dr->x + 2.0 / r5 * d1q2x -
			5.0 / r7 * (q2s * d1->x + 2.0 * q2xdr * d1dr);
	force->y = t2 * dr->y + 2.0 / r5 * d1q2y -
			5.0 / r7 * (q2s * d1->y + 2.0 * q2ydr * d1dr);
	force->z = t2 * dr->z + 2.0 / r5 * d1q2z -
			5.0 / r7 * (q2s * d1->z + 2.0 * q2zdr * d1dr);

	add1->x = 2.0 / r5 * (d1->z * q2ydr - d1->y * q2zdr) +
			5.0 / r7 * q2s * (dr->z * d1->y - dr->y * d1->z);
	add1->y = 2.0 / r5 * (d1->x * q2zdr - d1->z * q2xdr) +
			5.0 / r7 * q2s * (dr->x * d1->z - dr->z * d1->x);
	add1->z = 2.0 / r5 * (d1->y * q2xdr - d1->x * q2ydr) +
			5.0 / r7 * q2s * (dr->y * d1->x - dr->x * d1->y);

	add2->x = -10.0 / r7 * d1dr * (q2ydr * dr->z - q2zdr * dr->y) -
			2.0 / r5 * ((q2zdr * d1->y + dr->y * d1q2z) -
			      (q2ydr * d1->z + dr->z * d1q2y));
	add2->y = -10.0 / r7 * d1dr * (q2zdr * dr->x - q2xdr * dr->z) -
			2.0 / r5 * ((q2xdr * d1->z + dr->z * d1q2x) -
			      (q2zdr * d1->x + dr->x * d1q2z));
	add2->z = -10.0 / r7 * d1dr * (q2xdr * dr->y - q2ydr * dr->x) -
			2.0 / r5 * ((q2ydr * d1->x + dr->x * d1q2y) -
			      (q2xdr * d1->y + dr->y * d1q2x));
}