Can I call function across files when using "it.set_callback"?

I tried to call function across files when using “it.set_callback” but it fails and gives an error message “ValueError : Python object atk is defined but is not callable.”

Global variables across files are defined in config.py file

The callback function works well when the function is defined in the main (TEST.py) file, but it fails when it is defined in the another file (mod1.py) and called as “atk”

TEST.py

get_ipython().magic('reset -sf') #command to initialize iPython environment
import itasca as it
import numpy as np
from vec import vec
import cfg
import mod1

it.command("python-reset-state false") #the model new command will not affect python environment

# APPLY MODULE CHANGES
import importlib
importlib.reload(cfg)
importlib.reload(mod1)

print('== start ==')
it.command("""
model new
model configure dynamic
model large-strain on
""")

# TEST PARAMETERS
it.command("""model domain extent -1.0 1.0
domain condition destroy""")

p1, p2, p3, p4, p5, p6, p7, p8 = (0,0,0), (0.5,0.5,0), (0.5,0,0), (0,0.5,0), (0,0,0.5), (0.5,0.5,0.5), (0.5,0,0.5), (0,0.5,0.5)

it.command(f"""
wall generate id 1 name 'aa' polygon {p1} {p2} {p3} {p4}
wall generate id 2 name 'bb' polygon {p5} {p6} {p7} {p8}
""")

cfg.wall_obj_id = np.array([it.wall.find(1), \
it.wall.find(2)])

cfg.hor_disp = 0.01
cfg.hor_freq  = 1.0

print('kk')
print(cfg.wall_obj_id)

it.command(f"""
wall history name 'disp' displacement-x id 1
model history name 'd_time' dynamic time-total
model dynamic timestep fix 0.01
""")

atk = mod1.af()

def af(*args):
     print('disp=', cfg.hor_disp, 'freq=', cfg.hor_freq)
     mech_time = it.mech_age() # get mechanical time
     hor_vel = cfg.hor_disp * 2 * np.pi * cfg.hor_freq * np.cos(2 * np.pi * cfg.hor_freq * mech_time)
     for i in range (len(cfg.wall_obj_id)):
         cfg.wall_obj_id[i].set_vel_x(hor_vel)

#it.set_callback("af", -10.9)
it.set_callback("atk", -10.9)

it.command(f"""
model solve time 10.0
""")

config.py

import numpy as np

# Declare global variable
hor_disp = 0.0
hor_freq  = 0.0
wall_obj_id = np.array([]) # This can make undefined array

mod1.py

import cfg
import numpy as np
import itasca as it

def af(*args):
     print('disp=', cfg.hor_disp, 'freq=', cfg.hor_freq)
     mech_time = it.mech_age() # get mechanical time
     hor_vel = cfg.hor_disp * 2 * np.pi * cfg.hor_freq * np.cos(2 * np.pi * cfg.hor_freq * mech_time)
     for i in range (len(cfg.wall_obj_id)):
         cfg.wall_obj_id[i].set_vel_x(hor_vel)

In Test.py, you just need a small modification:
atk = mod1.af instead of atk = mod1.af()

Thank you Huy
It works!!

:slight_smile: