Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help with Paraview and CGNS files generated with Cassiopee #77

Open
ricardofrantz opened this issue Jul 5, 2024 · 10 comments
Open

Help with Paraview and CGNS files generated with Cassiopee #77

ricardofrantz opened this issue Jul 5, 2024 · 10 comments
Labels
help wanted Extra attention is needed

Comments

@ricardofrantz
Copy link

Hi,

I'm experiencing an issue, and I'm not sure where to post this question, so I'm trying here in the GitHub issues.

We are running simulations with Cassiopee, and I need to export snapshots to open them in ParaView for visualization, such as creating videos.

Issue 1: The contour option in ParaView is not available after opening the CGNS file. Is this a known issue? Are there additional steps or information we need to add to the file to support contour visualization?

Issue 2: How can I open a series of files and add time stamps to them in ParaView?

I am attempting the following, but ParaView does not recognize the time stamps:

This is what I am doing: initialize the time nodes on the tree...

import Converter.PyTree as C
import Converter.Internal as Int
t = C.convertFile2PyTree(input_file)
t = Int.renameNode(t, input_file, "Base")
# https://cgns.github.io/CGNS_docs_current/sids/timedep.html
n = Int.newBaseIterativeData(name="BaseIterativeData", nsteps=1, itype="IterationValues", parent=t)
Int.newDataArray("TimeValues", value=[0.0], parent=n)

and then upon runtime:

def write_snapshot(file_number: int, t: Any, mpi: bool, timestamp: float = 0.0, iteration: int = 0, restart_vars: List[str] = None):
    fname = f"snapshot{file_number:06d}.cgns" if file_number != 0 else "initial_condition.cgns"
    t_export_disk = extract_vars(t, restart_vars) if restart_vars else t
    print0(f'Writing file: {fname} at time: {timestamp:.6f}')

    BaseIterativeData = Int.getNodeFromName(t, "BaseIterativeData")
    IterationValues = Int.getNodeFromName(BaseIterativeData, "IterationValues")
    TimeValues = Int.getNodeFromName(BaseIterativeData, "TimeValues")
    Int.setValue(node=IterationValues, value=iteration)
    Int.setValue(node=TimeValues, value=round(timestamp, 8))

    if mpi:
        Cmpi.convertPyTree2File(t_export_disk, fname)
    else:
        C.convertPyTree2File(t_export_disk, fname)

Any assistance or guidance on these issues would be greatly appreciated.

Thank you!

@benoit128
Copy link
Collaborator

Hi Ricardo,

Concerning the contour option, is your field located in centers or nodes in your cgns file?
If your field is in centers, can you try :
a = C.center2node(a, 'fieldName') before saving to cgns and see if you get the contour option in paraview?

Concerning iterative data, your cgns seems correct. I ll try to get more information.

Have a nice day

@ricardofrantz
Copy link
Author

ricardofrantz commented Jul 8, 2024

Hi Benoit,

Thanks for your time,

I updated my subroutines to move the outpost data to nodes, and it didn't change anything in ParaView.
Maybe I am doing something wrong or removing some other info that may be necessary?

def extract_vars(t: Any, vars: List[str]) -> Any:
    new_vars = ["centers:" + var for var in vars] + ["CoordinateX", "CoordinateY", "CoordinateZ"]
    t_outpost = C.extractVars(t, new_vars) # extract variables
    t_outpost = Cmpi.center2Node(t_outpost, new_vars) # convert centers to nodes
    return C.rmGhostCells(t_outpost, t_outpost, hlo_rhs - 1, adaptBCs=1, modified=[]) # remove ghost cells


def write_snapshot(file_number: int, t: Any, mpi: bool, timestamp: float = 0.0, iteration: int = 0, restart_vars: List[str] = None):

    fname = f"snapshot{file_number:06d}.cgns" if file_number != 0 else "initial_condition.cgns"
    
    t_export_disk = extract_vars(t, restart_vars) if restart_vars else t # full tree if initial condition
    
    print0(f"Writing file: {fname} at time: {timestamp:.6f}")

    # Update the time and iteration values
    BaseIterativeData = Int.getNodeFromName(t, "BaseIterativeData")
    IterationValues = Int.getNodeFromName(BaseIterativeData, "IterationValues")
    TimeValues = Int.getNodeFromName(BaseIterativeData, "TimeValues")
    Int.setValue(node=IterationValues, value=iteration)
    Int.setValue(node=TimeValues, value=round(timestamp, 8))

    if mpi:
        Cmpi.convertPyTree2File(t_export_disk, fname)
    else:
        C.convertPyTree2File(t_export_disk, fname)

Cordialement,
A+
R

@benoit128
Copy link
Collaborator

Hard to say, but if you provide a small cgns file containing your t_outpost, i can try to look at it.
a+

@ricardofrantz
Copy link
Author

Hello,

After further inspection, I can now select Point Arrays alongside Cell Arrays in ParaView. Still, isocontours appear quite erratic, and I am unable to view the time stamps.

