OpenLB 1.7
Loading...
Searching...
No Matches
interpMagForceForMagP3D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2015 Marie-Luise Maier, Mathias J. Krause, Sascha Janz
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24// Magnetic field that creates magnetization in wire has to be orthogonal to the wire.
27#ifndef InterpMagForceForMagP3D_HH
28#define InterpMagForceForMagP3D_HH
29
30#include "utilities/omath.h"
31#include <vector>
33
34#ifndef M_PI
35#define M_PI 3.14159265358979323846
36#endif
37
38namespace olb {
39
40template<typename T, template<typename U> class PARTICLETYPE, typename DESCRIPTOR>
42 : Force3D<T, PARTICLETYPE>(),
43 _scale(scale),
44 _scaleT(scaleT)
45{
46// this->_name = "InterpMagForceForMagP3D";
47}
48
49template<typename T, template<typename U> class PARTICLETYPE, typename DESCRIPTOR>
51 typename std::deque<PARTICLETYPE<T> >::iterator p, int pInt,
53{
54
55 std::vector < std::pair<size_t, T> > ret_matches;
56 pSys.getDetection()->getMatches(pInt, ret_matches);
57 // std::random_shuffle ( ret_matches.begin(), ret_matches.end() );
58
59 /*const*/ PARTICLETYPE<T>* p2 = NULL;
60 typename std::vector<std::pair<size_t, T> >::iterator it =
61 ret_matches.begin();
62
63 Vector<T, 3> dMom_1 = Vector<T, 3>((p->getMoment()));
64 if (norm(dMom_1) > std::numeric_limits<T>::epsilon()) {
65 T m_p1 = p->getMagnetisation();
66
67 for (; it != ret_matches.end(); it++) {
68 if (it->second >= std::numeric_limits < T > ::epsilon()) {
69
70 p2 = &pSys[it->first];
71
72 // No magnetic force between particles which are in physcal contact
73 // if ((p2->getRad() + p->getRad()) <= util::sqrt(it->second)) {
74
75 // get neighbour particle moment
76 Vector<T, 3> dMom_2((p2->getMoment()));
77 if (norm(dMom_2) > std::numeric_limits<T>::epsilon()) {
78 T m_p2 = p2->getMagnetisation();
79
80 // given moment magnitudes as scale factors
81 T m_i_scaleFactor = norm(dMom_1);
82 T m_j_scaleFactor = norm(dMom_2);
83
84 // normalised moment directions
85 Vector<T, 3> n_i(dMom_1);
86 n_i = normalize(n_i);
87 Vector<T, 3> n_j(dMom_2);
88 n_j = normalize(n_j);
89
90 // constants
91 T mu_0 = 4 * M_PI * 1.e-7; // magnetic constant
92 T mu_i = 4. / 3 * M_PI * util::pow(p->getRad(), 3) * m_p1 * m_i_scaleFactor ; // magnetic moment of particle i
93 T mu_j = 4. / 3 * M_PI * util::pow(p2->getRad(), 3) * m_p2 * m_j_scaleFactor ; // of particle j
94
95 //vector from particle1 to particle2
96 Vector<T, 3> r_ij;
97 //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
98 r_ij[0] = p->getPos()[0] - p2->getPos()[0];
99 r_ij[1] = p->getPos()[1] - p2->getPos()[1];
100 r_ij[2] = p->getPos()[2] - p2->getPos()[2];
101
102 // distance from particle1 to particle2
103 T r = norm(r_ij);
104
105 // normalised direction vector
106 Vector<T, 3> t_ij(r_ij);
107 t_ij = normalize(t_ij);
108
109 // FORCE of Dipole 1 on Dipole 2
110 Vector<T, 3> mi = {n_i};
111 mi *= mu_i;
112 Vector<T, 3> mj = {n_j};
113 mj *= mu_j;
114 Vector<T, 3> rn = {r_ij};
115 rn *= -1. ;
116 rn = normalize(rn);
117 T scalar_termF = (3 * mu_0 ) / (4 * M_PI * util::pow(r, 4));
118 Vector<T, 3> force = mj * (mi * rn) + mi * (mj * rn) + rn * (mi * mj) - 5 * rn * (mi * rn) * (mj * rn) ;
119 force *= scalar_termF;
120
121 // TORQUE of Dipole 1 on Dipole 2
122 // 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]
123 T scalar_termT = - (mu_0 * mu_i * mu_j) / (4 * M_PI * util::pow(r, 3));
124 Vector<T, 3> torque = crossProduct3D(n_i, n_j);
125 torque -= crossProduct3D( 3 * (n_j * t_ij) * n_i, t_ij);
126 torque *= scalar_termT;
127
128 // Force an torque for overlapping particles
129 if ((p2->getRad() + p->getRad()) >= util::sqrt(it->second)) {
130 force = normalize(force);
131 torque *= 0;
132 force *= mu_0 * util::pow((mu_i + mu_j) / 2., 2.) / (4 * M_PI * util::pow(r / 2, 4.)) ;
133 }
134
135 p->getTorque()[0] += 0.5 * torque[0] * _scaleT;
136 p->getTorque()[1] += 0.5 * torque[1] * _scaleT;
137 p->getTorque()[2] += 0.5 * torque[2] * _scaleT;
138 p->getForce()[0] -= 0.5 * force[0] * _scale ;
139 p->getForce()[1] -= 0.5 * force[1] * _scale ;
140 p->getForce()[2] -= 0.5 * force[2] * _scale ;
141 p2->getTorque()[0] -= 0.5 * torque[0] * _scaleT;
142 p2->getTorque()[1] -= 0.5 * torque[1] * _scaleT;
143 p2->getTorque()[2] -= 0.5 * torque[2] * _scaleT;
144 p2->getForce()[0] += 0.5 * force[0] * _scale ;
145 p2->getForce()[1] += 0.5 * force[1] * _scale ;
146 p2->getForce()[2] += 0.5 * force[2] * _scale ;
147
148 }
149 // }
150 }
151 }
152 }
153}
154
155}
156
157#endif // INTERPMAGFORCEFORMAGP3D_H_
#define M_PI
Prototype for all particle forces.
Definition force3D.h:43
InterpMagForceForMagP3D(T scale=T(1), T scaleT=T(1))
void applyForce(typename std::deque< PARTICLETYPE< T > >::iterator p, int pInt, ParticleSystem3D< T, PARTICLETYPE > &psSys) override
ContactDetection< T, PARTICLETYPE > * getDetection()
Plain old scalar vector.
Definition vector.h:47
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
Top level namespace for all of OpenLB.
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.
constexpr Vector< T, 3 > crossProduct3D(const ScalarVector< T, 3, IMPL > &a, const ScalarVector< T, 3, IMPL_ > &b) any_platform
Definition vector.h:224
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})
Definition vector.h:245