Skip to content

Unable to apply the adjoint for a linear model

I'm trying to apply the Adjoint operator for an Advection Diffusion 1D problem. However, I get an error in the Jacobian matrix-vector product. In this case, the Jacobian should be state/time independent but the function expects a time to evaluate it.

Steps to recreate it are shown below.

tspan  = (1,20)
chkpts = np.arange(2,7,0.5)

# Get the model setup
model = AdvectionDiffusion1D(configs={'nx':40, 'dt':0.1})
    
# Setup the selection operator
obspct = 60.0
n_obs = int(np.round((obspct / 100.0) * model.state_size))
s_pts = np.sort(np.random.choice(model.state_size, n_obs, replace=False))

obsop = SelectionOperator(configs={'model':model, 
                            'observation_indexes':s_pts})
    
# Setup the prior
prior = GaussianErrorModel(configs={'size':model.state_size, 
                'mean':0, 'variance':1, 'random_seed':117})

# Setup the noise
obsns = GaussianErrorModel(configs={'size':obsop.shape[0], 
                'variance':0.01, 'random_seed':113})

# Setup the 4D Var object
F_oper = VanillaFourDVar()
F_oper.register_model(model)
F_oper.register_assimilation_window(tspan)
F_oper.register_observation_operator(obsop)
F_oper.register_prior_model(prior)
F_oper.register_observation_error_model(obsns)

F_obs, F_sts = F_oper.apply_forward_operator(x, checkpoints=chkpts, scale_by_noise=False, save_states=True)

q = np.random.rand(obsop.shape[0])
(F_chktimes, F_chksts) = zip(*F_sts.items())

Ft_adj, Ft_sts = F_oper.apply_forward_operator_adjoint(q, chkpts[-1], scale_by_noise=False,                                    checkpointed_states=F_chksts, checkpointed_states_times=F_chktimes)

Running this example results in the following error.

File ~/Desktop/Academics/Code/pyoed/pyoed/assimilation/smoothing/fourDVar.py:1240, in VanillaFourDVar.apply_forward_operator_adjoint(self, obs, obs_time, eval_at, checkpointed_states, checkpointed_states_times, verbose, save_all, scale_by_noise)
   1238 # Not checkpointed states
   1239 for i in range(len(local_checkpoints) - 1):
-> 1240     adjoint = self._MODEL.Jacobian_T_matvec(adjoint)
   1241 if DEBUG:
   1242     print(
   1243         "Adjoint evaluation for linear model; number of"
   1244         f" applications {len(local_checkpoints)-1}"
   1245     )

TypeError: AdvectionDiffusion1D.Jacobian_T_matvec() missing 1 required positional argument: 'eval_at_t'