onera / Fast

Fast CFD solver
https://onera.github.io/Fast/
GNU Lesser General Public License v3.0
14 stars 6 forks source link

display_temporal_criteria provokes segfault for NSTurbulent simple case #13

Open Luispain opened 2 months ago

Luispain commented 2 months ago

Hi everyone,

I came through this issue when making slight adaptions to the provided example # - convergenceHistory (pyTree) -.

I started from such examples, and did slight adaptations :

  1. changed from Euler to NSTurbulent
  2. set modulo_verif = 1
  3. added a wall at imin
  4. added distance to wall
  5. set wall and farfield as families

The script is:


# - convergenceHistory (pyTree) -
import Converter.PyTree as C
import Generator.PyTree as G
import FastS.PyTree as FastS
import FastC.PyTree as FastC
import Connector.PyTree as X
import Converter.Internal as Internal
import Initiator.PyTree as I

ni = 155; dx = 100./(ni-1); dz = 0.01
a1 = G.cart((-50,-50,0.), (dx,dx,dz), (ni,ni,2))

C._addBC2Zone(a1, 'WALL', 'FamilySpecified:WALL', 'imin')
C._fillEmptyBCWith(a1, 'FARFIELD', 'FamilySpecified:FARFIELD', dim=2)
C._addState(a1, 'GoverningEquations', 'NSTurbulent')
I._initConst(a1, MInf=0.4, loc='centers')
C._addState(a1, MInf=0.4)
t = C.newPyTree(['Base', a1])
C._tagWithFamily(t,'FARFIELD')
C._tagWithFamily(t,'WALL')
C._addFamily2Base(t, 'FARFIELD', bndType='BCFarfield')
C._addFamily2Base(t, 'WALL', bndType='BCWall')

import Dist2Walls.PyTree as DTW
walls = C.extractBCOfType(t, 'BCWall')
DTW._distance2Walls(t, walls, loc='centers', type='ortho')

# Numerics
modulo_verif = 1
numb = {}
numb["temporal_scheme"]    = "implicit"
numb["ss_iteration"]       = 3
numb["modulo_verif"]       = modulo_verif
numz = {}
numz["time_step"]          = 0.0007
numz["time_step_nature"]   = "local"
numz["cfl"]                = 4.0
numz["scheme"]             = "roe"
numz["slope"]              = "minmod"
FastC._setNum2Zones(t, numz) ; FastC._setNum2Base(t, numb)

(t, tc, metrics) = FastS.warmup(t, None)

# Number or records to store residuals 
nrec = 100//modulo_verif

#To remove old ConvergenceHistory nodes 
t = C.rmNodes(t, "ZoneConvergenceHistory")

#Convergence history with nrec records
FastS.createConvergenceHistory(t, nrec)

nit = 100; time = 0
time_step = Internal.getNodeFromName(t, 'time_step')
time_step = Internal.getValue(time_step)
for it in range(nit):
    FastS._compute(t, metrics, it, tc)
    if it%modulo_verif == 0:
        FastS.display_temporal_criteria(t, metrics, it)
    time += time_step

# time stamp
Internal.createUniqueChild(t, 'Iteration', 'DataArray_t', value=nit)
Internal.createUniqueChild(t, 'Time', 'DataArray_t', value=time)
C.convertPyTree2File(t, 'out.cgns')

This script provokes segfault at termination (even if everything seems to be ok during computation).

The strange behavior is as follows: if we supress the line FastS.display_temporal_criteria(t, metrics, it), then the segfault dissappears.

Run on ONERA LD machine using cassiopee v4 environment.

Thank you in advance for your help,

Luis

IvanMary69 commented 2 months ago

hello,

did you try to suppress the convergenceHistory node before the call to warmup function?

Ivan

Luispain commented 2 months ago

Hi Ivan,

I tried what you said, removing convergenceHistory nodes before the coll to warmup function but it does not seem to work either :


# - convergenceHistory (pyTree) -
import Converter.PyTree as C
import Generator.PyTree as G
import FastS.PyTree as FastS
import FastC.PyTree as FastC
import Connector.PyTree as X
import Converter.Internal as Internal
import Initiator.PyTree as I

ni = 155; dx = 100./(ni-1); dz = 0.01
a1 = G.cart((-50,-50,0.), (dx,dx,dz), (ni,ni,2))

C._addBC2Zone(a1, 'WALL', 'FamilySpecified:WALL', 'imin')
C._fillEmptyBCWith(a1, 'FARFIELD', 'FamilySpecified:FARFIELD', dim=2)
C._addState(a1, 'GoverningEquations', 'NSTurbulent')
I._initConst(a1, MInf=0.4, loc='centers')
C._addState(a1, MInf=0.4)
t = C.newPyTree(['Base', a1])
C._tagWithFamily(t,'FARFIELD')
C._tagWithFamily(t,'WALL')
C._addFamily2Base(t, 'FARFIELD', bndType='BCFarfield')
C._addFamily2Base(t, 'WALL', bndType='BCWall')

import Dist2Walls.PyTree as DTW
walls = C.extractBCOfType(t, 'BCWall')
DTW._distance2Walls(t, walls, loc='centers', type='ortho')

