VectorMatrix CalculateStrayfieldForCuboid( int dim_x, int dim_y, int dim_z, double delta_x, double delta_y, double delta_z, int mag_dir, Vector3d pos, Vector3d size, int infinity) { // Check arguments. if ((infinity & INFINITE_POS_X || infinity & INFINITE_NEG_X) && size.x != 0.0) throw std::runtime_error("CalculateStrayfieldForCuboid: cuboid size in x-direction must be zero for infinite extents in x direction"); if ((infinity & INFINITE_POS_Y || infinity & INFINITE_NEG_Y) && size.y != 0.0) throw std::runtime_error("CalculateStrayfieldForCuboid: cuboid size in y-direction must be zero for infinite extents in y direction"); if ((infinity & INFINITE_POS_Z || infinity & INFINITE_NEG_Z) && size.z != 0.0) throw std::runtime_error("CalculateStrayfieldForCuboid: cuboid size in z-direction must be zero for infinite extents in z direction"); if (size.x < 0.0 || size.y < 0.0 || size.z < 0.0) throw std::runtime_error("CalculateStrayfieldForCuboid: cuboid size must be positive"); if (dim_x < 1 || dim_y < 1 || dim_z < 1) throw std::runtime_error("CalculateStrayfieldForCuboid: dim_x,y,z must be positive"); if (!(delta_x > 0.0 && delta_y > 0.0 && delta_z > 0.0)) throw std::runtime_error("CalculateStrayfieldForCuboid: delta_x,y,z must be positive"); if (mag_dir < 0 || mag_dir > 2) throw std::runtime_error("CalculateStrayfieldForCuboid: cuboid_mag_dir must be 0, 1, or 2"); Vector3d p0 = pos; Vector3d p1 = pos + size; VectorMatrix H(Shape(dim_x, dim_y, dim_z)); H.clear(); VectorMatrix::accessor H_acc(H); H_acc.set(0,0,0, Vector3d(1,2,3)); assert(0); }
void Transposer_CUDA::copy_unpad(const float *in_x, const float *in_y, const float *in_z, VectorMatrix &H) { // Ifdef HAVE_CUDA_64 and isCuda64Enabled(), we directly store output matrices on the GPU with 64 bit precision. #ifdef HAVE_CUDA_64 if (isCuda64Enabled()) { // xyz, s1 -> H VectorMatrix::cu64_accessor H_acc(H); cuda_copy_unpad_r2r(exp_x, dim_y, dim_z, dim_x, in_x, in_y, in_z, H_acc.ptr_x(), H_acc.ptr_y(), H_acc.ptr_z()); } else #endif { // xyz, s1 -> H VectorMatrix::cu32_accessor H_acc(H); cuda_copy_unpad_r2r(exp_x, dim_y, dim_z, dim_x, in_x, in_y, in_z, H_acc.ptr_x(), H_acc.ptr_y(), H_acc.ptr_z()); } }
void SymmetricMatrixVectorConvolution_Simple::execute(const VectorMatrix &rhs, VectorMatrix &res) { Matrix::ro_accessor N_acc(lhs); VectorMatrix::const_accessor M_acc(rhs); VectorMatrix:: accessor H_acc(res); // H(r) = int N(r-r')*M(r') dr' // Hx = Nxx*Mx + Nxy*My + Nxz*Mz // Hy = Nyx*Mx + Nyy*My + Nyz*Mz // Hz = Nxz*Mx + Nyz*My + Nzz*Mz for (int z=0; z<dim_z; ++z) for (int y=0; y<dim_y; ++y) for (int x=0; x<dim_x; ++x) { Vector3d H(0.0, 0.0, 0.0); for (int o=0; o<dim_z; ++o) for (int n=0; n<dim_y; ++n) for (int m=0; m<dim_x; ++m) { // (X,Y,Z): position in demag tensor field matrix const int X = (x-m+exp_x) % exp_x; const int Y = (y-n+exp_y) % exp_y; const int Z = (z-o+exp_z) % exp_z; const double Nxx = N_acc.at(0,X,Y,Z); const double Nxy = N_acc.at(1,X,Y,Z); const double Nxz = N_acc.at(2,X,Y,Z); const double Nyy = N_acc.at(3,X,Y,Z); const double Nyz = N_acc.at(4,X,Y,Z); const double Nzz = N_acc.at(5,X,Y,Z); const Vector3d &M = M_acc.get(m, n, o); H.x += Nxx*M.x + Nxy*M.y + Nxz*M.z; H.y += Nxy*M.x + Nyy*M.y + Nyz*M.z; H.z += Nxz*M.x + Nyz*M.y + Nzz*M.z; } H_acc.set(x,y,z,H); } }
static double fdm_exchange_cpu_nonperiodic( int dim_x, int dim_y, int dim_z, double delta_x, double delta_y, double delta_z, const Matrix &Ms, const Matrix &A, const VectorMatrix &M, VectorMatrix &H) { const int dim_xy = dim_x * dim_y; const double wx = 1.0 / (delta_x * delta_x); const double wy = 1.0 / (delta_y * delta_y); const double wz = 1.0 / (delta_z * delta_z); VectorMatrix::const_accessor M_acc(M); VectorMatrix::accessor H_acc(H); Matrix::ro_accessor Ms_acc(Ms), A_acc(A); double energy = 0.0; 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 i = z*dim_xy + y*dim_x + x; // linear index of (x,y,z) const double Ms = Ms_acc.at(i); if (Ms == 0.0) { H_acc.set(i, Vector3d(0.0, 0.0, 0.0)); continue; } const int idx_l = i- 1; const int idx_r = i+ 1; const int idx_u = i- dim_x; const int idx_d = i+ dim_x; const int idx_f = i-dim_xy; const int idx_b = i+dim_xy; const Vector3d M_i = M_acc.get(i) / Ms; // magnetization at (x,y,z) Vector3d sum(0.0, 0.0, 0.0); // left / right (X) if (x > 0) { const double Ms_l = Ms_acc.at(idx_l); if (Ms_l != 0.0) sum += ((M_acc.get(idx_l) / Ms_l) - M_i) * wx; } if (x < dim_x-1) { const double Ms_r = Ms_acc.at(idx_r); if (Ms_r != 0.0) sum += ((M_acc.get(idx_r) / Ms_r) - M_i) * wx; } // up / down (Y) if (y > 0) { const double Ms_u = Ms_acc.at(idx_u); if (Ms_u != 0.0) sum += ((M_acc.get(idx_u) / Ms_u) - M_i) * wy; } if (y < dim_y-1) { const double Ms_d = Ms_acc.at(idx_d); if (Ms_d != 0.0) sum += ((M_acc.get(idx_d) / Ms_d) - M_i) * wy; } // forward / backward (Z) if (z > 0) { const double Ms_f = Ms_acc.at(idx_f); if (Ms_f != 0.0) sum += ((M_acc.get(idx_f) / Ms_f) - M_i) * wz; } if (z < dim_z-1) { const double Ms_b = Ms_acc.at(idx_b); if (Ms_b != 0.0) sum += ((M_acc.get(idx_b) / Ms_b) - M_i) * wz; } // Exchange field at (x,y,z) const Vector3d H_i = (2/MU0) * A_acc.at(i) * sum / Ms; H_acc.set(i, H_i); // Exchange energy sum energy += dot(M_i, H_i); } } } energy *= -MU0/2.0 * delta_x * delta_y * delta_z; return energy; }