File indexing completed on 2025-01-18 09:55:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_FIELDS_H
0014 #define DD4HEP_FIELDS_H
0015
0016
0017 #include <DD4hep/NamedObject.h>
0018 #include <DD4hep/Objects.h>
0019
0020
0021 #include <vector>
0022 #include <map>
0023
0024
0025 namespace dd4hep {
0026
0027
0028 typedef Position Direction;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 class CartesianField: public Handle<NamedObject> {
0041 public:
0042 enum FieldType {
0043 UNKNOWN = 0, ELECTRIC = 0x1, MAGNETIC = 0x2, OVERLAY = 0x4,
0044 };
0045 typedef std::map<std::string, std::map<std::string, std::string> > Properties;
0046
0047
0048
0049
0050
0051
0052
0053 class TypedObject : public NamedObject {
0054 public:
0055
0056 int field_type { UNKNOWN };
0057
0058 using NamedObject::NamedObject;
0059 };
0060
0061
0062
0063
0064
0065
0066
0067 class Object: public TypedObject {
0068 public:
0069
0070 typedef std::vector<double> Coefficents;
0071
0072 Properties properties;
0073
0074 Object();
0075
0076 virtual ~Object();
0077
0078
0079
0080
0081
0082 virtual void fieldComponents(const double* pos, double* field) = 0;
0083 };
0084
0085
0086 CartesianField() = default;
0087
0088
0089 CartesianField(const CartesianField& e) = default;
0090
0091
0092 template <typename Q> CartesianField(const Handle<Q>& e) : Ref_t(e) {
0093 }
0094
0095
0096 CartesianField& operator=(const CartesianField& f) = default;
0097
0098
0099 int fieldType() const {
0100 return data<Object>()->field_type;
0101 }
0102
0103
0104 const char* type() const;
0105
0106
0107 bool changesEnergy() const;
0108
0109
0110 void value(const Position& pos, Direction& field) const;
0111
0112
0113 void value(const Position& pos, double* val) const;
0114
0115
0116 void value(const double* pos, double* val) const;
0117
0118
0119 Properties& properties() const;
0120 };
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 class OverlayedField: public Handle<NamedObject> {
0139 public:
0140 enum FieldType {
0141 ELECTRIC = CartesianField::ELECTRIC,
0142 MAGNETIC = CartesianField::MAGNETIC,
0143 OVERLAY = CartesianField::OVERLAY,
0144 };
0145 typedef std::map<std::string, std::string> PropertyValues;
0146 typedef std::map<std::string, PropertyValues> Properties;
0147
0148
0149
0150
0151
0152
0153
0154 class Object: public CartesianField::TypedObject {
0155 public:
0156 CartesianField electric;
0157 CartesianField magnetic;
0158 std::vector<CartesianField> electric_components;
0159 std::vector<CartesianField> magnetic_components;
0160
0161 Properties properties;
0162
0163 public:
0164
0165 Object();
0166
0167 virtual ~Object();
0168 };
0169
0170
0171 OverlayedField() = default;
0172
0173
0174 template <typename Q> OverlayedField(const Handle<Q>& e) : Ref_t(e) { }
0175
0176
0177 OverlayedField(const std::string& name);
0178
0179
0180 int fieldType() const {
0181 return data<Object>()->field_type;
0182 }
0183
0184
0185 bool changesEnergy() const;
0186
0187
0188 void add(CartesianField field);
0189
0190
0191 void combinedElectric(const Position& pos, double* field) const;
0192
0193
0194 Direction combinedElectric(const Position& pos) const {
0195 double field[3] = { 0e0, 0e0, 0e0 };
0196 combinedElectric(pos, field);
0197 return {field[0], field[1], field[2]};
0198 }
0199
0200
0201 void combinedElectric(const double* pos, double* field) const {
0202 combinedElectric(Position(pos[0], pos[1], pos[2]), field);
0203 }
0204
0205
0206 void combinedMagnetic(const Position& pos, double* field) const;
0207
0208
0209 Direction combinedMagnetic(const Position& pos) const {
0210 double field[3] = { 0e0, 0e0, 0e0 };
0211 combinedMagnetic({pos.X(), pos.Y(), pos.Z()}, field);
0212 return { field[0], field[1], field[2] };
0213 }
0214
0215
0216 void combinedMagnetic(const double* pos, double* field) const {
0217 combinedMagnetic(Position(pos[0], pos[1], pos[2]), field);
0218 }
0219
0220
0221 void electricField(const Position& pos, double* field) const;
0222
0223
0224 Direction electricField(const Position& pos) const {
0225 double field[3] = { 0e0, 0e0, 0e0 };
0226 electricField(pos, field);
0227 return { field[0], field[1], field[2] };
0228 }
0229
0230
0231 void electricField(const Position& pos, Direction& field) const {
0232 double fld[3] = { 0e0, 0e0, 0e0 };
0233 electricField(Position(pos.X(), pos.Y(), pos.Z()), fld);
0234 field = { fld[0], fld[1], fld[2] };
0235 }
0236
0237
0238 void electricField(const double* pos, double* field) const {
0239 field[0] = field[1] = field[2] = 0.0;
0240 CartesianField f = data<Object>()->electric;
0241 f.isValid() ? f.value(pos, field) : combinedElectric(pos, field);
0242 }
0243
0244
0245 void magneticField(const Position& pos, double* field) const;
0246
0247
0248 void magneticField(const double* pos, double* field) const {
0249 magneticField(Position(pos[0], pos[1], pos[2]), field);
0250 }
0251
0252
0253 void magneticField(const double* pos, Direction& field) const {
0254 double fld[3] = { 0e0, 0e0, 0e0 };
0255 magneticField(Position(pos[0], pos[1], pos[2]), fld);
0256 field = { fld[0], fld[1], fld[2] };
0257 }
0258
0259
0260 Direction magneticField(const Position& pos) const {
0261 double field[3] = { 0e0, 0e0, 0e0 };
0262 magneticField(pos, field);
0263 return { field[0], field[1], field[2] };
0264 }
0265
0266
0267 void electromagneticField(const Position& pos, double* field) const;
0268
0269
0270 void electromagneticField(const double* pos, double* val) const {
0271 electromagneticField(Position(pos[0], pos[1], pos[2]), val);
0272 }
0273
0274
0275 Properties& properties() const;
0276 };
0277 }
0278 #endif