step/stepcore
coulombforce.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "coulombforce.h"
00020 #include "particle.h"
00021
00022 #include <cmath>
00023
00024 namespace StepCore {
00025
00026 STEPCORE_META_OBJECT(CoulombForce, "Coulomb force", 0,
00027 STEPCORE_SUPER_CLASS(Item) STEPCORE_SUPER_CLASS(Force),
00028 STEPCORE_PROPERTY_RW(double, coulombConst, STEPCORE_FROM_UTF8("N m²/C²"),
00029 "Coulomb constant", coulombConst, setCoulombConst))
00030
00031 STEPCORE_META_OBJECT(CoulombForceErrors, "Errors class for CoulombForce", 0,
00032 STEPCORE_SUPER_CLASS(ObjectErrors),
00033 STEPCORE_PROPERTY_RW(double, coulombConstVariance, STEPCORE_FROM_UTF8("N m²/C²"),
00034 "Coulomb constant variance", coulombConstVariance, setCoulombConstVariance))
00035
00036 CoulombForce* CoulombForceErrors::coulombForce() const
00037 {
00038 return static_cast<CoulombForce*>(owner());
00039 }
00040
00041 CoulombForce::CoulombForce(double coulombConst)
00042 : _coulombConst(coulombConst)
00043 {
00044 coulombForceErrors()->setCoulombConstVariance(
00045 square(Constants::CoulombError));
00046 }
00047
00048 void CoulombForce::calcForce(bool calcVariances)
00049 {
00050 const BodyList::const_iterator end = world()->bodies().end();
00051 for(BodyList::const_iterator b1 = world()->bodies().begin(); b1 != end; ++b1) {
00052 if(!(*b1)->metaObject()->inherits<ChargedParticle>()) continue;
00053 for(BodyList::const_iterator b2 = b1+1; b2 != end; ++b2) {
00054 if(!(*b2)->metaObject()->inherits<ChargedParticle>()) continue;
00055 ChargedParticle* p1 = static_cast<ChargedParticle*>(*b1);
00056 ChargedParticle* p2 = static_cast<ChargedParticle*>(*b2);
00057
00058 Vector2d r = p2->position() - p1->position();
00059 double rnorm2 = r.norm2();
00060 Vector2d force = _coulombConst* p1->charge() * p2->charge() * r / (rnorm2*sqrt(rnorm2));
00061 p2->applyForce(force);
00062 force.invert();
00063 p1->applyForce(force);
00064
00065 if(calcVariances) {
00066
00067 ChargedParticleErrors* pe1 = p1->chargedParticleErrors();
00068 ChargedParticleErrors* pe2 = p2->chargedParticleErrors();
00069 Vector2d rV = pe2->positionVariance() + pe1->positionVariance();
00070 Vector2d forceV = force.cSquare().cMultiply(
00071 Vector2d(coulombForceErrors()->_coulombConstVariance / square(_coulombConst) +
00072 pe1->chargeVariance() / square(p1->charge()) +
00073 pe2->chargeVariance() / square(p2->charge())) +
00074 Vector2d(rV[0] * square(1/r[0] - 3*r[0]/rnorm2) + rV[1] * square(3*r[1]/rnorm2),
00075 rV[1] * square(1/r[1] - 3*r[1]/rnorm2) + rV[0] * square(3*r[0]/rnorm2)));
00076 pe1->applyForceVariance(forceV);
00077 pe2->applyForceVariance(forceV);
00078 }
00079 }
00080 }
00081 }
00082
00083 }
00084