Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion pypact/input/inputdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,18 @@ def _deserialize(self, f):
"""
self.reset()

lines = f.readlines()
lines = iter(f.readlines()) # Convert lines to an iterator
in_mass_section = False
irradiation_active = True # Flag to track if irradiation schedule is active
flux_set = False # Flag to ensure FLUX is set to a non-zero value before the first irradiation step

time_unit_to_seconds = {
"SECS": 1,
"MINS": 60,
"HOURS": 3600,
"DAYS": 86400,
"YEARS": 31536000
}

for line in lines:
line = line.strip()
Expand All @@ -451,10 +461,74 @@ def _deserialize(self, f):
if num_elements == 0:
in_mass_section = False
else:
if line.startswith(COMMENT_START) and line.endswith(COMMENT_END):
# Ignore comments
continue
raise PypactInvalidOptionException("Invalid element line format in MASS section.")

elif line.startswith("DENSITY"):
parts = line.split()
if len(parts) != 2:
raise PypactInvalidOptionException("Invalid DENSITY line format.")
self.setDensity(float(parts[1]))

elif line.startswith("FLUX") and irradiation_active:
# Parse the FLUX line
parts = line.split()
if len(parts) != 2:
raise PypactInvalidOptionException("Invalid FLUX line format.")
fluxAmp = float(parts[1])

# Ensure FLUX is set to a non-zero value before the first irradiation step
if not flux_set and fluxAmp <= 0.0:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can do just decay in F-II without any ZERO keyword, but this needs to be confirmed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into this and I think yes FISPACT does decay without the ZERO keyword. Just setting the FLUX to 0.0 and the material decays. What ZERO does in addition to setting FLUX to 0.0 is to switch from irradiation to cooling schedule. So I've added a build up of cooling schedule to this PR as well. Sorry for the scope creep.

https://fispact.ukaea.uk/wiki/Keyword:ZERO
https://fispact.ukaea.uk/wiki/Keyword:FLUX

raise PypactInvalidOptionException("FLUX must be set to a non-zero positive value before the first irradiation step.")
flux_set = True

# Store the current flux amplitude - we'll use it when we find a TIME command
current_flux_amp = fluxAmp

# If FLUX is 0.0, we're entering the cooling phase
if fluxAmp == 0.0:
self.addIrradiation(0.0, fluxAmp)
continue

# Handle TIME entries - can appear after any number of intermediate commands following FLUX
elif line.startswith("TIME") and flux_set:
time_parts = line.split()

# Ensure we have at least the TIME keyword and a value
if len(time_parts) < 2:
raise PypactInvalidOptionException(
"Invalid TIME line format: missing time value."
)

# Get the time value
time_value = float(time_parts[1])
timeInSecs = time_value # Default unit is seconds

# Handle different TIME formats
if len(time_parts) >= 3:
# Check if the third part is a time unit
if time_parts[2] in time_unit_to_seconds:
# Format: TIME 10.0 SECS or TIME 0.1 YEARS ATOMS
timeInSecs = time_value * time_unit_to_seconds[time_parts[2]]
# Otherwise, the third part is likely "ATOMS" or something else
# We keep the default assumption of seconds

# Add the time to the appropriate schedule based on whether we're in irradiation or cooling phase
if irradiation_active:
# Still in irradiation phase
self.addIrradiation(timeInSecs, current_flux_amp)
else:
# In cooling phase after ZERO
self.addCooling(timeInSecs)

elif line.startswith("ZERO"):
# Ensure FLUX is set to zero before using ZERO
if not flux_set:
raise PypactInvalidOptionException(
"FLUX must be set before using the ZERO keyword."
)
# Stop processing irradiation schedule
irradiation_active = False
current_flux_amp = 0.0
2 changes: 2 additions & 0 deletions reference/test.i
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ ATOMS
<< irradiation schedule >>
FLUX 1100000000000000.0
TIME 300.0 SECS
FLUX 42.0
TIME 200.0 SECS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're going to need a lot more test cases for this.
Unfortunately, the system tests are not available, but perhaps the workshops can provide some valuable test cases.

Copy link
Contributor Author

@shimwell shimwell May 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 5 test input files from the workshop and added them to the test for irradiation and cooling schedule checking ✔️

ATOMS
<< end of irradiation >>
FLUX 0.0
Expand Down
52 changes: 52 additions & 0 deletions reference/test2.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<< -----set initial switches and get nuclear data----- >>
CLOBBER
JSON
SPEK
GETXS 1 709
GETDECAY 1
FISPACT
* FNS 5 Minutes Inconel-600
DENSITY 8.42
MASS 1.0E-3 4
NI 75.82
MN 0.39
FE 7.82
CR 15.97
MIND 1E3
GRAPH 1 2 1 3
UNCERTAINTY 2
HALF
HAZARDS
TAB1 1
<< -----irradiation phase----- >>
FLUX 1.116E+10
ATOMS
TIME 5.0 MINS
ATOMS
<< -----cooling phase----- >>
FLUX 0.
ZERO
TIME 36 ATOMS
TIME 15 ATOMS
TIME 16 ATOMS
TIME 15 ATOMS
TIME 15 ATOMS
TIME 26 ATOMS
TIME 33 ATOMS
TIME 36 ATOMS
TIME 53 ATOMS
TIME 66 ATOMS
TIME 66 ATOMS
TIME 97 ATOMS
TIME 127 ATOMS
TIME 126 ATOMS
TIME 187 ATOMS
TIME 246 ATOMS
TIME 244 ATOMS
TIME 246 ATOMS
TIME 428 ATOMS
TIME 606 ATOMS
TIME 607 ATOMS
END
* END
/*
16 changes: 16 additions & 0 deletions reference/test3.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
MONITOR 1
CLOBBER
JSON
SPEK
GETXS 1 709
GETDECAY 1
FISPACT
* irradiation 1
MASS 1.0 1
W 100.0
TAB1 21
FLUX 1.1e14
ATOMS
TIME 5 MINS ATOMS
END
* end
82 changes: 82 additions & 0 deletions reference/test4.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
MONITOR 1
<< Overwrite existing inventory.log and inventory.out files >>
CLOBBER
<< Enable JSON file format output for inventory data >>
JSON
<< Read ARRAYX and COLLAPX files >>
GETXS 1 709
GETDECAY 1
<< Read gamma bounds from file >>
READGG
<< End of control >>
FISPACT
* FNS 5 Minutes Inconel-600
<< Material definition - start of initialisation phase >>
<< Density is in units of g/cm3 >>
DENSITY 8.42
<< Elemental definition of material >>
<< total mass = 1g, with 4 elements>>
MASS 1.0E-3 4
<< Nickel at 75.82%>>
NI 75.82
<< Manganese at 0.39%>>
MN 0.39
<< Iron at 7.82%>>
FE 7.82
<< Chromium at 15.97%>>
CR 15.97
<< Set the minimum number of atoms to track - 1000 atom threshold>>
<< 1e5 atoms is the default >>
MIND 1E3
<< Produce some graph files for GNU plot for post processing >>
<< from left to right: 1 graph, 2= .gra and .plt for gnuplot, 1=use uncertainties, 3=total heat output>>
GRAPH 1 2 1 3
<< Output estimates of both uncertainty and pathway analysis >>
UNCERTAINTY 2
<< Output half lives to output inventory information >>
HALF
<< Output ingestion and inhalation doses to output >>
HAZARDS
<< Signify start of inventory phase >>
<< -----irradiation phase----- >>
<< Flux amplitude in /cm2 /s >>
FLUX 1.116E+10
<< ATOMS= tells F-II to solve rate equations and dump output to file >>
<< No time is given so it will use 0.0 (initial) >>
ATOMS
<< Solve and output at 5 minutes of irradiation>>
TIME 5.0 MINS
ATOMS
<< -----cooling phase----- >>
<< Set flux to 0 to tell F-II that no irradiation is occuring and it is decay only >>
FLUX 0.
<< Whilst it is possible to irradiate again FLUX >0, ZERO tells F-II that no more irradiation can occur >>
<< From here on only cooling can happen - this keyword is important for pathways analysis>>
ZERO
<< Cooling time - note use of ATOMS to indicate solving and output >>
<< we could also use STEP or SPECTRUM to reduce output>>
<< Default time unit is seconds, these are all in seconds >>
TIME 36 ATOMS
TIME 15 ATOMS
TIME 16 ATOMS
TIME 15 ATOMS
TIME 15 ATOMS
TIME 26 ATOMS
TIME 33 ATOMS
TIME 36 ATOMS
TIME 53 ATOMS
TIME 66 ATOMS
TIME 66 ATOMS
TIME 97 ATOMS
TIME 127 ATOMS
TIME 126 ATOMS
TIME 187 ATOMS
TIME 246 ATOMS
TIME 244 ATOMS
TIME 246 ATOMS
TIME 428 ATOMS
TIME 606 ATOMS
TIME 607 ATOMS
<< End of file >>
END
* END
28 changes: 28 additions & 0 deletions reference/test5.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
MONITOR 1
CLOBBER
JSON
SPEK
NOERROR
PROJECTILE 3
GETXS 1 162
GETDECAY 1
FISPACT
* proton irradiation
DENSITY 1.0
MASS 1.0 1
Y 100.
FLUX 1e20
ATOMS
TIME 1 MINS ATOMS
TIME 1 MINS ATOMS
TIME 1 MINS ATOMS
FLUX 0.0
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
TIME 1 DAYS ATOMS
END
* end
Loading