(CGNS) Is it possible to load a mesh with Cell-Centered solution and display the values in boundary patches?

Greetings to all people here!

Some time ago I created a thread here, asking for help in properly displaying boundary patches from a CGNS file in ParaView.

The aforementioned thread is this one:

My new question is kind of a follow-up to that thread, but since that thread provided a complete solution I figured I’d leave it as is and create a new thread for my new question.

What I want to do

I want to, if possible, display variables on boundary patches in a CGNS file that contains a CellCenter solution.

What is the current situation

Per the replies on the previous thread, displaying variables in boundary patches requires a Vertex based solution in the CGNS file.
When I posted the previous thread I was working on a node-based solver and thus I was able to turn patches on and off and view the solution accordingly.

However, I now also have to work on a cell-based solver.
ParaView is, of course, able to pickup the boundary patches (via the FamilySpecified route discussed in the previous thread), however it cannot display the solution on boundary patches.
This is completely expected, since the values on boundary faces cannot be directly derived from the CellCenter solution in volume elements.

What I’ve tried thus far

Since there is no official CGNS for ParaView documentation, I tried to find a way to make this work.

Using Cell Data to Point Data in ParaView → Does not work

At first, I figured that if I convert the Cell solution to a Point solution I would be able to visualize variables in boundary patches.
Unfortunately, this does not work. If you use the filter to convert the solution from Cells to Points, it only converts the solution in the Volume Mesh, not on boundary patches.

As far as I can tell, ParaView loads the volume and boundary meshes as separate entities.
One can verify this by examining the total number of Cells and Nodes before and after the Load Patches option.
If Load Patches is turned on, the total number of nodes is multiplied by the number of patches.
This implies that ParaView takes all nodes and stores them independently for each boundary patch.
Thus, if you convert Cell Data To Point Data, it only affects the volume mesh.
Boundary patch meshes are not affected.

Resampling from volume mesh to the boundary meshes → Does not work

I also gave this hacky way a try, of course it doesn’t work.
For a given mesh, the boundary is not surrounded by any cell (since it is in the boundary).
Thus the resampling does not return anything.

Using the official CGNS ParentData array for boundary elements → Does not work

CGNS provides the option to store parent elements for boundary patches.
For each boundary element (face), the neighbor volume cell elements are given, in addition to the corresponding number of cell-face that the boundary face matches to.

Unfortunately, ParaView still does not seem to pickup the solution.
The corresponding functionality is probably not implemented in the CGNS reader.

Converting the CellCenter solution to a Vertex solution using CGNStools → Works, but is kinda slow

By using the convert_location utility provided by the CGNS library, one can convert a CellCenter solution to a Vertex solution. ParaView then can display variables on patches accordingly.

This option works but the convert_location utility is kinda slow, converting the solution on large datasets takes a lot of time. However, it only needs to be done once for each solution file.

What other options are there, if any?

Is there anything else I can try?
Fortunately, the convert_solution utility can kinda do the trick.
However, perhaps there’s a way to do this more elegantly.
Converting the solution can take a couple of hours for large datasets.

@MicK7 Tagging you here since you wrote the CGNS reader and you helped me out in the previous thread!

Hi @SadBoySquad

Please share your data

Best,

Hello @SadBoySquad,

I’m not sure if this could suit your needs, but here is a small example file that is used for testing.
This file uses BCNeumann boundary conditions with values on the faces (GridLocation is FaceCenter).

VTK_BCNeumannUnstructuredQuads.cgns (29.1 KB)

BCDirichlet and BCNeumann support has been added recently so you might need to use a nightly version of ParaView or a recent build if you are building the application yourself.

@mwestphal

Here is a sample file:

It is the SC10_steady.cgns file downloaded from the CGNS examples (the 4th file in the “Unstructured Grid Examples” in the lower half of the page).
The link for the sample is the following:
https://cgns.github.io/CGNSFiles.html

I only modified the initial sample file to have “Family Specified” boundary conditions.

As expected, the solution cannot be displayed on Boundary Patches (and why would it, ParaView cannot know how to match the boundary patches to the CellCenter solution).

I think the format you propose has a different objective than what I want to achieve.

The format with NeumannData and DirichletData aims at giving the user information on applying boundary conditions.
For example, it can give the Dirichlet value for Temperature in a boundary that has fixed Temperature throughout the simulation.
Or it can give a scalar derivative via a the Neumann specification.

However, what I want to display is the Solution on the boundary.
For a Cell-Based solver, this would essentially be the value of the corresponding internal Cell that the boundary Face belongs to.
For a Vertex-Based solver the implementations can vary, however the most common option is to not assign dirichlet values to boundary nodes themselves but instead use flux schemes to upwind boundary values from ghost nodes towards boundary nodes.
Therefore, boundary values change with the solution.

Oh thanks for the explanation, I see what you mean now :slightly_smiling_face:

As you said, in ParaView, the boundary patches are separate from the volume cells and are not aware of each other.

I suggest the following solution:

  1. Use “Extract Block” on the CGNS output to extract the volume mesh (“Internal” block)
  2. Use “Extract Block” on the CGNS output to extract the boundary patches (“Patches” block(s))
  3. Use “Resample with Dataset” with the output of step 1 as “Source Data Arrays” and the output of step 2 as “Destination Mesh” when prompted

Your solution works and, since ParaView can be launched in parallel mode, is probably much more efficient than using the serial convert_location utility from CGNStools.

Unless there is a way that is able to directly display CellCenter values from a Solution node on boundary patches, I think this would be a good workaround.

Thank you! :slight_smile:

p.s. #1
For better surface visualization, I think that converting from Cell Data to Point data before extracting blocks provides a smoother contour of variables.

p.s. #2
The solution you provided is very straightforward and simple, however I never though to extract both the internal mesh and the patches and then use Resample with Dataset.
As per my initial post, I tried extracting a patch and Resampling from the initial file to the extracted patch, but I got nothing.
Why does one need to extract both the Internal Mesh and the Patches in order to Resample correctly?

You’re welcome! :slightly_smiling_face:

Digging a little into the code, it seems that this is caused by the fact that the arrays are partial here, because they are not defined on the boundary patches.
A piece of the documentation for vtkCompositeDataProbeFilter says:

When dealing with composite datasets, partial arrays are common i.e.
data-arrays that are not available in all of the blocks. By default, this
filter only passes those point and cell data-arrays that are available in all
the blocks i.e. partial arrays are removed.

So using the output of the CGNS reader directly won’t resample the partial arrays.

Hey Mathieu, did you manage to check the file I provided?
Is there another way to do this, or do I have to adopt the “Interpolation” route?

You are not completely right NeumannData and DirichletData can be use to provide field for the solver at boundary conditions. But since they accept multiple containers, the solver can also provide face center or vertex solution in a BCDataSet CGNS node that paraview will be able to load.
BCDataSet are just container for the BC data.