# Numerics
modulo_verif = 1
numb = {}
numb["temporal_scheme"]    = "implicit"
numb["ss_iteration"]       = 3
numb["modulo_verif"]       = modulo_verif
numz = {}
numz["time_step"]          = 0.0007
numz["time_step_nature"]   = "local"
numz["cfl"]                = 4.0
numz["scheme"]             = "roe"
numz["slope"]              = "minmod"
FastC._setNum2Zones(t, numz) ; FastC._setNum2Base(t, numb)

#To remove old ConvergenceHistory nodes 
t = C.rmNodes(t, "ZoneConvergenceHistory")

(t, tc, metrics) = FastS.warmup(t, None)

# Number or records to store residuals 
nrec = 100//modulo_verif

#Convergence history with nrec records
FastS.createConvergenceHistory(t, nrec)

nit = 100; time = 0
time_step = Internal.getNodeFromName(t, 'time_step')
time_step = Internal.getValue(time_step)
for it in range(nit):
    FastS._compute(t, metrics, it, tc)
    if it%modulo_verif == 0:
        FastS.display_temporal_criteria(t, metrics, it)
    time += time_step

# time stamp
Internal.createUniqueChild(t, 'Iteration', 'DataArray_t', value=nit)
Internal.createUniqueChild(t, 'Time', 'DataArray_t', value=time)
C.convertPyTree2File(t, 'out.cgns')

I still have the segmentation fault at iteration 85.

Luis

Luispain commented 1 month ago

Hello, for information this script works with nrec=10 but fails with 1, 2, 5... (I would like to have residuals at each iteration, so I guess I need nrec=1 ):


# - convergenceHistory (pyTree) -
import numpy
import Converter.PyTree as C
import Generator.PyTree as G
import FastS.PyTree as FastS
import FastC.PyTree as FastC
import Connector.PyTree as X
import Converter.Internal as I
import Initiator.PyTree as Init

def _createConvergenceHistory(t, nrec):
    """Create a node in tree to store convergence history."""
    varsR   = ['RSD_L2','RSD_oo','RSD_L2_diff','RSD_oo_diff']
    bases   = I.getNodesFromType1(t, 'CGNSBase_t')
    curIt   = 0
    for b in bases:
       I.createUniqueChild(b, 'GlobalConvergenceHistory',
                              'ConvergenceHistory_t', value=curIt)

       model='Nada'
       a = I.getNodeFromName2(t, 'GoverningEquations')
       if a is not None: model = I.getValue(a)

       for z in I.getZones(b):

          a = I.getNodeFromName2(z, 'GoverningEquations')
          if a is not None: model = I.getValue(a)
          neq = 5
          if model == 'nsspalart' or model =='NSTurbulent': neq = 6

          c = I.createUniqueChild(z, 'ZoneConvergenceHistory',
                                     'ConvergenceHistory_t', value=curIt)
          tmp = numpy.zeros((nrec), numpy.int32)
          I.createChild(c, 'IterationNumber', 'DataArray_t', tmp)
          for var in varsR:
            tmp = numpy.zeros((nrec*neq), numpy.float64)
            I.createChild(c, var ,'DataArray_t', tmp)

npts = 5
dx = 0.5
z = G.cart((0.0,0.0,0.0), (dx,dx,dx), (npts,npts,npts))
C._addBC2Zone(z, 'WALL', 'FamilySpecified:WALL', 'imin')
C._fillEmptyBCWith(z, 'FARFIELD', 'FamilySpecified:FARFIELD', dim=3)
C._addState(z, 'GoverningEquations', 'NSTurbulent')

Init._initConst(z, MInf=0.4, loc='centers')
C._addState(z, MInf=0.4)
t = C.newPyTree(['Base', z])
C._tagWithFamily(t,'FARFIELD')
C._tagWithFamily(t,'WALL')
C._addFamily2Base(t, 'FARFIELD', bndType='BCFarfield')
C._addFamily2Base(t, 'WALL', bndType='BCWall')

import Dist2Walls.PyTree as DTW
walls = C.extractBCOfType(t, 'BCWall')
DTW._distance2Walls(t, walls, loc='centers', type='ortho')

numb = { 'temporal_scheme': 'implicit', 'ss_iteration':3, 'modulo_verif':1}
numz = { 'scheme':'roe', 'slope':'minmod',
    'time_step':0.0007,'time_step_nature':'local', 'cfl':4}
FastC._setNum2Zones(t, numz); FastC._setNum2Base(t, numb)

(t, tc, metrics) = FastS.warmup(t, None)

# Number or records to store residuals 
nrec = 10 # works with 10, but crashes with 1, 2, 5...

#To remove old ConvergenceHistory nodes 
t = C.rmNodes(t, "ZoneConvergenceHistory")

#Convergence history with nrec records
# FastS.createConvergenceHistory(t, nrec)
_createConvergenceHistory(t, nrec)

nit = 100; time = 0
time_step = I.getNodeFromName(t, 'time_step')
time_step = I.getValue(time_step)
for it in range(nit):
    FastS._compute(t, metrics, it, tc)
    if it%nrec == 0:
        FastS.display_temporal_criteria(t, metrics, it, format='store')
    time += time_step

