File indexing completed on 2025-01-18 09:13:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <DD4hep/Fields.h>
0015 #include <DD4hep/Printout.h>
0016 #include <DD4hep/InstanceCount.h>
0017 #include <DD4hep/detail/Handle.inl>
0018
0019 using namespace dd4hep;
0020
0021 typedef CartesianField::Object CartesianFieldObject;
0022 DD4HEP_INSTANTIATE_HANDLE(CartesianFieldObject);
0023
0024 typedef OverlayedField::Object OverlayedFieldObject;
0025 DD4HEP_INSTANTIATE_HANDLE(OverlayedFieldObject);
0026
0027 namespace {
0028 void calculate_combined_field(std::vector<CartesianField>& v, const Position& pos, double* field) {
0029 for (const auto& i : v ) i.value(pos, field);
0030 }
0031 }
0032
0033
0034 CartesianField::Object::Object() : TypedObject() {
0035
0036 field_type = UNKNOWN;
0037 InstanceCount::increment(this);
0038 }
0039
0040
0041 CartesianField::Object::~Object() {
0042 InstanceCount::decrement(this);
0043 }
0044
0045
0046 const char* CartesianField::type() const {
0047 return m_element->GetTitle();
0048 }
0049
0050
0051 bool CartesianField::changesEnergy() const {
0052 return ELECTRIC == (fieldType() & ELECTRIC);
0053 }
0054
0055
0056 CartesianField::Properties& CartesianField::properties() const {
0057 return data<Object>()->properties;
0058 }
0059
0060
0061 void CartesianField::value(const Position& pos, Direction& field) const {
0062 double fld[3] = {0e0, 0e0, 0e0};
0063 double position[3] = {pos.X(), pos.Y(), pos.Z()};
0064 data<Object>()->fieldComponents(position, fld);
0065 field = Direction(fld[0], fld[1], fld[2]);
0066 }
0067
0068
0069 void CartesianField::value(const Position& pos, double* field) const {
0070 double position[3] = {pos.X(), pos.Y(), pos.Z()};
0071 data<Object>()->fieldComponents(position, field);
0072 }
0073
0074
0075 void CartesianField::value(const double* pos, double* field) const {
0076 data<Object>()->fieldComponents(pos, field);
0077 }
0078
0079
0080 OverlayedField::Object::Object() : TypedObject(), electric(), magnetic()
0081 {
0082 field_type = CartesianField::OVERLAY;
0083 InstanceCount::increment(this);
0084 }
0085
0086
0087 OverlayedField::Object::~Object() {
0088 InstanceCount::decrement(this);
0089 }
0090
0091
0092 OverlayedField::OverlayedField(const std::string& nam) : Ref_t() {
0093 auto* obj = new Object();
0094 assign(obj, nam, "overlay_field");
0095 obj->field_type = CartesianField::OVERLAY;
0096 }
0097
0098
0099 OverlayedField::Properties& OverlayedField::properties() const {
0100 return data<Object>()->properties;
0101 }
0102
0103
0104 bool OverlayedField::changesEnergy() const {
0105 int field = data<Object>()->field_type;
0106 return CartesianField::ELECTRIC == (field & CartesianField::ELECTRIC);
0107 }
0108
0109
0110 void OverlayedField::add(CartesianField field) {
0111 if (field.isValid()) {
0112 Object* o = data<Object>();
0113 if ( o ) {
0114 int typ = field.fieldType();
0115 bool isEle = field.ELECTRIC == (typ & field.ELECTRIC);
0116 bool isMag = field.MAGNETIC == (typ & field.MAGNETIC);
0117 if (isEle) {
0118 std::vector < CartesianField > &v = o->electric_components;
0119 v.emplace_back(field);
0120 o->field_type |= field.ELECTRIC;
0121 o->electric = (v.size() == 1) ? field : CartesianField();
0122 }
0123 if (isMag) {
0124 std::vector < CartesianField > &v = o->magnetic_components;
0125 v.emplace_back(field);
0126 o->field_type |= field.MAGNETIC;
0127 o->magnetic = (v.size() == 1) ? field : CartesianField();
0128 }
0129 if ( isMag || isEle ) {
0130 return;
0131 }
0132 except("OverlayedField","add: Attempt to add an unknown field type.");
0133 }
0134 except("OverlayedField","add: Attempt to add an invalid object.");
0135 }
0136 except("OverlayedField","add: Attempt to add an invalid field.");
0137 }
0138
0139
0140 void OverlayedField::magneticField(const Position& pos, double* field) const {
0141 if ( isValid() ) {
0142 field[0] = field[1] = field[2] = 0.0;
0143 auto* obj = data<Object>();
0144 CartesianField f = obj->magnetic;
0145 if ( f.isValid() )
0146 f.value(pos, field);
0147 else
0148 calculate_combined_field(obj->magnetic_components, pos, field);
0149 return;
0150 }
0151 except("OverlayedField","add: Attempt to add an invalid field.");
0152 }
0153
0154
0155 void OverlayedField::combinedElectric(const Position& pos, double* field) const {
0156 field[0] = field[1] = field[2] = 0.;
0157 calculate_combined_field(data<Object>()->electric_components, pos, field);
0158 }
0159
0160
0161 void OverlayedField::combinedMagnetic(const Position& pos, double* field) const {
0162 field[0] = field[1] = field[2] = 0.;
0163 calculate_combined_field(data<Object>()->magnetic_components, pos, field);
0164 }
0165
0166
0167 void OverlayedField::electromagneticField(const Position& pos, double* field) const {
0168 Object* o = data<Object>();
0169 field[0] = field[1] = field[2] = 0.;
0170 calculate_combined_field(o->electric_components, pos, field);
0171 calculate_combined_field(o->magnetic_components, pos, field + 3);
0172 }