File indexing completed on 2024-04-06 12:22:32
0001
0002
0003
0004
0005
0006 #include "TrapezoidalCartesianMFGrid.h"
0007 #include "MagneticField/Interpolation/interface/binary_ifstream.h"
0008 #include "LinearGridInterpolator3D.h"
0009 #include "MagneticField/VolumeGeometry/interface/MagExceptions.h"
0010 #include <iostream>
0011
0012
0013
0014 using namespace std;
0015
0016 TrapezoidalCartesianMFGrid::TrapezoidalCartesianMFGrid(binary_ifstream& inFile, const GloballyPositioned<float>& vol)
0017 : MFGrid3D(vol), increasingAlongX(false), convertToLocal(true) {
0018
0019
0020
0021
0022
0023
0024 GlobalVector localXDir(frame().toGlobal(LocalVector(1, 0, 0)));
0025 GlobalVector localYDir(frame().toGlobal(LocalVector(0, 1, 0)));
0026
0027 if (localXDir.dot(GlobalVector(1, 0, 0)) > 0.999999 && localYDir.dot(GlobalVector(0, 1, 0)) > 0.999999) {
0028
0029 convertToLocal = false;
0030 } else if (localXDir.dot(GlobalVector(0, 1, 0)) > 0.999999 && localYDir.dot(GlobalVector(1, 0, 0)) > 0.999999) {
0031
0032 convertToLocal = true;
0033 } else {
0034 convertToLocal = true;
0035
0036 cout << "WARNING: TrapezoidalCartesianMFGrid: unexpected orientation: x: " << localXDir << " y: " << localYDir
0037 << endl;
0038 }
0039
0040 int n1, n2, n3;
0041 inFile >> n1 >> n2 >> n3;
0042 double xref, yref, zref;
0043 inFile >> xref >> yref >> zref;
0044 double step1, step2, step3;
0045 inFile >> step1 >> step2 >> step3;
0046
0047 double BasicDistance1[3][3];
0048 double BasicDistance2[3][3];
0049 bool easya, easyb, easyc;
0050
0051 inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
0052 inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
0053 inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
0054 inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
0055 inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
0056 inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
0057 inFile >> easya >> easyb >> easyc;
0058
0059 vector<BVector> fieldValues;
0060 float Bx, By, Bz;
0061 int nLines = n1 * n2 * n3;
0062 fieldValues.reserve(nLines);
0063 for (int iLine = 0; iLine < nLines; ++iLine) {
0064 inFile >> Bx >> By >> Bz;
0065 if (convertToLocal) {
0066
0067 Vector3DBase<double, LocalTag> lB = frame().toLocal(Vector3DBase<double, GlobalTag>(Bx, By, Bz));
0068 fieldValues.push_back(BVector(lB.x(), lB.y(), lB.z()));
0069
0070 } else {
0071 fieldValues.push_back(BVector(Bx, By, Bz));
0072 }
0073 }
0074
0075 string lastEntry;
0076 inFile >> lastEntry;
0077 if (lastEntry != "complete") {
0078 cout << "ERROR during file reading: file is not complete" << endl;
0079 }
0080
0081
0082
0083
0084
0085
0086 int nx, ny;
0087 double stepx, stepy, stepz;
0088 double dstep, offset;
0089 if (!easya && easyb && easyc) {
0090
0091 increasingAlongX = true;
0092 nx = n1;
0093 ny = n2;
0094 stepx = step1;
0095 stepy = step2;
0096 stepz = step3;
0097 dstep = BasicDistance1[0][1];
0098 offset = BasicDistance2[0][1];
0099 } else if (easya && !easyb && easyc) {
0100
0101 increasingAlongX = false;
0102 nx = n2;
0103 ny = n1;
0104 stepx = step2;
0105 stepy = step1;
0106 stepz = -step3;
0107 dstep = BasicDistance1[1][0];
0108 offset = BasicDistance2[1][0];
0109
0110 } else {
0111
0112 throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first or second coordinate");
0113 }
0114
0115 double a = stepx * (nx - 1);
0116 double b = a + dstep * (ny - 1) * (nx - 1);
0117 double h = stepy * (ny - 1);
0118 double delta = -offset * (ny - 1);
0119 double baMinus1 = dstep * (ny - 1) / stepx;
0120
0121 GlobalPoint grefp(xref, yref, zref);
0122 LocalPoint lrefp = frame().toLocal(grefp);
0123
0124 if (fabs(baMinus1) > 0.000001) {
0125 double b_over_a = 1 + baMinus1;
0126 double a1 = delta / baMinus1;
0127
0128 #ifdef DEBUG_GRID
0129 cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
0130 cout << "Global origin " << grefp << endl;
0131 cout << "Local origin " << lrefp << endl;
0132 cout << "a1 = " << a1 << endl;
0133 #endif
0134
0135
0136
0137 double x0 = lrefp.x() + a1;
0138 double y0 = lrefp.y() + h / 2.;
0139 mapping_ = Trapezoid2RectangleMappingX(x0, y0, b_over_a, h);
0140 } else {
0141 mapping_ = Trapezoid2RectangleMappingX(0, 0, delta / h);
0142 }
0143
0144
0145 double xrec, yrec;
0146 mapping_.rectangle(lrefp.x(), lrefp.y(), xrec, yrec);
0147
0148 Grid1D gridX(xrec, xrec + (a + b) / 2., nx);
0149 Grid1D gridY(yrec, yrec + h, ny);
0150 Grid1D gridZ(lrefp.z(), lrefp.z() + stepz * (n3 - 1), n3);
0151
0152 #ifdef DEBUG_GRID
0153 cout << " GRID X range: local " << gridX.lower() << " - " << gridX.upper()
0154 << " global: " << (frame().toGlobal(LocalPoint(gridX.lower(), 0, 0))).y() << " - "
0155 << (frame().toGlobal(LocalPoint(gridX.upper(), 0, 0))).y() << endl;
0156
0157 cout << " GRID Y range: local " << gridY.lower() << " - " << gridY.upper()
0158 << " global: " << (frame().toGlobal(LocalPoint(0, gridY.lower(), 0))).x() << " - "
0159 << (frame().toGlobal(LocalPoint(0, gridY.upper(), 0))).x() << endl;
0160
0161 cout << " GRID Z range: local " << gridZ.lower() << " - " << gridZ.upper()
0162 << " global: " << (frame().toGlobal(LocalPoint(0, 0, gridZ.lower()))).z() << " "
0163 << (frame().toGlobal(LocalPoint(0, 0, gridZ.upper()))).z() << endl;
0164 #endif
0165
0166 if (increasingAlongX) {
0167 grid_ = GridType(gridX, gridY, gridZ, fieldValues);
0168 } else {
0169
0170
0171
0172
0173 grid_ = GridType(gridY, gridX, gridZ, fieldValues);
0174 }
0175
0176 #ifdef DEBUG_GRID
0177 dump();
0178 #endif
0179 }
0180
0181 void TrapezoidalCartesianMFGrid::dump() const {
0182 cout << endl << "Dump of TrapezoidalCartesianMFGrid" << endl;
0183
0184
0185 cout << "Number of points from Grid1D " << grid_.grida().nodes() << " " << grid_.gridb().nodes() << " "
0186 << grid_.gridc().nodes() << endl;
0187
0188
0189
0190 cout << "Reference Point from Grid1D " << grid_.grida().lower() << " " << grid_.gridb().lower() << " "
0191 << grid_.gridc().lower() << endl;
0192
0193
0194
0195 cout << "Basic Distance from Grid1D " << grid_.grida().step() << " " << grid_.gridb().step() << " "
0196 << grid_.gridc().step() << endl;
0197
0198 cout << "Dumping " << grid_.data().size() << " field values " << endl;
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 }
0214
0215 MFGrid::LocalVector TrapezoidalCartesianMFGrid::uncheckedValueInTesla(const LocalPoint& p) const {
0216 double xrec, yrec;
0217 mapping_.rectangle(p.x(), p.y(), xrec, yrec);
0218
0219
0220
0221
0222
0223 LinearGridInterpolator3D interpol(grid_);
0224
0225 if (!increasingAlongX) {
0226 std::swap(xrec, yrec);
0227
0228
0229
0230 }
0231
0232 return LocalVector(interpol.interpolate(xrec, yrec, p.z()));
0233 }
0234
0235 void TrapezoidalCartesianMFGrid::toGridFrame(const LocalPoint& p, double& a, double& b, double& c) const {
0236 if (increasingAlongX) {
0237 mapping_.rectangle(p.x(), p.y(), a, b);
0238 } else {
0239 mapping_.rectangle(p.x(), p.y(), b, a);
0240 }
0241
0242 c = p.z();
0243 }
0244
0245 MFGrid::LocalPoint TrapezoidalCartesianMFGrid::fromGridFrame(double a, double b, double c) const {
0246 double xtrap, ytrap;
0247 if (increasingAlongX) {
0248 mapping_.trapezoid(a, b, xtrap, ytrap);
0249 } else {
0250 mapping_.trapezoid(b, a, xtrap, ytrap);
0251 }
0252 return LocalPoint(xtrap, ytrap, c);
0253 }