/* This file is part of the OpenLB library * * Copyright (C) 2015 Marie-Luise Maier, Mathias J. Krause, Sascha Janz * E-mail contact: info@openlb.net * The most recent release of OpenLB can be downloaded at * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /// Magnetic field that creates magnetization in wire has to be orthogonal to the wire. /// to calculate the magnetic force on particles around a cylinder /// (J. Lindner et al. / Computers and Chemical Engineering 54 (2013) 111-121) #ifndef InterpMagForceForMagP3D_HH #define InterpMagForceForMagP3D_HH #include #include #include "interpMagForceForMagP3D.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif namespace olb { template class PARTICLETYPE, typename DESCRIPTOR> InterpMagForceForMagP3D::InterpMagForceForMagP3D(T scale, T scaleT) : Force3D(), _scale(scale), _scaleT(scaleT) { // this->_name = "InterpMagForceForMagP3D"; } template class PARTICLETYPE, typename DESCRIPTOR> void InterpMagForceForMagP3D::applyForce( typename std::deque >::iterator p, int pInt, ParticleSystem3D& pSys) { std::vector < std::pair > ret_matches; pSys.getDetection()->getMatches(pInt, ret_matches); // std::random_shuffle ( ret_matches.begin(), ret_matches.end() ); /*const*/ PARTICLETYPE* p2 = NULL; typename std::vector >::iterator it = ret_matches.begin(); Vector dMom_1 = Vector((p->getMoment())); if (dMom_1.norm() > std::numeric_limits::epsilon()) { T m_p1 = p->getMagnetisation(); for (; it != ret_matches.end(); it++) { if (it->second >= std::numeric_limits < T > ::epsilon()) { p2 = &pSys[it->first]; // No magnetic force between particles which are in physcal contact // if ((p2->getRad() + p->getRad()) <= std::sqrt(it->second)) { // get neighbour particle moment Vector dMom_2((p2->getMoment())); if (dMom_2.norm() > std::numeric_limits::epsilon()) { T m_p2 = p2->getMagnetisation(); // given moment magnitudes as scale factors T m_i_scaleFactor = dMom_1.norm(); T m_j_scaleFactor = dMom_2.norm(); // normalised moment directions Vector n_i(dMom_1); n_i.normalize(); Vector n_j(dMom_2); n_j.normalize(); // constants T mu_0 = 4 * M_PI * 1.e-7; // magnetic constant T mu_i = 4. / 3 * M_PI * pow(p->getRad(), 3) * m_p1 * m_i_scaleFactor ; // magnetic moment of particle i T mu_j = 4. / 3 * M_PI * pow(p2->getRad(), 3) * m_p2 * m_j_scaleFactor ; // of particle j //vector from particle1 to particle2 Vector r_ij; //S Das wäre der Richtungsvektor von p2 zu p und nicht von p zu p2, aber die Rechung unten berücksichtigt das wohl, da richtige Ergebnisse r_ij[0] = p->getPos()[0] - p2->getPos()[0]; r_ij[1] = p->getPos()[1] - p2->getPos()[1]; r_ij[2] = p->getPos()[2] - p2->getPos()[2]; // distance from particle1 to particle2 T r = r_ij.norm(); // normalised direction vector Vector t_ij(r_ij); t_ij.normalize(); // FORCE of Dipole 1 on Dipole 2 Vector mi = {n_i}; mi *= mu_i; Vector mj = {n_j}; mj *= mu_j; Vector rn = {r_ij}; rn *= -1. ; normalize(rn); T scalar_termF = (3 * mu_0 ) / (4 * M_PI * std::pow(r, 4)); Vector force = mj * (mi * rn) + mi * (mj * rn) + rn * (mi * mj) - 5 * rn * (mi * rn) * (mj * rn) ; force *= scalar_termF; // TORQUE of Dipole 1 on Dipole 2 // T_ij = -[(mu_0*mu_i*mu_j)/(4*M_PI*r^3)][n_i x n_j - 3(n_j * t_ij)n_i x t_ij] T scalar_termT = - (mu_0 * mu_i * mu_j) / (4 * M_PI * std::pow(r, 3)); Vector torque = crossProduct3D(n_i, n_j); torque -= crossProduct3D( 3 * (n_j * t_ij) * n_i, t_ij); torque *= scalar_termT; // Force an torque for overlapping particles if ((p2->getRad() + p->getRad()) >= std::sqrt(it->second)) { normalize(force); torque *= 0; force *= mu_0 * pow((mu_i + mu_j) / 2., 2.) / (4 * M_PI * pow(r / 2, 4.)) ; } p->getTorque()[0] += 0.5 * torque[0] * _scaleT; p->getTorque()[1] += 0.5 * torque[1] * _scaleT; p->getTorque()[2] += 0.5 * torque[2] * _scaleT; p->getForce()[0] -= 0.5 * force[0] * _scale ; p->getForce()[1] -= 0.5 * force[1] * _scale ; p->getForce()[2] -= 0.5 * force[2] * _scale ; p2->getTorque()[0] -= 0.5 * torque[0] * _scaleT; p2->getTorque()[1] -= 0.5 * torque[1] * _scaleT; p2->getTorque()[2] -= 0.5 * torque[2] * _scaleT; p2->getForce()[0] += 0.5 * force[0] * _scale ; p2->getForce()[1] += 0.5 * force[1] * _scale ; p2->getForce()[2] += 0.5 * force[2] * _scale ; } // } } } } } } #endif // INTERPMAGFORCEFORMAGP3D_H_