00001
00002 #include "MagneticFieldGrid.h"
00003
00004 using namespace std;
00005
00006 void MagneticFieldGrid::load(const string& name){
00007 binary_ifstream inFile(name);
00008 inFile >> GridType;
00009
00010 switch (GridType){
00011 case 1:
00012 inFile >> NumberOfPoints[0] >> NumberOfPoints[1] >> NumberOfPoints[2];
00013 inFile >> ReferencePoint[0] >> ReferencePoint[1] >> ReferencePoint[2];
00014 inFile >> BasicDistance0[0] >> BasicDistance0[1] >> BasicDistance0[2];
00015 break;
00016 case 2:
00017 inFile >> NumberOfPoints[0] >> NumberOfPoints[1] >> NumberOfPoints[2];
00018 inFile >> ReferencePoint[0] >> ReferencePoint[1] >> ReferencePoint[2];
00019 inFile >> BasicDistance0[0] >> BasicDistance0[1] >> BasicDistance0[2];
00020 inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
00021 inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
00022 inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
00023 inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
00024 inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
00025 inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
00026 inFile >> EasyCoordinate[0] >> EasyCoordinate[1] >> EasyCoordinate[2];
00027 break;
00028 case 3:
00029 inFile >> NumberOfPoints[0] >> NumberOfPoints[1] >> NumberOfPoints[2];
00030 inFile >> ReferencePoint[0] >> ReferencePoint[1] >> ReferencePoint[2];
00031 inFile >> BasicDistance0[0] >> BasicDistance0[1] >> BasicDistance0[2];
00032 break;
00033 case 4:
00034 inFile >> NumberOfPoints[0] >> NumberOfPoints[1] >> NumberOfPoints[2];
00035 inFile >> ReferencePoint[0] >> ReferencePoint[1] >> ReferencePoint[2];
00036 inFile >> BasicDistance0[0] >> BasicDistance0[1] >> BasicDistance0[2];
00037 inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
00038 inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
00039 inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
00040 inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
00041 inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
00042 inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
00043 inFile >> EasyCoordinate[0] >> EasyCoordinate[1] >> EasyCoordinate[2];
00044 break;
00045 case 5:
00046 inFile >> NumberOfPoints[0] >> NumberOfPoints[1] >> NumberOfPoints[2];
00047 inFile >> ReferencePoint[0] >> ReferencePoint[1] >> ReferencePoint[2];
00048 inFile >> BasicDistance0[0] >> BasicDistance0[1] >> BasicDistance0[2];
00049 inFile >> RParAsFunOfPhi[0] >> RParAsFunOfPhi[1] >> RParAsFunOfPhi[2] >> RParAsFunOfPhi[3];
00050 break;
00051 }
00052
00053 float Bx, By, Bz;
00054 BVector FieldEntry;
00055 int nLines = NumberOfPoints[0]*NumberOfPoints[1]*NumberOfPoints[2];
00056 FieldValues.reserve(nLines);
00057
00058 for (int iLine=0; iLine<nLines; ++iLine){
00059 inFile >> Bx >> By >> Bz;
00060 FieldEntry.putB3(Bx,By,Bz);
00061 FieldValues.push_back(FieldEntry);
00062 }
00063
00064 string lastEntry;
00065 inFile >> lastEntry;
00066 inFile.close();
00067 if (lastEntry != "complete"){
00068 GridType = 0;
00069 cout << "error during file reading: file is not complete" << endl;
00070 }
00071 return;
00072 }
00073
00074 int MagneticFieldGrid::gridType(){
00075 int type = GridType;
00076 bool text = false;
00077 if (text){
00078 if (type == 0) cout << " grid type = " << type << " --> not determined" << endl;
00079 if (type == 1) cout << " grid type = " << type << " --> (x,y,z) cube" << endl;
00080 if (type == 2) cout << " grid type = " << type << " --> (x,y,z) trapezoid" << endl;
00081 if (type == 3) cout << " grid type = " << type << " --> (r,phi,z) cube" << endl;
00082 if (type == 4) cout << " grid type = " << type << " --> (r,phi,z) trapezoid" << endl;
00083 if (type == 5) cout << " grid type = " << type << " --> (r,phi,z) 1/sin(phi)" << endl;
00084 }
00085 return type;
00086 }
00087
00088 void MagneticFieldGrid::interpolateAtPoint(double X1, double X2, double X3, float &Bx, float &By, float &Bz){
00089 double dB[3] = {0.,0.,0.};
00090
00091 VectorFieldInterpolation MagInterpol;
00092
00093 int index[3];
00094 putCoordGetInd(X1,X2,X3,index[0],index[1],index[2]);
00095 int index0[3] = {0,0,0};
00096 int index1[3] = {0,0,0};
00097 for (int i=0; i<3; ++i){
00098 if (NumberOfPoints[i] > 1){
00099 index0[i] = max(0,index[i]);
00100 if (index0[i] > NumberOfPoints[i]-2) index0[i] = NumberOfPoints[i]-2;
00101 index1[i] = max(1,index[i]+1);
00102 if (index1[i] > NumberOfPoints[i]-1) index1[i] = NumberOfPoints[i]-1;
00103 }
00104 }
00105 double tmpX[3];
00106 float tmpB[3];
00107
00108
00109 putIndicesGetB(index0[0],index0[1],index0[2],tmpB[0],tmpB[1],tmpB[2]);
00110 putIndGetCoord(index0[0],index0[1],index0[2],tmpX[0],tmpX[1],tmpX[2]);
00111 MagInterpol.defineCellPoint000(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00112 putIndicesGetB(index1[0],index0[1],index0[2],tmpB[0],tmpB[1],tmpB[2]);
00113 putIndGetCoord(index1[0],index0[1],index0[2],tmpX[0],tmpX[1],tmpX[2]);
00114 MagInterpol.defineCellPoint100(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00115 putIndicesGetB(index0[0],index1[1],index0[2],tmpB[0],tmpB[1],tmpB[2]);
00116 putIndGetCoord(index0[0],index1[1],index0[2],tmpX[0],tmpX[1],tmpX[2]);
00117 MagInterpol.defineCellPoint010(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00118 putIndicesGetB(index1[0],index1[1],index0[2],tmpB[0],tmpB[1],tmpB[2]);
00119 putIndGetCoord(index1[0],index1[1],index0[2],tmpX[0],tmpX[1],tmpX[2]);
00120 MagInterpol.defineCellPoint110(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00121 putIndicesGetB(index0[0],index0[1],index1[2],tmpB[0],tmpB[1],tmpB[2]);
00122 putIndGetCoord(index0[0],index0[1],index1[2],tmpX[0],tmpX[1],tmpX[2]);
00123 MagInterpol.defineCellPoint001(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00124 putIndicesGetB(index1[0],index0[1],index1[2],tmpB[0],tmpB[1],tmpB[2]);
00125 putIndGetCoord(index1[0],index0[1],index1[2],tmpX[0],tmpX[1],tmpX[2]);
00126 MagInterpol.defineCellPoint101(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00127 putIndicesGetB(index0[0],index1[1],index1[2],tmpB[0],tmpB[1],tmpB[2]);
00128 putIndGetCoord(index0[0],index1[1],index1[2],tmpX[0],tmpX[1],tmpX[2]);
00129 MagInterpol.defineCellPoint011(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00130 putIndicesGetB(index1[0],index1[1],index1[2],tmpB[0],tmpB[1],tmpB[2]);
00131 putIndGetCoord(index1[0],index1[1],index1[2],tmpX[0],tmpX[1],tmpX[2]);
00132 MagInterpol.defineCellPoint111(tmpX[0],tmpX[1],tmpX[2],double(tmpB[0]),double(tmpB[1]),double(tmpB[2]));
00133
00134 MagInterpol.putSCoordGetVField(X1,X2,X3,dB[0],dB[1],dB[2]);
00135 Bx = float(dB[0]);
00136 By = float(dB[1]);
00137 Bz = float(dB[2]);
00138 return;
00139 }
00140
00141
00142
00143
00144
00145 void MagneticFieldGrid::putCoordGetInd(double X1, double X2, double X3, int &Index1, int &Index2, int &Index3){
00146 double pnt[3] = {X1,X2,X3};
00147 int index[3];
00148 switch (GridType){
00149 case 1:
00150 for (int i=0; i<3; ++i){
00151 index[i] = int((pnt[i]-ReferencePoint[i])/BasicDistance0[i]);
00152 }
00153 break;
00154 case 2:
00155
00156 for (int i=0; i<3; ++i){
00157 if (EasyCoordinate[i]){
00158 index[i] = int((pnt[i]-ReferencePoint[i])/BasicDistance0[i]);
00159 }
00160 }
00161 for (int i=0; i<3; ++i){
00162 if (!EasyCoordinate[i]){
00163 double stepSize = BasicDistance0[i];
00164 double offset = 0.0;
00165 for (int j=0; j<3; ++j){
00166 stepSize += BasicDistance1[i][j]*index[j];
00167 offset += BasicDistance2[i][j]*index[j];
00168 }
00169 index[i] = int((pnt[i]-(ReferencePoint[i] + offset))/stepSize);
00170 }
00171 }
00172 break;
00173 case 3:
00174 for (int i=0; i<3; ++i){
00175 index[i] = int((pnt[i]-ReferencePoint[i])/BasicDistance0[i]);
00176 }
00177 break;
00178 case 4:
00179
00180 for (int i=0; i<3; ++i){
00181 if (EasyCoordinate[i]){
00182 index[i] = int((pnt[i]-ReferencePoint[i])/BasicDistance0[i]);
00183 }
00184 }
00185 for (int i=0; i<3; ++i){
00186 if (!EasyCoordinate[i]){
00187 double stepSize = BasicDistance0[i];
00188 double offset = 0.0;
00189 for (int j=0; j<3; ++j){
00190 stepSize += BasicDistance1[i][j]*index[j];
00191 offset += BasicDistance2[i][j]*index[j];
00192 }
00193 index[i] = int((pnt[i]-(ReferencePoint[i] + offset))/stepSize);
00194 }
00195 }
00196 break;
00197 case 5:
00198 double sinPhi = sin(pnt[1]);
00199 double stepSize = RParAsFunOfPhi[0] + RParAsFunOfPhi[1]/sinPhi - RParAsFunOfPhi[2] - RParAsFunOfPhi[3]/sinPhi;
00200 stepSize = stepSize/(NumberOfPoints[0]-1);
00201 double startingPoint = RParAsFunOfPhi[2] + RParAsFunOfPhi[3]/sinPhi;
00202 index[0] = int((pnt[0]-startingPoint)/stepSize);
00203 index[1] = int((pnt[1]-ReferencePoint[1])/BasicDistance0[1]);
00204 index[2] = int((pnt[2]-ReferencePoint[2])/BasicDistance0[2]);
00205 break;
00206 }
00207 Index1 = index[0];
00208 Index2 = index[1];
00209 Index3 = index[2];
00210 return;
00211 }
00212
00213 void MagneticFieldGrid::putIndicesGetB(int Index1, int Index2, int Index3, float &Bx, float &By, float &Bz){
00214 BVector FieldEntry;
00215 FieldEntry = FieldValues.operator[](lineNumber(Index1, Index2, Index3));
00216 Bx = FieldEntry.bx();
00217 By = FieldEntry.by();
00218 Bz = FieldEntry.bz();
00219 return;
00220 }
00221
00222
00223 void MagneticFieldGrid::putIndGetCoord(int Index1, int Index2, int Index3, double &X1, double &X2, double &X3){
00224 int index[3] = {Index1, Index2, Index3};
00225 double pnt[3];
00226 switch (GridType){
00227 case 1:
00228 for (int i=0; i<3; ++i){
00229 pnt[i] = ReferencePoint[i] + BasicDistance0[i]*index[i];
00230 }
00231 break;
00232 case 2:
00233 for (int i=0; i<3; ++i){
00234 if (EasyCoordinate[i]){
00235 pnt[i] = ReferencePoint[i] + BasicDistance0[i]*index[i];
00236 }
00237 else {
00238 double stepSize = BasicDistance0[i];
00239 double offset = 0.0;
00240 for (int j=0; j<3; ++j){
00241 stepSize += BasicDistance1[i][j]*index[j];
00242 offset += BasicDistance2[i][j]*index[j];
00243 }
00244 pnt[i] = ReferencePoint[i] + offset + stepSize*index[i];
00245 }
00246 }
00247 break;
00248 case 3:
00249 for (int i=0; i<3; ++i){
00250 pnt[i] = ReferencePoint[i] + BasicDistance0[i]*index[i];
00251 }
00252 break;
00253 case 4:
00254 for (int i=0; i<3; ++i){
00255 if (EasyCoordinate[i]){
00256 pnt[i] = ReferencePoint[i] + BasicDistance0[i]*index[i];
00257 }
00258 else {
00259 double stepSize = BasicDistance0[i];
00260 double offset = 0.0;
00261 for (int j=0; j<3; ++j){
00262 stepSize += BasicDistance1[i][j]*index[j];
00263 offset += BasicDistance2[i][j]*index[j];
00264 }
00265 pnt[i] = ReferencePoint[i] + offset + stepSize*index[i];
00266 }
00267 }
00268 break;
00269 case 5:
00270 pnt[2] = ReferencePoint[2] + BasicDistance0[2]*index[2];
00271 pnt[1] = ReferencePoint[1] + BasicDistance0[1]*index[1];
00272 double sinPhi = sin(pnt[1]);
00273 double stepSize = RParAsFunOfPhi[0] + RParAsFunOfPhi[1]/sinPhi - RParAsFunOfPhi[2] - RParAsFunOfPhi[3]/sinPhi;
00274 stepSize = stepSize/(NumberOfPoints[0]-1);
00275 double startingPoint = RParAsFunOfPhi[2] + RParAsFunOfPhi[3]/sinPhi;
00276 pnt[0] = startingPoint + stepSize*index[0];
00277 break;
00278 }
00279 X1 = pnt[0];
00280 X2 = pnt[1];
00281 X3 = pnt[2];
00282 return;
00283 }
00284
00285 int MagneticFieldGrid::lineNumber(int Index1, int Index2, int Index3){
00286 return Index1*NumberOfPoints[1]*NumberOfPoints[2] + Index2*NumberOfPoints[2] + Index3;
00287 }
00288
00289 void MagneticFieldGrid::BVector::putB3(float Bx, float By, float Bz){
00290 B3[0] = Bx;
00291 B3[1] = By;
00292 B3[2] = Bz;
00293 return;
00294 }
00295
00296 float MagneticFieldGrid::BVector::bx(){ return B3[0]; }
00297
00298 float MagneticFieldGrid::BVector::by(){ return B3[1]; }
00299
00300 float MagneticFieldGrid::BVector::bz(){ return B3[2]; }