1 package org.lcsim.detector.material;
2
3 import static java.lang.Math.log;
4 import static java.lang.Math.pow;
5 import static org.lcsim.units.clhep.PhysicalConstants.fine_structure_const;
6
7
8
9
10
11
12
13
14
15
16
17
18 public class MaterialElement implements IMaterial
19 {
20
21 protected String name;
22 protected double Z;
23 protected double A;
24 protected double density;
25 protected double temperature;
26 protected double pressure;
27
28
29 protected State state = defaultState;
30
31
32 protected double N;
33 protected double nuclearInteractionLength;
34 protected double nuclearInteractionLengthWithDensity;
35 protected double radiationLength;
36 protected double radiationLengthWithDensity;
37 protected double criticalEnergy;
38 protected double moliereRadius;
39
40
41
42
43 protected MaterialElement()
44 {
45 MaterialStore.getInstance().add(this);
46 }
47
48
49
50
51
52
53
54
55
56
57
58
59 public MaterialElement(String name, double Z, double A, double density, State state, double temperature, double pressure)
60 {
61
62 this.name = name;
63 this.Z = Z;
64 this.A = A;
65 this.density = density;
66 this.density = density;
67 this.state = state;
68 this.temperature = temperature;
69 this.pressure = pressure;
70
71
72 computeDerivedQuantities();
73
74
75 MaterialStore.getInstance().add(this);
76 }
77
78
79
80
81
82
83
84
85
86 public MaterialElement(String name, double Z, double A, double density)
87 {
88
89 this.name = name;
90 this.Z = Z;
91 this.A = A;
92 this.density = density;
93 this.density = density;
94 this.state = Unknown;
95 this.temperature = defaultTemperature;
96 this.pressure = defaultPressure;
97
98
99 computeDerivedQuantities();
100
101
102 MaterialStore.getInstance().add(this);
103 }
104
105 private void computeDerivedQuantities()
106 {
107 computeRadiationLength();
108 computeNuclearInteractionLength();
109 computeCriticalEnergy();
110 computeMoliereRadius();
111 }
112
113 protected void computeCriticalEnergy()
114 {
115 criticalEnergy = 2.66 * pow(getRadiationLength() * getZ() / getA(), 1.1);
116 }
117
118 protected void computeMoliereRadius()
119 {
120 moliereRadius = getRadiationLengthWithDensity() * 21.2052 / criticalEnergy;
121 }
122
123 protected void computeRadiationLength()
124 {
125 radiationLength = computeRadiationLengthTsai(A, Z);
126 radiationLengthWithDensity = radiationLength / getDensity();
127 }
128
129 protected void computeNuclearInteractionLength()
130 {
131 nuclearInteractionLength = computeNuclearInteractionLength(A, Z);
132 nuclearInteractionLengthWithDensity = nuclearInteractionLength / getDensity();
133 }
134
135 public double getA()
136 {
137 return A;
138 }
139
140 public double getDensity()
141 {
142 return density;
143 }
144
145 public String getName()
146 {
147 return name;
148 }
149
150 public double getNuclearInteractionLength()
151 {
152 return nuclearInteractionLength;
153 }
154
155 public double getRadiationLength()
156 {
157 return radiationLength;
158 }
159
160 public State getState()
161 {
162 return state;
163 }
164
165 public double getZ()
166 {
167 return Z;
168 }
169
170 public double getEffectiveNumberOfNucleons()
171 {
172 return N;
173 }
174
175 public double getMoliereRadius()
176 {
177 return moliereRadius;
178 }
179
180 public double getNuclearInteractionLengthWithDensity()
181 {
182 return nuclearInteractionLengthWithDensity;
183 }
184
185 public double getRadiationLengthWithDensity()
186 {
187 return radiationLengthWithDensity;
188 }
189
190 public static double computeRadiationLengthTsai(double A, double Z)
191 {
192 double azsq = fine_structure_const * Z;
193 azsq *= azsq;
194 double f = azsq * (1.0 / (1.0 + azsq) + 0.20206 - 0.0369 * azsq + 0.0083 * azsq * azsq - 0.002 * azsq * azsq * azsq);
195
196 double Lrad, LradP;
197 if (Z == 1)
198 {
199 Lrad = 5.31;
200 LradP = 6.144;
201 }
202 else if (Z == 2)
203 {
204 Lrad = 4.79;
205 LradP = 5.621;
206 }
207 else if (Z == 3)
208 {
209 Lrad = 4.74;
210 LradP = 5.805;
211 }
212 else if (Z == 4)
213 {
214 Lrad = 4.71;
215 LradP = 5.924;
216 }
217 else
218 {
219 Lrad = log(184.15 / pow(Z, 0.333333333));
220 LradP = log(1194.0 / pow(Z, 0.666666667));
221 }
222 double rlen = 716.408 * A / ((Z * Z * (Lrad - f) + Z * LradP));
223 return rlen;
224 }
225
226 public static double computeNuclearInteractionLength(double A, double Z)
227 {
228 double NIL = 0;
229 if (Z == 1)
230 {
231 if (A < 1.5)
232 {
233 NIL = 50.8;
234 }
235 else
236 {
237 NIL = 54.7;
238 }
239 }
240 else if (Z == 2)
241 {
242 NIL = 65.2;
243 }
244 else
245 {
246 NIL = 40.8 * pow(A, 0.289);
247 }
248
249 return NIL;
250 }
251
252 public double getTemperature()
253 {
254 return temperature;
255 }
256
257 public double getPressure()
258 {
259 return pressure;
260 }
261
262 public String toString()
263 {
264 StringBuffer sb = new StringBuffer();
265 sb.append(getName() + '\n');
266 sb.append("D = " + getDensity() + " {g/cm3} ; ");
267 sb.append("A = " + getA() + "; ");
268 sb.append("Z = " + getZ());
269 sb.append('\n');
270 sb.append("LamdaT = " + getNuclearInteractionLength() + " {g/cm2}; ");
271 sb.append("LamdaT = " + getNuclearInteractionLengthWithDensity() + " {cm}; ");
272 sb.append("X0 = " + getRadiationLength() + " {g/cm2}; ");
273 sb.append("X0 = " + getRadiationLengthWithDensity() + " {cm}; ");
274 sb.append("Rm = " + getMoliereRadius() + " {cm} ");
275 sb.append('\n');
276
277 return sb.toString();
278 }
279 }