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
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ LIST(APPEND PROCESS_SRCS
pfcoil.f90
reinke_module.f90
sctfcoil.f90
final_module.f90
cost_variables.f90
divertor_variables.f90
fwbs_variables.f90
Expand Down
85 changes: 74 additions & 11 deletions process/final.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
"""Final output at the end of a scan."""

from process import fortran as ft
from process.fortran import final_module as fm
from tabulate import tabulate

from process.fortran import (
process_output as po,
constants,
function_evaluator,
numerics,
constraints,
)
from process import output as op
from process.fortran import process_output as po
from process.utilities.f2py_string_patch import f2py_compatible_to_string


def finalise(models, ifail, non_idempotent_msg: None | str = None):
def finalise(models, ifail: int, non_idempotent_msg: None | str = None):
"""Routine to print out the final point in the scan.

Writes to OUT.DAT and MFILE.DAT.
Expand All @@ -18,18 +25,74 @@ def finalise(models, ifail, non_idempotent_msg: None | str = None):
:param non_idempotent_msg: warning about non-idempotent variables, defaults to None
:type non_idempotent_msg: None | str, optional
"""
fm.final_header(ifail)
if ifail == 1:
po.oheadr(constants.nout, "Final Feasible Point")
else:
po.oheadr(constants.nout, "Final UNFEASIBLE Point")

# Output relevant to no optimisation
if ft.numerics.ioptimz == -2:
fm.no_optimisation()
if numerics.ioptimz == -2:
output_once_through()

# Print non-idempotence warning to OUT.DAT only
if non_idempotent_msg:
po.oheadr(ft.constants.nout, "NON-IDEMPOTENT VARIABLES")
po.ocmmnt(ft.constants.nout, non_idempotent_msg)
po.oheadr(constants.nout, "NON-IDEMPOTENT VARIABLES")
po.ocmmnt(constants.nout, non_idempotent_msg)

# Write output to OUT.DAT and MFILE.DAT
op.write(models, ft.constants.nout)
op.write(models, constants.nout)


def output_once_through():
"""Write output for a once-through run of PROCESS"""
po.oheadr(constants.nout, "Numerics")
po.ocmmnt(constants.nout, "PROCESS has performed a run witout optimisation.")
po.oblnkl(constants.nout)

# Evaluate objective function
norm_objf = function_evaluator.funfom()
po.ovarre(
constants.mfile, "Normalised objective function", "(norm_objf)", norm_objf
)

# Print the residuals of the constraint equations

residual_error, value, residual, symbols, units = constraints.constraint_eqns(
numerics.neqns + numerics.nineqns, -1
)

labels = [
f2py_compatible_to_string(i)
for i in numerics.lablcc[numerics.icc[: numerics.neqns + numerics.nineqns]]
]
units = [f2py_compatible_to_string(i) for i in units]
physical_constraint = [f"{c} {u}" for c, u in zip(value.tolist(), units)]
physical_residual = [f"{c} {u}" for c, u in zip(residual.tolist(), units)]

table_data = {
"Constraint Name": labels,
"Constraint Type": symbols.tolist(),
"Physical constraint": physical_constraint,
"Constraint residual": physical_residual,
"Normalised residual": residual_error.tolist(),
}

po.write(constants.nout, tabulate(table_data, headers="keys"))

for i in range(numerics.neqns):
constraint_id = numerics.icc[i]
po.ovarre(
constants.mfile,
f"{labels[i]} normalised residue",
f"(eq_con{constraint_id:03d})",
residual_error[i],
)

fm.final_output()
for i in range(numerics.nineqns):
constraint_id = numerics.icc[numerics.neqns + i]
po.ovarre(
constants.mfile,
f"{labels[numerics.neqns + i]}",
f"(ineq_con{constraint_id:03d})",
residual_error[numerics.neqns + i],
)
125 changes: 0 additions & 125 deletions source/fortran/final_module.f90

This file was deleted.