Automatic adjoint differentiation for gradient descent and model calibration