This is an old question but I struggled with the same thing so I thought I'd share what I did. Eonasdan's answer is right on. In my case I added code to the subGridRowExpanded and subGridRowCollapsed events to store the row ID of the row which have been expanded (I only allowed one row to be expanded at a time, but you could use a collection as well). Then I added code to the loadComplete event for the table to re-open the row that collapsed after the postback. That part is all obvious, but here are the two kickers:
1. Re-expanding the subgrid doesn't cause its data to be persisted for some reason. So I had to go back to the server to get it. I did that by resubmitting the subgrid row (which has an id of the grid an underscore and the rowid).
2. For some reason you have to use a timer and expand the subgrid after a delay (even 1ms seems to work). It is like you can't expand the grid during the loadComplete event itself, but if you wait a tick then it works fine.
So like this:
var expandSubGrid = function(){
$('#grid').jqGrid('expandSubGridRow', expandedRowID);
$('#grid_' + expandedRowID).trigger('reloadGrid');
};
//the loadComplete event handler which was wired up when I created the grid
var grid_loadComplete = function () {
//expand the subgrid
window.setTimeout(expandSubGrid, 1);
};