Skip to content

Instantly share code, notes, and snippets.

@Shitaro
Created March 12, 2014 03:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shitaro/9500323 to your computer and use it in GitHub Desktop.
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.
#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