大家好,我在跑一个工程程序(基于水平集法优化悬臂梁)时,在iters=1之后会报错UnboundLocalError。我希望解决它,谢谢各位!
报错的地方在子程序中的一个函数中:
@no_annotations
def retract(self, input_phi, delta_x, scaling=1):
"""input_phi is not modified,
output_phi refers to problem.phi
Args:
input_phi ([type]): [description]
delta_x ([type]): [description]
scaling (int, optional): [description]. Defaults to 1.
Returns:
[type]: [description]
"""
self.current_max_distance_at_t0 = self.current_max_distance
self.hj_solver.ts.setMaxTime(scaling)
try:
output_phi = self.hj_solver.solve(input_phi)
except:
reason = self.hj_solver.ts.getConvergedReason()
print(f"Time stepping of Hamilton Jacobi failed. Reason: {reason}")
if self.output_dir:
print(f"Printing last solution to {self.output_dir}")
fd.File(f"{self.output_dir}/failed_hj.pvd").write(input_phi)
max_vel = calculate_max_vel(delta_x)
self.last_distance = max_vel * scaling
conv = self.hj_solver.ts.getConvergedReason()
rtol, atol = (
self.hj_solver.parameters["ts_rtol"],
self.hj_solver.parameters["ts_atol"],
)
max_steps = self.hj_solver.parameters.get("ts_max_steps", 800)
current_time = self.hj_solver.ts.getTime()
total_time = self.hj_solver.ts.getMaxTime()
if conv == 2:
warning = (
f"Maximum number of time steps {self.hj_solver.ts.getStepNumber()} reached."
f"Current time is only: {current_time} for total time: {total_time}."
"Consider making the optimization time step dt shorter."
"Restarting this step with more time steps and tighter tolerances if applicable."
)
fd.warning(warning)
# Tighten tolerances if we are really far
if current_time / total_time < 0.2:
current_rtol, current_atol = self.hj_solver.ts.getTolerances()
new_rtol, new_atol = max(rtol / 200, current_rtol / 10), max(
atol / 200, current_atol / 10
)
self.hj_solver.ts.setTolerances(rtol=new_rtol, atol=new_atol)
# Relax max time steps
current_max_steps = self.hj_solver.ts.getMaxSteps()
new_max_steps = min(current_max_steps * 1.5, max_steps * 3)
self.hj_solver.ts.setMaxSteps(new_max_steps)
output_phi.assign(input_phi)
elif conv == 1:
self.hj_solver.ts.setTolerances(rtol=rtol, atol=atol)
return output_phi
运行结果为:
UnboundLocalError: local variable 'output_phi' referenced before assignment
在全局变量和局部变量处报错。
按照网上的方法:
1.添加关键字,global output_phi。结果为:
NameError: name 'output_phi' is not defined
2.事先对output_phi赋值。结果为:
Warning, merit function did not decrease (merit=37.89031163251481, new_merit=779406.285122143)-> Trial 10
All trials have failed, passing to the next iteration.
这里虽然没有报错,但输出表示“试验了n次,数值未减小,算子未参与迭代步骤”。(总共试验了10次)
两个方法皆未能解决。
希望各位师兄支招,解决报错!不胜感激!
报错的原因是try里出错了,进入了except,导致output_phi的赋值语句没有执行
你可以在try之前先把它赋值成0
或者在try里面把它赋值成0也行
output_phi在try之前定义一下就行了,不然只是try部分的局部变量,后面58、62行是访问不到这个变量的
你这样,两种结合起来。外边先定义一个全局变量output_phi,然后函数里面使用的时候先使用global output_phi 声明一下,然后再使用
这是Python变量作用域的问题的问题导致的:
内部函数,不修改全局变量可以访问全局变量
内部函数,修改同名全局变量,则python会认为它是一个局部变量
在内部函数修改同名全局变量之前调用变量名称(如print sum),则引发Unbound-LocalError
解决方法
如果想在函数里修改同名全局变量的值之前引用该变量,就需要在函数内引用前用global关键字将被认为是局部的变量定义为全局变量