Example #1
0
void fdm_zhangli_cpu(
	int dim_x, int dim_y, int dim_z,
	double delta_x, double delta_y, double delta_z,
	bool do_precess,
	const Matrix &P, const Matrix &xi,
	const Matrix &Ms, const Matrix &alpha,
	const VectorMatrix &j, const VectorMatrix &M,
	VectorMatrix &dM)
{
	VectorMatrix::const_accessor M_acc(M), j_acc(j);
	Matrix::ro_accessor Ms_acc(Ms), alpha_acc(alpha), P_acc(P), xi_acc(xi);
	VectorMatrix::accessor dM_acc(dM);

	for (int z=0; z<dim_z; ++z)
	for (int y=0; y<dim_y; ++y)
	for (int x=0; x<dim_x; ++x) {	
		const int k = z*dim_x*dim_y + y*dim_x + x;

		const double Ms    = Ms_acc.at(k); 
		const double alpha = alpha_acc.at(k);
		const double P     = P_acc.at(k);
		const double xi    = xi_acc.at(k);
		const Vector3d j   = j_acc.get(k);

		dM_acc.set(k, zhangli_dMdt(x, y, z, dim_x, dim_y, dim_z, delta_x, delta_y, delta_z, do_precess, P, xi, Ms, alpha, j, M_acc));
	}
}
void fdm_slonchewski(
	int dim_x, int dim_y, int dim_z,
	double delta_x, double delta_y, double delta_z,
	double a_j,
	const VectorMatrix &p, // spin polarization
	const Matrix &Ms,
	const Matrix &alpha,
	const VectorMatrix &M,
	VectorMatrix &dM)
{
	// Calculate: 
	//   c1*(M x (M x p)) + c2*(M x p)
	//
	//   c1(theta): damping factor
	//   c2(theta): precession factor
	//   Ms*cos(theta) = M*p

	Matrix::ro_accessor Ms_acc(Ms), alpha_acc(alpha);
	VectorMatrix::const_accessor p_acc(p);
	VectorMatrix::const_accessor M_acc(M);
	VectorMatrix::accessor dM_acc(dM);

	const int N = dim_x * dim_y * dim_z;
	for (int n=0; n<N; ++n) {
		const double alpha = alpha_acc.at(n);
		const double Ms    = Ms_acc.at(n);

		const Vector3d p = p_acc.get(n);
		const Vector3d M = M_acc.get(n);
		
		if (p == Vector3d(0.0, 0.0, 0.0)) continue;
		if (Ms == 0.0) continue;

		// Calculate precession and damping terms
		const Vector3d Mxp   = cross(M, p); // precession: u=mxp
		const Vector3d MxMxp = cross(M, Mxp); // damping:  t=mxu=mx(mxp)

		// add both terms to dm/dt in LLGE
		const double gamma_pr = GYROMAGNETIC_RATIO / (1.0 + alpha*alpha);

		Vector3d dM_n;
		dM_n.x = gamma_pr * a_j * (-MxMxp.x/Ms + Mxp.x*alpha);
		dM_n.y = gamma_pr * a_j * (-MxMxp.y/Ms + Mxp.y*alpha);
		dM_n.z = gamma_pr * a_j * (-MxMxp.z/Ms + Mxp.z*alpha);
		dM_acc.set(n, dM_n);
	}
}