Created
March 12, 2014 03:33
-
-
Save Shitaro/9500323 to your computer and use it in GitHub Desktop.
Computing the magnetic field which a Merritt 4-coil produces using the Builder design pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma warning(disable : 4996) // If we use VS, we should write this in order to avoid error C4996. | |
#include <iostream> | |
#include <valarray> | |
#include <numeric> | |
// Merritt coil class | |
class MerrittCoil | |
{ | |
public: | |
MerrittCoil(); | |
~MerrittCoil(); | |
double effFunc(int index, bool sgn); | |
double getCurrent(); | |
void setCurrent(double current); | |
double getLength(); | |
void setLength(double length); | |
double getDistance(); | |
void setDistance(double distance); | |
std::valarray<double> getPoint(); | |
void setPoint(std::valarray<double> &point); | |
std::valarray<double> getMagneticField(); | |
double getB(); | |
double getTrueB(); | |
private: | |
double current; // an electric current | |
double length; // the side length of a square | |
double distance; // the distance between the point of origin and a Merritt coil | |
std::valarray<double> point; // the place where we would like to find the B | |
std::valarray<double> magneticField; // the norm of B | |
double B; | |
double mu; // the magnetic permeability per 4*pi | |
}; | |
MerrittCoil::MerrittCoil() | |
: current(0), | |
length(0), | |
distance(0), | |
point(3), | |
magneticField(3), | |
B(0), | |
mu(1e-7) // [N/A^2] | |
{ | |
} | |
MerrittCoil::~MerrittCoil(){ | |
} | |
double MerrittCoil::getCurrent(){ | |
return current; | |
} | |
double MerrittCoil::effFunc(int index, bool sgn){ | |
int s; | |
double a, b; | |
if(sgn==true){s=1;} | |
else{s=-1;} | |
a=sqrt( | |
(point[2]-distance)*(point[2]-distance) | |
+(length-point[index])*(length-point[index]) | |
+(length-s*point[1-index])*(length-s*point[1-index])); | |
b=sqrt( | |
(point[2]-distance)*(point[2]-distance) | |
+(length+point[index])*(length+point[index]) | |
+(length-s*point[1-index])*(length-s*point[1-index])); | |
return ((length-point[index])*b+(length+point[index])*a)/(a*b); | |
} | |
void MerrittCoil::setCurrent(double current){ | |
this->current = current; | |
} | |
double MerrittCoil::getLength(){ | |
return current; | |
} | |
void MerrittCoil::setLength(double length){ | |
this->length = length*0.5; | |
} | |
double MerrittCoil::getDistance(){ | |
return distance; | |
} | |
void MerrittCoil::setDistance(double distance){ | |
this->distance = distance; | |
} | |
std::valarray<double> MerrittCoil::getPoint(){ | |
return point; | |
} | |
void MerrittCoil::setPoint(std::valarray<double> &point){ | |
this->point = point; | |
} | |
std::valarray<double> MerrittCoil::getMagneticField(){ | |
int i; | |
std::valarray<double> tmp(2); | |
for(i=0;i<2;i++){ | |
magneticField[i]=effFunc(1-i,true) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length+point[i])*(length+point[i]) | |
) | |
-effFunc(1-i,false) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length-point[i])*(length-point[i]) | |
); | |
magneticField[i]*=mu*current*(point[2]-distance); | |
magneticField[i]/=( | |
( | |
(point[2]-distance)*(point[2]-distance) | |
+(length+point[i])*(length+point[i]) | |
) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length-point[i])*(length-point[i])) | |
); | |
} | |
for(i=0;i<2;i++){ | |
tmp[i]=effFunc(i,true)*(length-point[1-i]) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length+point[1-i])*(length+point[1-i]) | |
) | |
+effFunc(i,false)*(length+point[1-i]) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length-point[1-i])*(length+-point[1-i]) | |
); | |
tmp[i]/=( | |
( | |
(point[2]-distance)*(point[2]-distance) | |
+(length+point[1-i])*(length+point[1-i]) | |
) | |
*( | |
(point[2]-distance)*(point[2]-distance) | |
+(length-point[1-i])*(length+-point[1-i]) | |
) | |
); | |
} | |
magneticField[2]=mu*current*(tmp[0]+tmp[1]); | |
return magneticField; | |
} | |
double MerrittCoil::getB(){ | |
getMagneticField(); | |
B=std::inner_product(&magneticField[0], &magneticField[0]+3, &magneticField[0], 0.0); | |
return sqrt(B); | |
} | |
double MerrittCoil::getTrueB(){ | |
B=sqrt(2.0)*4.0*mu*current; | |
B/=length; | |
return B; | |
} | |
// Builder interface | |
class IBuilder | |
{ | |
public: | |
virtual void setParameter() = 0; | |
virtual MerrittCoil* getResult() = 0; | |
protected: | |
MerrittCoil* coil; | |
}; | |
// Merrit coil1 builder class | |
class MerrittCoilBuilder1 | |
: public IBuilder | |
{ | |
public: | |
MerrittCoilBuilder1(); | |
~MerrittCoilBuilder1(); | |
void setParameter(); | |
MerrittCoil* getResult(); | |
}; | |
// Builder class | |
MerrittCoilBuilder1::MerrittCoilBuilder1(){ | |
this->coil = new MerrittCoil(); | |
} | |
MerrittCoilBuilder1::~MerrittCoilBuilder1(){ | |
delete coil; | |
} | |
void MerrittCoilBuilder1::setParameter() | |
{ | |
coil->setCurrent(5.2e2); // I = 5.2e2[A] | |
coil->setLength(6.0e-1); // L = 3.0e-1[m] | |
coil->setDistance(3.025e-1); // d = 3.025e-1[m] | |
} | |
MerrittCoil* MerrittCoilBuilder1::getResult(){ | |
return coil; | |
} | |
// Director class | |
class Director | |
{ | |
public: | |
Director(); | |
~Director(); | |
MerrittCoil* Construct(IBuilder* builder); | |
}; | |
Director::Director(){} | |
Director::~Director(){} | |
MerrittCoil* Director::Construct(IBuilder* builder){ | |
builder->setParameter(); | |
return builder->getResult(); | |
} | |
int main(){ | |
std::valarray<double> point(3); | |
Director director; | |
MerrittCoilBuilder1* builder1 = new MerrittCoilBuilder1(); | |
MerrittCoil* coil; | |
director.Construct(builder1); | |
coil = builder1->getResult(); | |
point[2] = 3.025e-1; | |
coil->setPoint(point); | |
std::cout << "B(0,0,3.025e-1) -> " << coil->getMagneticField()[2] << std::endl; | |
std::cout << " true -> " << coil->getTrueB() << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment