Skip to content
Open
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
14 changes: 7 additions & 7 deletions process/core/caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,13 @@ def call_models_and_write_output(self, xc: np.ndarray, ifail: int):
for _ in range(10):
# Divert OUT.DAT and MFILE.DAT output to scratch files for
# idempotence checking
OutputFileManager.open_idempotence_files()
OutputFileManager.open_idempotence_files(self.data.globals.output_prefix)
self._call_models_once(xc)
# Write mfile
finalise(self.models, self.data, ifail)

# Extract data from intermediate idempotence-checking mfile
mfile_path = (
data_structure.global_variables.output_prefix
) + "IDEM_MFILE.DAT"
mfile_path = (self.data.globals.output_prefix) + "IDEM_MFILE.DAT"
mfile = MFile(mfile_path)
# Create mfile dict of float values: only compare floats
mfile_data = {
Expand Down Expand Up @@ -204,7 +202,9 @@ def call_models_and_write_output(self, xc: np.ndarray, ifail: int):
logger.debug("Mfiles idempotent, returning")
# Divert OUT.DAT and MFILE.DAT output back to original files
# now idempotence checking complete
OutputFileManager.close_idempotence_files()
OutputFileManager.close_idempotence_files(
self.data.globals.output_prefix
)
# Write final output file and mfile
finalise(self.models, self.data, ifail)
return
Expand All @@ -230,12 +230,12 @@ def call_models_and_write_output(self, xc: np.ndarray, ifail: int):
)

# Close idempotence files, write final output file and mfile
OutputFileManager.close_idempotence_files()
OutputFileManager.close_idempotence_files(self.data.globals.output_prefix)

except Exception:
# If exception in model evaluations delete intermediate idempotence
# files to clean up
OutputFileManager.close_idempotence_files()
OutputFileManager.close_idempotence_files(self.data.globals.output_prefix)
raise
else:
finalise(
Expand Down
25 changes: 11 additions & 14 deletions process/core/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from process.data_structure.impurity_radiation_variables import N_IMPURITIES
from process.data_structure.numerics import FiguresOfMerit, PROCESSRunMode
from process.data_structure.physics_variables import DivertorNumberModels
from process.data_structure.scan_variables import init_scan_variables
from process.models.pfcoil import PFLocationTypes
from process.models.physics.profiles import DensityProfilePedestalType
from process.models.stellarator.initialization import st_init
Expand All @@ -48,7 +47,7 @@ def init_process(data: DataStructure):
iteration_variables.initialise_iteration_variables()

# Creating and open the files MFile and OUTFile
process_output.OutputFileManager.open_files()
process_output.OutputFileManager.open_files(data.globals.output_prefix)

# Input any desired new initial values
inputs = parse_input_file(data)
Expand All @@ -65,7 +64,7 @@ def init_process(data: DataStructure):
# Check input data for errors/ambiguities
check_process(inputs, data)

run_summary()
run_summary(data)


def get_git_summary() -> tuple[str, str]:
Expand Down Expand Up @@ -103,7 +102,7 @@ def get_git_summary() -> tuple[str, str]:
return git_branch, git_tag


def run_summary():
def run_summary(data: DataStructure):
"""Write a summary of the PROCESS run to the output file and MFile"""
# Outfile and terminal #
for outfile in [constants.NOUT, constants.IOTTY]:
Expand Down Expand Up @@ -139,20 +138,20 @@ def run_summary():
process_output.ocmmnt(outfile, f"Computer : {machine}")
process_output.ocmmnt(outfile, f"Directory : {Path.cwd()}")

fileprefix = data_structure.global_variables.fileprefix
fileprefix = data.globals.fileprefix
process_output.ocmmnt(
outfile,
f"Input : {fileprefix}",
)
runtitle = data_structure.global_variables.runtitle
runtitle = data.globals.runtitle
process_output.ocmmnt(
outfile,
f"Run title : {runtitle}",
)

process_output.ocmmnt(
outfile,
f"Run type : Reactor concept design: {data_structure.global_variables.icase}, (c) UK Atomic Energy Authority",
f"Run type : Reactor concept design: {data.globals.icase}, (c) UK Atomic Energy Authority",
)

process_output.oblnkl(outfile)
Expand All @@ -177,7 +176,7 @@ def run_summary():
if data_structure.numerics.ioptimz == PROCESSRunMode.OPTIMISATION:
process_output.ocmmnt(
outfile,
f"Max iterations : {data_structure.global_variables.maxcal}",
f"Max iterations : {data.globals.maxcal}",
)

if data_structure.numerics.minmax > 0:
Expand Down Expand Up @@ -233,8 +232,6 @@ def init_all_module_vars():
"""
logging_model_handler.clear_logs()
data_structure.numerics.init_numerics()
data_structure.global_variables.init_global_variables()
init_scan_variables()
constants.init_constants()


Expand Down Expand Up @@ -561,7 +558,7 @@ def check_process(inputs, data): # noqa: ARG001

# Tight aspect ratio options (ST)
if data.physics.itart == 1:
data_structure.global_variables.icase = "Tight aspect ratio tokamak model"
data.globals.icase = "Tight aspect ratio tokamak model"

# Disabled Forcing that no inboard breeding blanket is used
# Disabled i_blkt_inboard = 0
Expand Down Expand Up @@ -748,7 +745,7 @@ def check_process(inputs, data): # noqa: ARG001

# Pulsed power plant model
if data.pulse.i_pulsed_plant == 1:
data_structure.global_variables.icase = "Pulsed tokamak model"
data.globals.icase = "Pulsed tokamak model"
else:
data.buildings.esbldgm3 = 0.0

Expand Down Expand Up @@ -1154,6 +1151,6 @@ def set_active_constraints():

def set_device_type(data):
if data.ife.ife == 1:
data_structure.global_variables.icase = "Inertial Fusion model"
data.globals.icase = "Inertial Fusion model"
elif data.stellarator.istell != 0:
data_structure.global_variables.icase = "Stellarator model"
data.globals.icase = "Stellarator model"
42 changes: 22 additions & 20 deletions process/core/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from process.data_structure.impurity_radiation_variables import N_IMPURITIES
from process.data_structure.pfcoil_variables import N_PF_GROUPS_MAX
from process.data_structure.physics_variables import N_CONFINEMENT_SCALINGS
from process.data_structure.scan_variables import IPNSCNS, IPNSCNV

if TYPE_CHECKING:
from collections.abc import Callable
Expand Down Expand Up @@ -68,11 +69,12 @@ class InputVariable:
been cast to the specified `type`.
"""
additional_actions: (
Callable[[str, ValidInputTypes, int | None, InputVariable], None] | None
Callable[[str, ValidInputTypes, int | None, InputVariable, DataStructure], None]
| None
) = None
"""A function that takes the input variable: name, value, array index, and config (this dataclass)
as input and performs some additional action in addition to the default actions prescribed by the variables
config. May raise a ProcessValidationError.
"""A function that takes the input variable: name, value, array index, config (this dataclass), and
the data structure object as input and performs some additional action in addition to the default
actions prescribed by the variables config. May raise a ProcessValidationError.

NOTE: The value passed in has already been cleaned in the default
way and has been cast to the specified `type`.
Expand Down Expand Up @@ -103,15 +105,15 @@ def __post_init__(self):


INPUT_VARIABLES = {
"runtitle": InputVariable(data_structure.global_variables, str),
"verbose": InputVariable(data_structure.global_variables, int, choices=[0, 1]),
"run_tests": InputVariable(data_structure.global_variables, int, choices=[0, 1]),
"runtitle": InputVariable("globals", str),
"verbose": InputVariable("globals", int, choices=[0, 1]),
"run_tests": InputVariable("globals", int, choices=[0, 1]),
"ioptimz": InputVariable(data_structure.numerics, int, choices=[1, -2]),
"epsvmc": InputVariable(data_structure.numerics, float, range=(0.0, 1.0)),
"boundl": InputVariable(data_structure.numerics, float, array=True),
"boundu": InputVariable(data_structure.numerics, float, array=True),
"epsfcn": InputVariable(data_structure.numerics, float, range=(0.0, 1.0)),
"maxcal": InputVariable(data_structure.global_variables, int, range=(0, 10000)),
"maxcal": InputVariable("globals", int, range=(0, 10000)),
"minmax": InputVariable(data_structure.numerics, int),
"neqns": InputVariable(
data_structure.numerics, int, range=(0, ConstraintManager.num_constraints())
Expand Down Expand Up @@ -1049,7 +1051,7 @@ def __post_init__(self):
"output_costs": InputVariable("costs", int, choices=[0, 1]),
"i_p_coolant_pumping": InputVariable("fwbs", int, range=(0, 3)),
"reinke_mode": InputVariable("reinke", int, choices=[0, 1]),
"scan_dim": InputVariable(data_structure.scan_variables, int, range=(1, 2)),
"scan_dim": InputVariable("scan", int, range=(1, 2)),
"i_thermal_electric_conversion": InputVariable("fwbs", int, range=(0, 4)),
"secondary_cycle_liq": InputVariable("fwbs", int, range=(2, 4)),
"supercond_cost_model": InputVariable("costs", int, choices=[0, 1]),
Expand Down Expand Up @@ -1091,27 +1093,27 @@ def __post_init__(self):
"v2matf": InputVariable("ife", float, array=True),
"v3matf": InputVariable("ife", float, array=True),
"isweep": InputVariable(
data_structure.scan_variables,
"scan",
int,
choices=range(data_structure.scan_variables.IPNSCNS + 1),
choices=range(IPNSCNS + 1),
),
"nsweep": InputVariable(
data_structure.scan_variables,
"scan",
int,
choices=range(1, data_structure.scan_variables.IPNSCNV + 1),
choices=range(1, IPNSCNV + 1),
),
"isweep_2": InputVariable(
data_structure.scan_variables,
"scan",
int,
choices=range(data_structure.scan_variables.IPNSCNS + 1),
choices=range(IPNSCNS + 1),
),
"nsweep_2": InputVariable(
data_structure.scan_variables,
"scan",
int,
choices=range(1, data_structure.scan_variables.IPNSCNV + 1),
choices=range(1, IPNSCNV + 1),
),
"sweep": InputVariable(data_structure.scan_variables, float, array=True),
"sweep_2": InputVariable(data_structure.scan_variables, float, array=True),
"sweep": InputVariable("scan", float, array=True),
"sweep_2": InputVariable("scan", float, array=True),
"impvardiv": InputVariable(
"reinke",
int,
Expand Down Expand Up @@ -1144,7 +1146,7 @@ def __post_init__(self):


def parse_input_file(data_structure_obj: DataStructure):
input_file = data_structure.global_variables.fileprefix
input_file = data_structure_obj.globals.fileprefix

input_file_path = Path("IN.DAT")
if input_file != "":
Expand Down
10 changes: 4 additions & 6 deletions process/core/io/vary_run/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import click
from numpy.random import default_rng

from process import data_structure
from process.core.io.in_dat import InDat
from process.core.io.mfile import MFile
from process.core.io.vary_run.tools import (
Expand All @@ -26,6 +25,7 @@
process_warnings,
set_variable_in_indat,
)
from process.core.model import DataStructure

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -261,7 +261,7 @@ def error_status2readme(self, mfile):
def modify_in_dat(self):
"""Modifies the original IN.DAT file"""

def setup(self):
def setup(self, data: DataStructure):
"""Sets up the program for running"""
self.echo()

Expand All @@ -275,10 +275,8 @@ def setup(self):

self.generator = default_rng(seed=self.u_seed)

data_structure.global_variables.output_prefix = str(
self.wdir / self.outfile.strip("MFILE.DAT")
)
data_structure.global_variables.fileprefix = str(self.wdir / self.infile)
data.globals.output_prefix = str(self.wdir / self.outfile.strip("MFILE.DAT"))
data.globals.fileprefix = str(self.wdir / self.infile)

@staticmethod
def run_process(input_path: Path, solver: str = "vmcon"):
Expand Down
4 changes: 4 additions & 0 deletions process/core/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from process.data_structure.divertor_variables import DivertorData
from process.data_structure.first_wall_variables import FirstWallData
from process.data_structure.fwbs_variables import FWBSData
from process.data_structure.global_variables import GlobalData
from process.data_structure.heat_transport_variables import HeatTransportData
from process.data_structure.ife_variables import IFEData
from process.data_structure.impurity_radiation_variables import ImpurityRadiationData
Expand All @@ -26,6 +27,7 @@
from process.data_structure.pulse_variables import PulseData
from process.data_structure.rebco_variables import RebcoData
from process.data_structure.reinke_variables import ReinkeData
from process.data_structure.scan_variables import ScanData
from process.data_structure.stellarator_configuration import StellaratorConfigData
from process.data_structure.stellarator_variables import StellaratorData
from process.data_structure.structure_variables import StructureData
Expand Down Expand Up @@ -75,6 +77,8 @@ class DataStructure:
rebco: RebcoData = initialise_later
tfcoil: TFData = initialise_later
superconducting_tfcoil: SuperconductingTFData = initialise_later
globals: GlobalData = initialise_later
scan: ScanData = initialise_later

def __post_init__(self):
for f in fields(self):
Expand Down
18 changes: 9 additions & 9 deletions process/core/process_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,38 @@
import numpy as np

from process.core import constants
from process.data_structure import global_variables, numerics
from process.data_structure import numerics


class OutputFileManager:
@classmethod
def open_files(cls, *, mode="w"):
def open_files(cls, output_prefix: str, *, mode="w"):
cls._outfile = open( # noqa: SIM115
Path(global_variables.output_prefix + "OUT.DAT"), mode
Path(output_prefix + "OUT.DAT"), mode
)
cls._mfile = open( # noqa: SIM115
Path(global_variables.output_prefix + "MFILE.DAT"), mode
Path(output_prefix + "MFILE.DAT"), mode
)

@classmethod
def open_idempotence_files(cls):
def open_idempotence_files(cls, output_prefix: str):
cls._outfile.close()
cls._mfile.close()

cls._outfile = open( # noqa: SIM115
Path(global_variables.output_prefix + "IDEM_OUT.DAT"), "w"
Path(output_prefix + "IDEM_OUT.DAT"), "w"
)
cls._mfile = open( # noqa: SIM115
Path(global_variables.output_prefix + "IDEM_MFILE.DAT"), "w"
Path(output_prefix + "IDEM_MFILE.DAT"), "w"
)

@classmethod
def close_idempotence_files(cls):
def close_idempotence_files(cls, output_prefix: str):
Path(cls._outfile.name).unlink()
Path(cls._mfile.name).unlink()
cls._outfile.close()
cls._mfile.close()
cls.open_files(mode="a")
cls.open_files(mode="a", output_prefix=output_prefix)

@classmethod
def finish(cls):
Expand Down
Loading
Loading