Here is a snapshot000008.cgns.zip](https://github.com/user-attachments/files/16128849/snapshot000008.cgns.zip) generated by the routines I shared previously.

Hopefully, your expert eyes can find any inconsistencies.

Thanks for your time,
Ricardo

@benoit128
Copy link
Collaborator

Hi Ricardo,

Here is a short example of BaseIterativeData for 2 zones with 2 times that load in paraview:

import Converter.PyTree as C
import Generator.PyTree as G
import Converter.Internal as Internal

a1 = G.cart((0,0,0), (1,1,1), (10,10,10)); a1[0] = 'cart1'
a2 = G.cart((9,0,0), (1,1,1), (10,10,10)); a2[0] = 'cart2'
t = C.newPyTree(['Base', a1, a2])

# instant must be in differents FlowSolutions
Internal.__FlowSolutionNodes__ = 'FlowSolution#001'
C._initVars(t, '{F}={CoordinateX}')
Internal.__FlowSolutionNodes__ = 'FlowSolution#002'
C._initVars(t, '{F}={CoordinateX}+1')


# add to base
b = Internal.getNodeFromName1(t, 'Base')
it = Internal.newBaseIterativeData(nsteps=2, parent=b)
Internal.createChild(it, 'TimeValues', 'DataArray_t', [0.1, 0.2])
Internal.createChild(it, 'NumberOfZones', 'DataArray_t', 2)
Internal.createChild(it, 'ZonePointers', 'DataArray_t', [['cart1'.ljust(65), 'cart2'.ljust(65)], ['cart1'.ljust(65), 'cart2'.ljust(65)]])

# add to zones
for a in [a1,a2]:
    zt = Internal.newZoneIterativeData(parent=a)
    Internal.createChild(zt, 'FlowSolutionPointers', 'DataArray_t', ['FlowSolution#001'.ljust(32), 'FlowSolution#002'.ljust(32)])

Internal.printTree(t)

C.convertPyTree2File(t, 'out.cgns')

@ricardofrantz
Copy link
Author

Hello,

Thank you very much for your help. Indeed, it works as I expected. However, I believe it would be better to have each snapshot in a separate file rather than in a single file, especially for moving data around. Currently, I am unable to load the files as a group, such as a series of 100 snapshots each with a timestamp.

Best regards,
Ricardo

@benoit128
Copy link
Collaborator

Hi,
Maybe you can try to use links having one master file and different files that store the solution at different times.
For example:

# - HDF write with links -
import Generator.PyTree as G
import Converter.PyTree as C
import Converter.Internal as Internal

a = G.cart((0,0,0),(1,1,1),(50,50,50))
C._initVars(a, 'Density=1.')
t = C.newPyTree(['Base',a])

# Save file with links
links=[['.','coord.hdf','/Base/cart/GridCoordinates','/Base/cart/GridCoordinates']]
C.convertPyTree2File(t, 'main.hdf', links=links)

# Write pointed file
Internal._rmNodeByPath(t, '/Base/cart/FlowSolution')
C.convertPyTree2File(t, 'coord.hdf')

@vincentcasseau
Copy link
Collaborator

Hi @ricardofrantz ,

Isn't your cgns file broken?

cgnsview reports the following errors:

* Checking pyTree [13:58:37]
 - Range of donor BC match3_1 is invalid for zone Zone5.2.
 - Range of donor BC match3_12 is invalid for zone Zone5.2.
 - Range of donor BC match5_24 is invalid for zone Zone4.1.
 - Range of donor BC match6_9 is invalid for zone Zone4.3.
 - Range of donor BC match6_30 is invalid for zone Zone4.3.
 - Range of donor BC match8_25 is invalid for zone zone.
 - Range of donor BC match8_40 is invalid for zone zone.
 - Range of donor BC match8_42 is invalid for zone zone.
 - Range of donor BC match1_0.0 is invalid for zone Zone2.
 - Range of donor BC match1_2.0 is invalid for zone Zone2.
 - Range of donor BC match1_4.0 is invalid for zone Zone2.
 - Range of donor BC match10_41 is invalid for zone Zone5.1.
 - Range of donor BC match10_48 is invalid for zone Zone5.1.
 - Range of donor BC match2_3 is invalid for zone Zone4.2.
 - Range of donor BC match2_8 is invalid for zone Zone4.2.
 - Range of donor BC match7_31 is invalid for zone Zone6.3.
 - Range of donor BC match7_34 is invalid for zone Zone6.3.
 - Range of donor BC match9_17 is invalid for zone zone.0.
 - Range of donor BC match9_43 is invalid for zone zone.0.
 - Range of donor BC match4_16 is invalid for zone Zone6.4.
 - Range of donor BC match11_13 is invalid for zone Zone5.3.
 - Range of donor BC match11_49 is invalid for zone Zone5.3.
 - Range of donor BC match12_5 is invalid for zone Zone6.5.
 - Range of donor BC match12_35 is invalid for zone Zone6.5.

while the mesh connectivity displayed in cassiopee is clearly wrong (see image attached).
This could explain why contours in cassiopee and Paraview aren't drawn properly.

mesh

@vincentcasseau vincentcasseau added the help wanted Extra attention is needed label Aug 5, 2024
@vincentcasseau
Copy link
Collaborator

Hi Ricardo,
Any update on your case?
Thanks,
Vincent

@ricardofrantz
Copy link
Author

Hi Vincent,

We’re in the process of migrating our code to the latest version of Cassiopee. Once the migration is complete, I’ll try again and provide you with feedback.

Best,
R

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants