Coverage for steam_pysigma\comsol\BuildGlobalVariables.py: 81%
191 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-12-16 17:09 +0100
« prev ^ index » next coverage.py v7.4.3, created at 2024-12-16 17:09 +0100
1# STEAM PySigma is a python wrapper of STEAM-SIGMA written in Java.
2# Copyright (C) 2023, CERN, Switzerland. All rights reserved.
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, version 3 of the License.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <https://www.gnu.org/licenses/>.
16import logging
17import os
19class BuildGlobalVariables:
21 def __init__(self, g, model_data):
22 self.g = g
23 self.model_data = model_data
26 def validate_sigma_model_data(self):
27 """
28 Method checks the SIGMA options in the model_data to be valid to parse into SIGMA.
29 :return:
30 """
31 model_data = self.model_data
32 constants = self.g.MPHC
33 logging.getLogger().setLevel(logging.INFO)
35 # logging.warning('And this, too')
36 options_sigma = model_data.Options_SIGMA
37 # Check key time_vector_solution.time_step
38 time_step = options_sigma.time_vector_solution.time_step
39 # Check type list[list] with three values
40 if type(time_step) == list:
41 if any(isinstance(el, list) for el in time_step):
42 # Check data in vector is valid;
43 for i in range(len(time_step)):
44 if len(time_step[i]) == 3:
45 if time_step[i][0] > time_step[i][2]:
46 raise ValueError(
47 "options_sigma.time_vector_solution.time_step has invalid data. Start value can not be larger than end value.")
48 else:
49 pass
50 if i <= len(time_step) - 2:
51 if time_step[i][2] > time_step[i + 1][0]:
52 raise ValueError(
53 "options_sigma.time_vector_solution.time_step has overlapping time step intervals")
54 else:
55 raise ValueError(
56 "options_sigma.time_vector_solution.time_step has invalid data. Three element per sublist needed")
58 # Check options_sigma.simulation
59 study_type = options_sigma.simulation.study_type
60 print(f"Running study type: {study_type}")
61 if study_type == constants.LABEL_TRANSIENT or study_type == constants.LABEL_STATIONARY:
62 pass
63 else:
64 raise ValueError(f"String is not Transient or Stationary.")
66 # Check options_sigma.physics
67 if study_type == constants.LABEL_TRANSIENT:
68 for key, value in options_sigma.physics:
69 if key == "tauCC_PE":
70 pass
71 elif value is None:
72 raise ValueError(f'{key} is set to null. To make sigma run this will be set to 0 as default.')
74 # Check options_sigma.quench_initialization only valid if Transient
75 if options_sigma.simulation.study_type == constants.LABEL_TRANSIENT:
76 for key, value in options_sigma.quench_initialization:
77 if "FLAG" in key:
78 if value is None:
79 raise ValueError(f'{key} is set to null. To make sigma run this will be set to 0 as default.')
80 if key == "num_qh_div":
81 if len(value) != model_data.Quench_Protection.Quench_Heaters.N_strips:
82 raise ValueError(
83 f"The number of quench heater divisions must be {model_data.Quench_Protection.Quench_Heaters.N_strips}")
84 if key == "quench_init_heat":
85 if value is None:
86 raise ValueError(f"{key} can't be none")
87 else:
88 if value < 0:
89 raise ValueError("Power for initialize quench can't be negative")
90 if key == "quench_stop_temp":
91 if value is None:
92 raise ValueError(f"{key} can't be none")
93 if value < 0:
94 raise ValueError("Tempereatur for initialize quench can't be negative")
96 # Check options_sigma.postprocessing.out_2D_at_points
97 options_sigma.postprocessing.out_2D_at_points.coordinate_source = None
98 for key, value in options_sigma.postprocessing.out_2D_at_points:
99 if key == "coordinate_source":
100 # Check if source exists
101 if value is not None:
102 if not os.path.exists(value):
103 raise ValueError("Given coordinate file path does not exist")
105 else:
106 logging.info("Using coordinate file to evaluate 2D plots")
108 if options_sigma.simulation.study_type == constants.LABEL_TRANSIENT:
109 if key == "time":
110 # Check number of values
111 if len(value) != len(options_sigma.postprocessing.out_2D_at_points.variables):
112 raise ValueError("Number of time vectors must be the same as number of variables.")
113 else:
114 for i in range(len(value)):
115 if len(value[i]) == 3:
116 if value[0] > value[2]:
117 raise ValueError(
118 "options_sigma.postprocessing.out_2D_at_points.time has invalid data. Start value can not be larger than end value.")
119 else:
120 pass
121 else:
122 raise ValueError(
123 "options_sigma.postprocessing.out_2D_at_points.time has invalid data. Three elements needed.")
124 if options_sigma.simulation.study_type == constants.LABEL_TRANSIENT:
125 for key, value in options_sigma.postprocessing.out_1D_vs_times:
126 if key == "time":
127 # Check number of values
128 if len(value) != len(options_sigma.postprocessing.out_1D_vs_times.variables):
129 raise ValueError("Number of time vectors must be the same as number of variables.")
130 else:
131 for i in range(len(value)):
132 if len(value[i]) == 3:
133 if value[i][0] > value[i][2]:
134 raise ValueError(
135 f"options_sigma.postprocessing.out_1D_vs_times.time has invalid data for value {value}. Start value can not be larger than end value.")
136 else:
137 raise ValueError(
138 "options_sigma.postprocessing.out_1D_vs_times.time has invalid data. Three elements needed.")
140 # options_sigma.quench_heaters
141 if options_sigma.simulation.study_type == constants.LABEL_TRANSIENT:
142 th_coils = options_sigma.quench_heaters.th_coils
143 if 0 in th_coils:
144 raise ValueError("List contains zero values, change model_data.yaml to valid value.")
146 if self.model_data.Quench_Protection.Quench_Heaters.N_strips == None:
147 raise ValueError("N_strips can't be null. Edit the model_data.yaml file.")
149 def helper_check_time_step_valid(self, time_step):
150 if type(time_step) == list:
151 if any(isinstance(el, list) for el in time_step):
152 # Check data in vector is valid;
153 for i in range(len(time_step)):
154 if len(time_step[i]) == 3:
155 if time_step[i][0] > time_step[i][2]:
156 raise ValueError(
157 "#options_sigma.time_vector_solution.time_step has invalid data. Start value can not be larger than end value.")
158 else:
159 pass
160 if i <= len(time_step) - 2:
161 if time_step[i][2] > time_step[i + 1][0]:
162 raise ValueError(
163 "options_sigma.time_vector_solution.time_step has overlapping time step intervals")
164 else:
165 raise ValueError(
166 "options_sigma.time_vector_solution.time_step has invalid data. Three element per sublist needed")
167 def build_global_variables(self):
168 """
169 Function builds all global variables nessesary for QH simulations.
170 :return: map with global variables
171 """
172 map = self.g.gateway.jvm.java.util.HashMap()
173 constants = self.g.MPHC
174 # Cliq variables:
175 end_sim_time = self.model_data.Options_SIGMA.time_vector_solution.time_step[-1][-1]
177 R_crow = self.model_data.Circuit.R_circuit
178 L_circuit = self.model_data.Circuit.L_circuit
179 C_cliq = self.model_data.Quench_Protection.CLIQ.C
180 L_cliq = self.model_data.Quench_Protection.CLIQ.L
182 V_cliq_0 = self.model_data.Quench_Protection.CLIQ.U0
183 I_cliq_0 = self.model_data.Quench_Protection.CLIQ.I0
185 sym_factor = self.model_data.Quench_Protection.CLIQ.sym_factor
186 cliq_time = self.model_data.Quench_Protection.CLIQ.t_trigger
187 if cliq_time > end_sim_time:
188 with_cliq = 0
189 else:
190 with_cliq = 1
192 if V_cliq_0 == None:
193 V_cliq_0 = 0
194 if I_cliq_0 == None:
195 I_cliq_0 = 0
196 if sym_factor == None:
197 sym_factor = 1
198 if L_circuit == None:
199 L_circuit = "1e-6"
200 if L_cliq == None:
201 L_cliq = "1e-6"
202 map.put(constants.LABEL_CLIQ_RCROW, str(R_crow))
203 map.put(constants.LABEL_CLIQ_LCIR, str(L_circuit))
204 map.put(constants.LABEL_CLIQ_CAPASITOR, str(C_cliq))
205 map.put(constants.LABEL_CLIQ_INDUCTANCE, str(L_cliq))
206 map.put(constants.LABEL_CLIQ_VOLTAGE_INITIAL, str(V_cliq_0))
207 map.put(constants.LABEL_CLIQ_CURRENT_INITIAL, str(I_cliq_0))
208 map.put(constants.LABEL_CLIQ_SYMFACTOR, str(sym_factor))
209 map.put(constants.LABEL_CLIQ_SWITCH, str(with_cliq))
211 FLAG_M_pers = self.model_data.Options_SIGMA.physics.FLAG_M_pers
212 FLAG_M_pers = "0" if FLAG_M_pers is None else FLAG_M_pers
214 FLAG_ifcc = self.model_data.Options_SIGMA.physics.FLAG_ifcc
215 FLAG_ifcc = "0" if FLAG_ifcc is None else FLAG_ifcc
217 FLAG_iscc_crossover = self.model_data.Options_SIGMA.physics.FLAG_iscc_crossover
218 FLAG_iscc_crossover = "0" if FLAG_iscc_crossover is None else FLAG_iscc_crossover
220 FLAG_iscc_adjw = self.model_data.Options_SIGMA.physics.FLAG_iscc_adjw
221 FLAG_iscc_adjw = "0" if FLAG_iscc_adjw is None else FLAG_iscc_adjw
223 FLAG_iscc_adjn = self.model_data.Options_SIGMA.physics.FLAG_iscc_adjn
224 FLAG_iscc_adjn = "0" if FLAG_iscc_adjn is None else FLAG_iscc_adjn
226 FLAG_quench_all = self.model_data.Options_SIGMA.quench_initialization.FLAG_quench_all
227 FLAG_quench_all = "0" if FLAG_quench_all is None else FLAG_quench_all
229 FLAG_quench_off = self.model_data.Options_SIGMA.quench_initialization.FLAG_quench_off
230 FLAG_quench_off = "0" if FLAG_quench_off is None else FLAG_quench_off
232 PARAM_time_quench = self.model_data.Options_SIGMA.quench_initialization.PARAM_time_quench
233 PARAM_time_quench = "0" if PARAM_time_quench is None else PARAM_time_quench
235 magnetic_length = self.model_data.GeneralParameters.magnetic_length
236 T_initial = self.model_data.GeneralParameters.T_initial
238 quench_heat = self.model_data.Options_SIGMA.quench_initialization.quench_init_heat
239 quench_temp = self.model_data.Options_SIGMA.quench_initialization.quench_stop_temp
241 map.put(constants.LABEL_FLAG_IFCC, str(FLAG_ifcc))
242 map.put(constants.LABEL_FLAG_ISCC_CROSSOVER, str(FLAG_iscc_crossover))
243 map.put(constants.LABEL_FLAG_ISCC_ADJW, str(FLAG_iscc_adjw))
244 map.put(constants.LABEL_FLAG_ISCC_ADJN, str(FLAG_iscc_adjn))
245 map.put(constants.LABEL_FLAG_MPERS, str(FLAG_M_pers))
246 map.put(constants.LABEL_FLAG_QUENCH_ALL, str(FLAG_quench_all))
247 map.put(constants.LABEL_FLAG_QUENCH_OFF, str(FLAG_quench_off))
248 map.put(constants.LABEL_PARAM_QUENCH_TIME, str(PARAM_time_quench))
249 map.put(constants.LABEL_MAGNETIC_LENGTH, str(magnetic_length))
250 map.put(constants.LABEL_OPERATIONAL_TEMPERATUR, str(T_initial))
251 map.put(constants.LABEL_INIT_QUENCH_HEAT, str(quench_heat))
252 map.put(constants.LABEL_QUENCH_TEMP, str(quench_temp))
254 ins_list = self.model_data.Quench_Protection.Quench_Heaters.s_ins
255 w_list = self.model_data.Quench_Protection.Quench_Heaters.w
256 qh_to_bath_list = self.model_data.Quench_Protection.Quench_Heaters.s_ins_He
257 qh_steel_strip = self.model_data.Quench_Protection.Quench_Heaters.h
258 tau = [round(a * b, 4) for a, b in
259 zip(self.model_data.Quench_Protection.Quench_Heaters.R_warm, self.model_data.Quench_Protection.Quench_Heaters.C)]
260 num_qh_div = self.model_data.Options_SIGMA.quench_initialization.num_qh_div
261 u_init = self.model_data.Quench_Protection.Quench_Heaters.U0
263 # In case R_warm = 0
264 try: i_init = [round(a / b, 3) for a, b in zip(self.model_data.Quench_Protection.Quench_Heaters.U0,
265 self.model_data.Quench_Protection.Quench_Heaters.R_warm)]
266 except: i_init = [0 for a, b in zip(self.model_data.Quench_Protection.Quench_Heaters.U0,
267 self.model_data.Quench_Protection.Quench_Heaters.R_warm)]
269 frac_heater = self.model_data.Quench_Protection.Quench_Heaters.f_cover
270 trigger_time = self.model_data.Quench_Protection.Quench_Heaters.t_trigger
271 ins_thick_to_coil = self.model_data.Options_SIGMA.quench_heaters.th_coils
272 lengths_qh = self.model_data.Quench_Protection.Quench_Heaters.l
274 for i in range(self.model_data.Quench_Protection.Quench_Heaters.N_strips):
275 if self.model_data.Options_SIGMA.time_vector_solution.time_step[-1][-1] < trigger_time[i]:
276 trigger_time[i] = self.model_data.Options_SIGMA.time_vector_solution.time_step[-1][-1]
277 map.put(constants.LABEL_INSULATION_THICKNESS_QH_TO_COIL + str(i + 1), str(ins_list[i]))
278 map.put(constants.LABEL_WIDTH_QH + str(i + 1), str(w_list[i]))
279 map.put(constants.LABEL_INSULATION_THICKNESS_QH_TO_BATH + str(i + 1), str(qh_to_bath_list[i]))
280 map.put(constants.LABEL_INSULATION_THICKNESS_QH_STRIP + str(i + 1), str(qh_steel_strip[i]))
281 map.put(constants.LABEL_EXPONENTIAL_TIME_CONSTANT_DECAY + str(i + 1), str(tau[i]))
282 map.put(constants.LABEL_QH + constants.LABEL_L + str(i + 1), str(lengths_qh[i]))
283 map.put(constants.LABEL_NUMBER_OF_QH_SUBDIVISIONS + str(i + 1), str(num_qh_div[i]))
284 map.put(constants.LABEL_INITIAL_QH_CURRENT + str(i + 1), str(i_init[i]))
285 map.put(constants.LABEL_INITIAL_QH_VOLTAGE + str(i + 1), str(u_init[i]))
286 map.put(constants.LABEL_QH + str(i + 1) + constants.LABEL_FRACTION_OF_QH_STATION, str(frac_heater[i]))
287 map.put(constants.LABEL_TRIGGER_TIME_QH + str(i + 1), str(trigger_time[i]))
288 map.put(constants.LABEL_INSULATION_THICKNESS_TO_COIL + str(i + 1), str(ins_thick_to_coil[i]))
290 return map