ATLAS Offline Software
Loading...
Searching...
No Matches
ElementModelScaleSag.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include <stdexcept>
7#include <utility>
8
9using namespace NswAsBuilt;
10namespace {
11 constexpr double DivBy1k = 1.e-3;
12}
13//===============================================================================
15: m_lenX(lenX), m_lenY(lenY), m_defo0(std::move(defo0))
16{ }
17
22
23 if (!parvec.transformCacheValid) {
24 throw std::runtime_error("Should call Element::cacheTransforms() first");
25 }
26
27 // Apply the deformation component
28 /*
29 * old-style (reference) implementation: not optimized
30 for (int i=0; i< local.cols(); ++i) {
31 applyDeformation(parvec, local.col(i));
32 }
33 */
34 // Eigen-style implementation: optimized
35 applyDeformation2(parvec, local);
36
37 // Apply the rigid component
38 local = (parvec.transformCache * local).eval(); // Needs eval to avoid aliasing (?)
39}
40
45 const auto& pars = parvec.parameters;
46 parvec.transformCache
47 = Eigen::Translation3d(pars[X], pars[Y], pars[Z])
48 * Eigen::AngleAxisd(pars[THZ], Eigen::Vector3d::UnitZ())
49 * Eigen::AngleAxisd(pars[THY], Eigen::Vector3d::UnitY())
50 * Eigen::AngleAxisd(pars[THX], Eigen::Vector3d::UnitX());
51 parvec.transformCacheValid = true;
52}
53
54
55//===============================================================================
56// Helper methods to convert parameter index to string representation
58{
59 if (parname == "x") return parameter_t::X;
60 if (parname == "y") return parameter_t::Y;
61 if (parname == "z") return parameter_t::Z;
62 if (parname == "thx") return parameter_t::THX;
63 if (parname == "thy") return parameter_t::THY;
64 if (parname == "thz") return parameter_t::THZ;
65 if (parname == "egx") return parameter_t::EGX;
66 if (parname == "egy") return parameter_t::EGY;
67 if (parname == "egz") return parameter_t::EGZ;
68 if (parname == "sagx") return parameter_t::SAGX;
69 if (parname == "sagy") return parameter_t::SAGY;
70 if (parname == "degx") return parameter_t::DEGX;
71 if (parname == "degy") return parameter_t::DEGY;
72 if (parname == "pgx") return parameter_t::PGX;
73 if (parname == "pgy") return parameter_t::PGY;
74 if (parname == "dsagx") return parameter_t::DSAGX;
75 if (parname == "dsagy") return parameter_t::DSAGY;
76 throw std::runtime_error("Invalid parameter name "+parname);
77}
78
79
80//===============================================================================
82{
83 switch (ipar) {
84 case X: return "x";
85 case Y: return "y";
86 case Z: return "z";
87 case THX: return "thx";
88 case THY: return "thy";
89 case THZ: return "thz";
90 case EGX: return "egx";
91 case EGY: return "egy";
92 case EGZ: return "egz";
93 case SAGX: return "sagx";
94 case SAGY: return "sagy";
95 case DEGX: return "degx";
96 case DEGY: return "degy";
97 case PGX: return "pgx";
98 case PGY: return "pgy";
99 case DSAGX: return "dsagx";
100 case DSAGY: return "dsagy";
101 default: throw std::runtime_error("Invalid parameter");
102 }
103}
104
105//===============================================================================
106// The basic ingredients of the calculation
107Amg::Vector3D ElementModelScaleSag::DEg( double egx, double egy, double egz, const Amg::Vector3D& d0)
108{
109 // Calculate thermal expansion
110 return d0.array() * Eigen::Array3d{egx*DivBy1k, egy*DivBy1k, egz*DivBy1k};
111}
112
113
114//===============================================================================
116{
117 // Calculate sag along X
118 double r = d0[1]/(0.5*m_lenY);
119 // delta is sagx at y=y0, 0 at y=y0+-0.5*_lenY
120 double delta = sagx * (1. - r*r);
121 return Amg::Vector3D(delta, 0., 0.);
122}
123
124
125//===============================================================================
127{
128 // Calculate sag along Y
129 double r = d0[0]/(0.5*m_lenX);
130 // delta is sagY at x=x0, 0 at x=x0+-0.5*_lenX
131 double delta = sagy * (1. - r*r);
132 return Amg::Vector3D(0., delta, 0.);
133}
134
135
136//===============================================================================
138{
139 // Calculate sag along X
140 double sagx = dsagx * d0[0]/(0.5*m_lenX);
141 double r = d0[1]/(0.5*m_lenY);
142 // delta is sagx at y=y0, 0 at y=y0+-0.5*_lenY
143 double delta = sagx * (1. - r*r);
144 return Amg::Vector3D(delta, 0., 0.);
145}
146
147
148//===============================================================================
150{
151 // Calculate dsag along Y
152 double sagy = dsagy * d0[1]/(0.5*m_lenY);
153 double r = d0[0]/(0.5*m_lenX);
154 // delta is sagY at x=x0, 0 at x=x0+-0.5*_lenX
155 double delta = sagy * (1. - r*r);
156 return Amg::Vector3D(0., delta, 0.);
157}
158
159
160//===============================================================================
162{
163 double egx_eff = degx * d0[1]/(0.5*m_lenY);
164 double delta = egx_eff * d0[0]*DivBy1k;
165 return Amg::Vector3D(delta, 0., 0.);
166}
167
168
169//===============================================================================
171{
172 double egy_eff = degy * d0[0]/(0.5*m_lenX);
173 double delta = egy_eff * d0[1]*DivBy1k;
174 return Amg::Vector3D(0., delta, 0.);
175}
176
177
178//===============================================================================
180{
181 double delta = pgx * d0[1]/(0.5*m_lenY);
182 return Amg::Vector3D(delta, 0., 0.);
183}
184
185
186//===============================================================================
188{
189 double delta = pgy * d0[0]/(0.5*m_lenX);
190 return Amg::Vector3D(0., delta, 0.);
191}
192
193
194//===============================================================================
195void ElementModelScaleSag::applyDeformation(const ParameterVector& parvec, Eigen::Ref<Amg::Vector3D> local) const
196{
197 // Applies the deformation to the set of local vectors given as argument
198 // This old-style implementation is the reference implementation
199 Amg::Vector3D d0 = local - m_defo0;
200 local = local
201 + DEg(parvec[EGX], parvec[EGY], parvec[EGZ], d0)
202 + DSagX(parvec[SAGX], d0)
203 + DSagY(parvec[SAGY], d0)
204 + DDSagX(parvec[DSAGX], d0)
205 + DDSagY(parvec[DSAGY], d0)
206 + DDegX(parvec[DEGX], d0)
207 + DDegY(parvec[DEGY], d0)
208 + DPgX(parvec[PGX], d0)
209 + DPgY(parvec[PGY], d0)
210 ;
211}
212
213
214//===============================================================================
216{
217 // Applies the deformation to the set of local vectors given as argument
218 // This implementation uses Eigen-style algebra (does the same as the method applyDeformation above, but benefits from Eigen's optimizations)
219
220 // Temporaries allocated on the stack
221 // d0 = local - defo0
222 VectorSet d0 = local.colwise() - m_defo0;
223
224 // r = {d0.x/(0.5*lenX), d0.y/(0.5*lenY), (d0.z)}
225 // r.x is (-1,+1) at X=(-0.5*lenX, 0.5*lenX), similarly for Y
226 VectorSet r = d0.array().colwise() * Eigen::Array3d{1.0/(0.5*m_lenX), 1.0/(0.5*m_lenY), 1.0};
227
228 // p2.{x,y,z} = 1 - r.{x,y,z}^2
229 // p2.x = 1 at r.x = 0 and p2.x = 0 at r.x = +-0.5*lenX, similarly for Y
230 VectorSet p2 = -1.0*(r.array().square().colwise() - Eigen::Array3d::Ones());
231
232 double egx = parvec[EGX];
233 double egy = parvec[EGY];
234 double egz = parvec[EGZ];
235 double sagx = parvec[SAGX];
236 double sagy = parvec[SAGY];
237 double dsagx = parvec[DSAGX];
238 double dsagy = parvec[DSAGY];
239 double degx = parvec[DEGX];
240 double degy = parvec[DEGY];
241 double pgx = parvec[PGX];
242 double pgy = parvec[PGY];
243
244 // EGX, EGY, EGZ:
245 // d0.{x,y,z} * {egx, egy, egz}
246 local.array() += d0.array().colwise() * Eigen::Array3d{egx*DivBy1k, egy*DivBy1k, egz*DivBy1k};
247
248 // SAGX, SAGY:
249 // p2.{y,x} * {sagx, sagy}
250 local.topRows<2>().array() += p2.topRows<2>().array().colwise().reverse().colwise() * Eigen::Array2d{sagx, sagy};
251
252 // DSAGX, DSAGY:
253 // p2.{y,x} * {dsagx*r.x, dsagy*r.y}
254 local.topRows<2>().array() += (p2.topRows<2>().array().colwise().reverse() * r.topRows<2>().array()).colwise() * Eigen::Array2d{dsagx, dsagy};
255
256 // DEGX, DEGY:
257 // d0.{x,y} * {degx*r.y, degy*r.x}
258 local.topRows<2>().array() += (d0.topRows<2>().array() * r.topRows<2>().array().colwise().reverse()).colwise() * Eigen::Array2d{degx*DivBy1k, degy*DivBy1k};
259
260 // PGX, PGY:
261 // r.{y,x} * {pgx, pgy}
262 local.topRows<2>().array() += r.topRows<2>().array().colwise().reverse().colwise() * Eigen::Array2d{pgx, pgy};
263}
264
virtual ipar_t getParameterIndex(const std::string &parname) const override
Amg::Vector3D DDSagX(double dsagx, const Amg::Vector3D &d0) const
void applyDeformation2(const ParameterVector &parvec, VectorSetRef local) const
virtual std::string getParameterName(ipar_t ipar) const override
Amg::Vector3D DPgX(double pgx, const Amg::Vector3D &d0) const
Amg::Vector3D DPgY(double pgy, const Amg::Vector3D &d0) const
static Amg::Vector3D DEg(double egx, double egy, double egz, const Amg::Vector3D &d0)
virtual void transform(const ParameterVector &parvec, VectorSetRef local) const override
Transform a set of vectors expressed in local frame, stored in a matrix.
Amg::Vector3D DDegY(double degy, const Amg::Vector3D &d0) const
Amg::Vector3D DDSagY(double dsagy, const Amg::Vector3D &d0) const
void applyDeformation(const ParameterVector &parvec, Eigen::Ref< Amg::Vector3D > local) const
virtual void cacheTransform(ParameterVector &parvec) const override
Cache the rigid component of this deformation model.
Amg::Vector3D DSagY(double sagy, const Amg::Vector3D &d0) const
Amg::Vector3D DSagX(double sagx, const Amg::Vector3D &d0) const
Amg::Vector3D DDegX(double degx, const Amg::Vector3D &d0) const
Eigen::Ref< VectorSet > VectorSetRef
Eigen::Matrix< double, 3, Eigen::Dynamic, Eigen::ColMajor|Eigen::AutoAlign, 3, 5 > VectorSet
STL class.
int r
Definition globals.cxx:22
Eigen::Matrix< double, 3, 1 > Vector3D
STL namespace.