This repository has been archived by the owner on Mar 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 55
/
Material.java
456 lines (408 loc) · 13.3 KB
/
Material.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/*******************************************************************************
* Copyright (c) 2012, 2014 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation - Jay Jay Billings,
* Jordan H. Deyton, Dasha Gorin, Alexander J. McCaskey, Taylor Patterson,
* Claire Saunders, Matthew Wang, Anna Wojtowicz
*******************************************************************************/
package org.eclipse.ice.datastructures.form;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.ice.datastructures.form.MaterialStack;
/**
* This class represents physical Materials.
*
* All materials have a name and a size. Other properties whose values are
* normally double precision floating point numbers are stored as properties.
* The list of properties available for a material can be retrieved by calling
* getProperties() and the list of properties can be modified by calling
* get/setProperty().
*
* Materials can also be composed of other materials called "Components." Each
* Material that comprises the the composite Materials should be set using the
* addComponent() operation and the whole list of components can get retrieved
* with the getComponents() operation. ICE makes no attempt to correct
* mismatched sizes, etc. between components and composites.
*
* @author Jay Jay Billings
*
*/
@XmlRootElement(name = "Material")
@XmlAccessorType(XmlAccessType.FIELD)
public class Material implements Cloneable, Comparable<Material> {
// Strings for property names.
/**
* The atomic mass of the material. This is the name of that property.
*/
public static final String ATOMIC_MASS = "M (amu)";
/**
* The Atomic density of the material. This is the name of that property.
*/
public static final String ATOMIC_DENSITY = "Dens (at/nm3)";
/**
* The density (in g/cm^3) of the material. This is the name of that
* property.
*/
public static final String DENSITY = "Dens (g/cm3)";
/**
* The Bound coherent scattering length of the material. This is the name of
* that property.
*/
public static final String BOUND_COHERENT_SCATTERING_LENGTH = "Coh b";
/**
* The Bound incoherent scattering length of the material. This is the name
* of that property.
*/
public static final String BOUND_INCOHERENT_SCATTERING_LENGTH = "Inc b";
/**
* The bound coherent scattering cross section of the material. This is the
* name of that property.
*/
public static final String BOUND_COHERENT_SCATTERING_CROSS_SECTION = "Coh xs";
/**
* The bound incoherent scattering cross section of the material. This is
* the name of that property.
*/
public static final String BOUND_INCOHERENT_SCATTERING_CROSS_SECTION = "Inc xs";
/**
* The scattering length density in (A^-2) of the material. This is the name
* of that property.
*/
public static final String SCATTERING_LENGTH_DENSITY = "Scattering Length Density (A^-2)";
/**
* The scattering cross section in (A^-2) of the material. This is the name
* of that property.
*/
public static final String SCATTERING_CROSS_SECTION = "Scattering Cross Section";
/**
* The absorption cross section of the material. This is the name of that
* property.
*/
public static final String ABSORPTION_CROSS_SECTION = "Abs xs";
/**
* The name of the material.
*/
private String name;
/**
* The key-value pair map of properties for this material.
*/
private HashMap<String, Double> properties;
/**
* The list of components that comprise this material.
*/
//@XmlElement(name = "Material")
private List<MaterialStack> components;
/**
* The constructor.
*/
public Material() {
name = "";
properties = new HashMap<String, Double>();
components = new ArrayList<MaterialStack>();
}
/**
* Get the name of the material.
*
* @return The name
*/
public String getName() {
return name;
}
/**
* Set the name of the material
*
* @param matName
* The name of the material. There are no restrictions on what it
* may be.
*/
public void setName(String matName) {
name = matName;
}
/**
* This operation returns the value of the material property with the given
* name.
*
* @param key
* The key/name of the property whose value should be returned
* @return the value or 0.0 if this value is not in the map, but never null.
*/
public double getProperty(String key) {
double value = 0.0;
if (properties.containsKey(key)) {
value = properties.get(key);
}
return value;
}
/**
* This operation sets value of the material property with the given name.
*
* @param key
* The key/name of the property whose value should be set
* @param value
* the property
*/
public void setProperty(String key, double value) {
properties.put(key, value);
}
/**
* This operation removes a property from the material's properties list.
*
* @param key
* The name of the property that should be removed.
*/
public void removeProperty(String key) {
if (properties.containsKey(key)) {
properties.remove(key);
}
}
/**
* This operation returns the full set of properties for this material.
*
* @return A map of the properties. Changing this map will not change the
* internal properties of the material.
*/
public Map<String, Double> getProperties() {
return new HashMap<String, Double>(properties);
}
/**
* This operation returns the list of materials that compose this material.
*
* @return The list of Materials that make up this one. Changing this list
* will not affect list stored by the Material.
*/
public List<MaterialStack> getComponents() {
return new ArrayList<MaterialStack>(components);
}
/**
* This operation adds a component to this material, effectively marking
* this Material as being a composite of others. It tries to see if the
* material added already exists in this material's components, and if so
* just increments the amount. Otherwise, adds the new material as a
* material stack with an amount of 1.
*
* @param component
* The material that is a component of this material to be added.
*/
public void addComponent(Material component) {
// Do not want to make a new stack if the material already is a
// component
// of this one.
boolean added = false;
// Iterate over stacks to try to find the material
for (MaterialStack stack : components) {
Material m = stack.getMaterial();
if (component.equals(m)) {
// Add the material
stack.setAmount(stack.getAmount() + 1);
added = true;
break;
}
}
// Not found already, create a new material stack and add to components
if (!added) {
components.add(new MaterialStack(component, 1));
}
}
/**
* This operation adds a component to this material, effectivly marking this
* Material as being a composite of others. It tries to see if the material
* stack given is a stack of an existing compoenent of this material, and if
* so updates the amount for that stack. Otherwise, adds the new stack to
* the list of components.
*
* @param stack
*/
public void addComponent(MaterialStack stack) {
// Do not want to add a new stack if the material in the stack already
// is a component of this one.
boolean added = false;
Material mat = stack.getMaterial();
// Iterate over stacks to try to find the material that fits the new
// stack
for (MaterialStack matStack : components) {
Material m = matStack.getMaterial();
if (mat.equals(m)) {
// Add the stack amount to the existing stack
matStack.setAmount(matStack.getAmount() + stack.getAmount());
added = true;
break;
}
}
// Not found already, then just add the stack to the components
if (!added) {
components.add(stack);
}
}
/**
* This operation overrides Object.equals() to tailor its behavior for
* materials.
*
* @param other
* The other Object to compare against this one
* @return true if they are equal, false otherwise
*/
public boolean equals(Object other) {
// Local Declarations
boolean retVal = false;
// Don't inspect the input if it is not a Material or if it is null
if (other != null && other instanceof Material) {
// Check the reference
if (this == other) {
retVal = true;
} else {
Material otherMaterial = (Material) other;
// Check each member
retVal = this.name.equals(otherMaterial.name)
&& this.components.equals(otherMaterial.components)
&& this.properties.equals(otherMaterial.properties);
}
}
return retVal;
}
/**
* This operation overrides Object.hashCode to return the proper hash for
* Materials.
*
* @return the hash
*/
@Override
public int hashCode() {
// Local Declarations
int hash = 8;
// Compute the hash code
hash = 31 * hash + name.hashCode();
hash = 31 * hash + properties.hashCode();
hash = 31 * hash + components.hashCode();
return hash;
}
/**
* This operation copies the content of the incoming material into this
* material.
*
* @param material
* the material to copy
*/
public void copy(Material material) {
// Don't copy the input if it is not a Material or if it is null
if (material != null && material != this) {
this.name = material.name;
this.properties = new HashMap<String, Double>(material.properties);
this.components = new ArrayList<MaterialStack>(material.components);
}
}
/**
* Gets the number before the element denoting which isotope or form of an
* element or compound this material represents.
*
* @return The number of this isotope, as an int. Will return 0 if this is a
* pure element (no number preceding its name)
*/
public int getIsotopicNumber() {
// Get an empty string to build off of
String numStr = "";
// Iterate over the characters in the name to pull out the isotope
// number.
// it is assumed that the name will follow the format xxxYy, where x is
// a digit and y is a letter.
for (int i = 0; i < name.length(); i++) {
if (Character.isDigit(name.charAt(i))) {
numStr += name.charAt(i);
} else {
break;
}
}
// Get the isotope number in int form. If no x values in name, return 0.
int retVal;
if (numStr.equals("")) {
retVal = 0;
} else {
retVal = Integer.parseInt(numStr);
}
return retVal;
}
/**
* Gets the elemental or compound name for this material. Note- this will
* return the same string for two isotopes of the same element.
*
* @return A String containing the name of the element or compound that this
* material represents.
*/
public String getElementalName() {
// A string to build on
String nameStr = "";
// Iterate over the name of the material, it is assumed that the
// name follow the form xxxYy, where x is a digit and y is a letter.
for (int i = name.length() - 1; i >= 0; i--) {
if (Character.isLetter(name.charAt(i))) {
nameStr = name.charAt(i) + nameStr;
} else {
break;
}
}
return nameStr;
}
/**
* This operation clones the material and creates a completely new material
* with the same information.
*
* @return The clone
*/
public Object clone() {
// Create a new Material, copy everything into it and return it
Material clone = new Material();
clone.copy(this);
return clone;
}
/**
* This operation compares materials so that they may be sorted when in
* lists. Implements the Comparable interface. Uses only the material's
* names, as these should be the best unique identifiers for sorting.
*
* @param otherMaterial
* The other material to be compared. Will return 0 if this is
* not a material object or a subclass!
* @return Returns a value less than one if it is to be closer to index 0
* than the other material. Returns a value of exactly 0 if it is
* equal to the other material. Finally, returns a value of greater
* than one if it is to be further from index 0 than the other
* material.
*/
@Override
public int compareTo(Material otherMaterial) {
int returnVal = 0;
// The name of the element or compound for the two materials
String thisElement = getElementalName();
String otherElement = otherMaterial.getElementalName();
// The isotopic numbers for the two materials
int thisNum = getIsotopicNumber();
int otherNum = otherMaterial.getIsotopicNumber();
// Dealing with the same element, sort by isotope number
if (thisElement.toLowerCase().equals(otherElement.toLowerCase())) {
// Sort from lower isotopic number to greater
if (thisNum < otherNum) {
returnVal = -1;
} else if (thisNum > otherNum) {
returnVal = 1;
} else {
returnVal = 0;
}
// Dealing with different elements, sort by name.
} else {
returnVal = thisElement.toLowerCase().compareTo(
otherElement.toLowerCase());
}
// Return the sorting value for these two Materials
return returnVal;
}
}