# time stamp
I.createUniqueChild(t, 'Iteration', 'DataArray_t', value=nit)
I.createUniqueChild(t, 'Time', 'DataArray_t', value=time)
C.convertPyTree2File(t, 'out.cgns')
IvanMary69 commented 1 month ago

Normal, nrec should be equal (or larger) than the number of iteration (nit) you want.

If you want to store the residual every iteration, then Nrec=nit. Don't forget that residu are compute only every "modulo_verif" iteration.

Therefore a good value for nrec is: nit//modulo_verif

Luispain commented 1 month ago

ok ! I got the logic now, thank you. It does not crash anymore but I still have one more issue : the residuals contains all nan values:

typezone: 3D cartesian with constant step, cart (0, 0, 0)
Info: using layer trans=c (ompmode=0)
Writing out.cgns (bin_cgns)...done.
[nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 
 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan
 nan nan nan nan nan nan]

I guess there is still some issue. Here is the updated script :


# - convergenceHistory (pyTree) -
import numpy
import Converter.PyTree as C
import Generator.PyTree as G
import FastS.PyTree as FastS
import FastC.PyTree as FastC
import Connector.PyTree as X
import Converter.Internal as I
import Initiator.PyTree as Init

def _createConvergenceHistory(t, nrec):
    """Create a node in tree to store convergence history."""
    varsR   = ['RSD_L2','RSD_oo','RSD_L2_diff','RSD_oo_diff']
    bases   = I.getNodesFromType1(t, 'CGNSBase_t')
    curIt   = 0
    for b in bases:
       I.createUniqueChild(b, 'GlobalConvergenceHistory',
                              'ConvergenceHistory_t', value=curIt)

       model='Nada'
       a = I.getNodeFromName2(t, 'GoverningEquations')
       if a is not None: model = I.getValue(a)

       for z in I.getZones(b):

          a = I.getNodeFromName2(z, 'GoverningEquations')
          if a is not None: model = I.getValue(a)
          neq = 5
          if model == 'nsspalart' or model =='NSTurbulent': neq = 6

          c = I.createUniqueChild(z, 'ZoneConvergenceHistory',
                                     'ConvergenceHistory_t', value=curIt)
          tmp = numpy.zeros((nrec), numpy.int32)
          I.createChild(c, 'IterationNumber', 'DataArray_t', tmp)
          for var in varsR:
            tmp = numpy.zeros((nrec*neq), numpy.float64)
            I.createChild(c, var ,'DataArray_t', tmp)

npts = 5
dx = 0.5
z = G.cart((0.0,0.0,0.0), (dx,dx,dx), (npts,npts,npts))
C._addBC2Zone(z, 'WALL', 'FamilySpecified:WALL', 'imin')
C._fillEmptyBCWith(z, 'FARFIELD', 'FamilySpecified:FARFIELD', dim=3)
C._addState(z, 'GoverningEquations', 'NSTurbulent')

Init._initConst(z, MInf=0.4, loc='centers')
C._addState(z, MInf=0.4)
t = C.newPyTree(['Base', z])
C._tagWithFamily(t,'FARFIELD')
C._tagWithFamily(t,'WALL')
C._addFamily2Base(t, 'FARFIELD', bndType='BCFarfield')
C._addFamily2Base(t, 'WALL', bndType='BCWall')

import Dist2Walls.PyTree as DTW
walls = C.extractBCOfType(t, 'BCWall')
DTW._distance2Walls(t, walls, loc='centers', type='ortho')

numb = { 'temporal_scheme': 'implicit', 'ss_iteration':3, 'modulo_verif':1}
numz = { 'scheme':'roe', 'slope':'minmod',
    'time_step':0.0007,'time_step_nature':'local', 'cfl':4}
FastC._setNum2Zones(t, numz); FastC._setNum2Base(t, numb)

(t, tc, metrics) = FastS.warmup(t, None)

nit = 10; time = 0

#To remove old ConvergenceHistory nodes 
t = C.rmNodes(t, "ZoneConvergenceHistory")

_createConvergenceHistory(t, nit)

time_step = I.getNodeFromName(t, 'time_step')
time_step = I.getValue(time_step)
for it in range(nit):
    FastS._compute(t, metrics, it, tc)
    FastS.display_temporal_criteria(t, metrics, it, format='store')
    time += time_step

# time stamp
I.createUniqueChild(t, 'Iteration', 'DataArray_t', value=nit)
I.createUniqueChild(t, 'Time', 'DataArray_t', value=time)
C.convertPyTree2File(t, 'out.cgns')

RSD_L2 = I.getNodeFromName(t,'RSD_L2')[1]
print(RSD_L2)
IvanMary69 commented 1 month ago

npts=5 too small. Only ghostcell in that case;

try npts=9 or larger

Luispain commented 1 month ago

oh thank you !! Now I have positive finite values of residuals, perfect !

Looking forward to the official update of _createConvergenceHistory. For the moment I will use the proposed workaround.

Best regards

Luis

vincentcasseau commented 2 weeks ago

See update in Issue #14