Thanks for the code.
Using your code and just passing some random values into the models, I can get valid gradients in both models:
model = Network(2, 2)
modelFCNN = NetworkFCNN(2, 1)
criterion1 = torch.nn.MSELoss()
    
data = torch.randn(1, 2)
y_pred_ref = modelFCNN(data)

# concatenate the tensor with the state vector along columns
sysnn_input = torch.cat((torch.rand_like(y_pred_ref), y_pred_ref), dim=1)

# now feed in this input to the trained sys NN model
output_sys=model(sysnn_input)

#compute the loss 
loss_FCNN = criterion1(output_sys, data)

loss_FCNN.backward() # compute gradients

# check gradients
for name, param in model.named_parameters():
    print(name, param.grad.abs().sum())

for name, param in modelFCNN.named_parameters():
    print(name, param.grad.abs().sum())

Unfortunately, your code isn’t executable in the current form, so could you compare my code snippet to your training?