Dear Chris,
Function 'fullyconnect' returns only a single output argument, see the following documentation page for more information,
and that is the cause of the error you are receiving when trying to include additional output arguments. Function 'fullyconnect' is used to sum all the weighted input data and apply a bias, as mentioned in the latter documentation page.
In that sense, the output argument 'dlU' should contain all the necessary components for the problem at hand and there should not be any additional output argument.
What needs to be modified in this case is the layer architecture so that it allows for three input channels (X-, Y-components and time) while it subsequently it also allows for three output channels (U-, V-components of the velocity and pressure). To account for these three input channels, the following lines of code for the shipping 1D Burger's example,
parameters.fc1.Weights = initializeHe(sz,2);
parameters.fc1.Bias = initializeZeros([numNeurons 1]);
need to be changed to,
parameters.fc1.Weights = initializeHe(sz,2);
parameters.fc1.Bias = initializeZeros([numNeurons 1]);
In this way, the 'dlarray' containing the spatial coordinates of the collocation points that are used for the training should no longer be defined as in the shipping 1D Burger's example, namely,
but as follows,
dlX0 = dlarray([X0; Y0],'CB');
where 'Y0' is a vector containing all the Y-components of your collocation points. This vector should be created in the same manner as vector 'X0' and all other 'dlarray' objects containing such spatial information should be extended accordingly. This is herein necessary since the input layer of your deep neural network expects three input channels.
Next, the output layer of your deep neural network should be changed in order to account for three output channels (U-, V-components of the velocity and pressure) instead of just one channels as for the shipping 1D Burger's example. In this way, the following lines of code of the shipping example,
parameters.("fc" + numLayers).Weights = initializeHe(sz,numIn);
parameters.("fc" + numLayers).Bias = initializeZeros([1 1]);
needs to be changed to the following,
parameters.("fc" + numLayers).Weights = initializeHe(sz,numIn);
parameters.("fc" + numLayers).Bias = initializeZeros([3 1]);
where both the number of channels for the input to the final fully connected layer and the number of biases needs to be modified accordingly.
Having made these changes, there should be applied no actual change in the function 'model', as the fully connected operations should already result into three outputs. The output of the last 'fullyconnect' call in the following loop (i.e. 'i = numLayers') within the 'model' function,
weights = parameters.(name).Weights;
bias = parameters.(name).Bias;
dlU = fullyconnect(dlU, weights, bias);
should herein result into a 3(C) × 1000(B) (instead of a 1(C) x 1000(B)) 'dlarray' object, where the first channel corresponds to the U-components of the velocity field, the second channel corresponds to the V-components of the velocity field and finally the third channel corresponds to the pressure field.
These are in principle the structural changes that need to be applied in order to have the appropriate sizes of the arrays for your particular problem at hand. However, the following changes need to be made in addition,
1.) The function 'solveBurgers' from the shipping 1D Burger's example should be changed to your particular PDE, namely the 2D Navier-Stokes equation,
2.) The function 'modelGradients' from the shipping 1D Burger's example should be changed to account for the loss based on the 2D Navier-Stokes equation.
Lastly, the current layer architecture with the nine fully connected layers might not be appropriate for your particular problem at hand. In this case you may need to adjust the layer architecture accordingly.
I hope that this information helps.
Kind regards,
Andreas