diff --git a/avaframe/com1DFA/com1DFA.py b/avaframe/com1DFA/com1DFA.py index 9285a99b7..c0eda26d4 100644 --- a/avaframe/com1DFA/com1DFA.py +++ b/avaframe/com1DFA/com1DFA.py @@ -1658,8 +1658,11 @@ def initializeFields(cfg, dem, particles, releaseLine): cfgGen = cfg["GENERAL"] # what result types are desired as output (we need this to decide which fields we actually need to compute) resTypes = fU.splitIniValueToArraySteps(cfgGen["resType"]) - resTypesReport = fU.splitIniValueToArraySteps(cfg["REPORT"]["plotFields"]) - resTypesLast = list(set(resTypes + resTypesReport)) + # ensure at least one field type is present for internal computations + # if resTypes only contains particles add pfv + validFieldTypes = [rt for rt in resTypes if rt not in ["particles"]] + if len(validFieldTypes) == 0: + resTypes.append("pfv") # read dem header header = dem["header"] ncols = header["ncols"] @@ -1684,7 +1687,7 @@ def initializeFields(cfg, dem, particles, releaseLine): fields["timeInfo"] = np.zeros((nrows, ncols)) # first time # for optional fields, initialize with dummys (minimum size array). The cython functions then need something # even if it is empty to run properly - if ("TA" in resTypesLast) or ("pta" in resTypesLast): + if ("TA" in resTypes) or ("pta" in resTypes): fields["pta"] = np.zeros((nrows, ncols)) # peak travel angle [°] fields["TA"] = np.zeros((nrows, ncols)) # travel angle [°] fields["computeTA"] = True @@ -1693,14 +1696,14 @@ def initializeFields(cfg, dem, particles, releaseLine): fields["pta"] = np.zeros((1, 1)) fields["TA"] = np.zeros((1, 1)) fields["computeTA"] = False - if "pke" in resTypesLast: + if "pke" in resTypes: fields["pke"] = np.zeros((nrows, ncols)) # peak kinetic energy [kJ/m²] fields["computeKE"] = True log.debug("Computing Kinetic energy") else: fields["pke"] = np.zeros((1, 1)) fields["computeKE"] = False - if ("P" in resTypesLast) or ("ppr" in resTypesLast): + if ("P" in resTypes) or ("ppr" in resTypes): fields["P"] = np.zeros((nrows, ncols)) # pressure [kPa] fields["ppr"] = np.zeros((nrows, ncols)) # peak pressure [kPa] fields["computeP"] = True @@ -2038,10 +2041,11 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si # add particles to the results type if trackParticles option is activated if cfg.getboolean("TRACKPARTICLES", "trackParticles"): resTypes = list(set(resTypes + ["particles"])) - # make sure to save all desiered resuts for first and last time step for - # the report - resTypesReport = fU.splitIniValueToArraySteps(cfg["REPORT"]["plotFields"]) - resTypesLast = list(set(resTypes + resTypesReport)) + # ensure at least one field type is present for internal computations + # if resTypes only contains particles, add pfv + validFieldTypes = [rt for rt in resTypes if rt not in ["particles"]] + if len(validFieldTypes) == 0: + resTypes.append("pfv") # derive friction type # turn friction model into integer frictModelsList = [ @@ -2080,7 +2084,7 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si pfvTimeMax = [] # setup a result fields info data frame to save max values of fields and avalanche front - resultsDF = setupresultsDF(resTypesLast, cfg["VISUALISATION"].getboolean("createRangeTimeDiagram")) + resultsDF = setupresultsDF(resTypes, cfg["VISUALISATION"].getboolean("createRangeTimeDiagram")) # Add different time stepping options here log.debug("Use standard time stepping") @@ -2094,15 +2098,27 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si t = particles["t"] log.debug("Saving results for time step t = %f s", t) - # export initial time step - if cfg["EXPORTS"].getboolean("exportData"): + # Initialize particles output directory if needed + if "particles" in resTypes: + outDirData = outDir / "particles" + fU.makeADir(outDirData) + + # Save original dtSave for initial timestep decisions + dtSaveOriginal = dtSave.copy() + + # export initial time step only if t=0 is explicitly in dtSaveOriginal + if cfg["EXPORTS"].getboolean("exportData") and ( + dtSaveOriginal.size > 0 and np.any(dtSaveOriginal <= 1.0e-8) + ): exportFields(cfg, t, fields, dem, outDir, cuSimName, TSave="initial") if "particles" in resTypes: - outDirData = outDir / "particles" - fU.makeADir(outDirData) savePartToPickle(particles, outDirData, cuSimName) + # Update dtSave to remove the initial timestep we just saved + dtSave = updateSavingTimeStep(dtSaveOriginal, cfgGen, t) + + # export particles properties for visulation if cfg["VISUALISATION"].getboolean("writePartToCSV"): particleTools.savePartToCsv( @@ -2128,8 +2144,12 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si ) cfgRangeTime["GENERAL"]["simHash"] = simHash - # add initial time step to Tsave array - Tsave = [0] + # add initial time step to Tsave array only if it was exported + if dtSaveOriginal.size > 0 and np.any(dtSaveOriginal <= 1.0e-8): + Tsave = [0] + else: + Tsave = [] + # derive time step for first iteration if cfgGen.getboolean("sphKernelRadiusTimeStepping"): dtSPHKR = tD.getSphKernelRadiusTimeStep(dem, cfgGen) @@ -2166,7 +2186,7 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si rangeValue = mtiInfo["rangeList"][-1] else: rangeValue = "" - resultsDF = addMaxValuesToDF(resultsDF, fields, t, resTypesLast, rangeValue=rangeValue) + resultsDF = addMaxValuesToDF(resultsDF, fields, t, resTypes, rangeValue=rangeValue) tCPU["nSave"] = nSave particles["t"] = t @@ -2348,25 +2368,19 @@ def DFAIterate(cfg, particles, fields, dem, inputSimLines, outDir, cuSimName, si # export particles dictionaries of saving time steps if "particles" in resTypes: savePartToPickle(particles, outDirData, cuSimName) - else: - # fetch contourline info + + # save contour line for each sim only if the field is properly computed (not a dummy array) + contourResType = cfg["VISUALISATION"]["contourResType"] + if fields[contourResType].shape != (1, 1): contourDictXY = outCom1DFA.fetchContCoors( dem["header"], - fields[cfg["VISUALISATION"]["contourResType"]], + fields[contourResType], cfg["VISUALISATION"], cuSimName, ) - - # save contour line for each sim - contourDictXY = outCom1DFA.fetchContCoors( - dem["header"], - fields[cfg["VISUALISATION"]["contourResType"]], - cfg["VISUALISATION"], - cuSimName, - ) - outDirDataCont = outDir / "contours" - fU.makeADir(outDirDataCont) - saveContToPickle(contourDictXY, outDirDataCont, cuSimName) + outDirDataCont = outDir / "contours" + fU.makeADir(outDirDataCont) + saveContToPickle(contourDictXY, outDirDataCont, cuSimName) # export particles properties for visulation if cfg["VISUALISATION"].getboolean("writePartToCSV"): @@ -2406,7 +2420,7 @@ def setupresultsDF(resTypes, cfgRangeTime): # TODO catch empty resTypes resDict = {"timeStep": [0.0]} for resT in resTypes: - if resT != "particles" and resT != "FTDet": + if resT != "particles": resDict["max" + resT] = [0.0] if cfgRangeTime: resDict["rangeList"] = [0.0] @@ -2440,11 +2454,12 @@ def addMaxValuesToDF(resultsDF, fields, timeStep, resTypes, rangeValue=""): newLine = [] for resT in resTypes: - if resT != "particles" and resT != "FTDet": + if resT != "particles": newLine.append(np.nanmax(fields[resT])) if rangeValue != "": newLine.append(rangeValue) + resultsDF.loc[timeStep] = newLine return resultsDF @@ -2973,17 +2988,15 @@ def exportFields( """ resTypesGen = fU.splitIniValueToArraySteps(cfg["GENERAL"]["resType"]) - resTypesReport = fU.splitIniValueToArraySteps(cfg["REPORT"]["plotFields"]) if "particles" in resTypesGen: resTypesGen.remove("particles") - if "particles" in resTypesReport: - resTypesReport.remove("particles") - if TSave == "final" or TSave == "initial": - # for last time step we need to add the report fields - resTypes = list(set(resTypesGen + resTypesReport)) - else: - resTypes = resTypesGen + resTypes = resTypesGen + # ensure at least one field type is present for export + # if resTypes only contains FTDet or is empty, add pfv + validFieldTypes = [rt for rt in resTypes if rt != "particles"] + if len(validFieldTypes) == 0: + resTypes.append("pfv") if resTypesForced != []: resTypes = resTypesForced diff --git a/avaframe/com1DFA/com1DFACfg.ini b/avaframe/com1DFA/com1DFACfg.ini index c9e9cd5e9..14937e5de 100644 --- a/avaframe/com1DFA/com1DFACfg.ini +++ b/avaframe/com1DFA/com1DFACfg.ini @@ -13,11 +13,11 @@ modelType = dfa #+++++++++++++ Output++++++++++++ # desired result Parameters (ppr, pft, pfv, pta, FT, FV, P, FM, Vx, Vy, Vz, TA, dmDet, sfcChange, demAdapted, timeInfo, particles) - separated by | resType = ppr|pft|pfv|timeInfo -# saving time step, i.e. time in seconds (first and last time step are always saved) +# saving time step, i.e. time in seconds (last time step is always saved; initial time step only if explicitly specified) # option 1: give an interval with start:interval in seconds (tStep = 0:5 - this will save desired results every 5 seconds for the full simulation) -# option 2: explicitly list all desired time steps (closest to actual computational time step) separated by | (example tSteps = 1|50.2|100) -# NOTE: initial and last time step are always saved! -tSteps = 1 +# option 2: explicitly list all desired time steps (closest to actual computational time step) separated by | (example tSteps = 1|50.2|100 or tSteps = 0|5|10 to include initial timestep) +# NOTE: last time step is always saved! Initial timestep (t=0) is only saved if explicitly included in tSteps +tSteps = #++++++++++++++++ particle Initialisation +++++++++ # initial particle distribution, options: random, semirandom, uniform, triangular @@ -544,16 +544,6 @@ releaseScenario = # important for parameter variation through probRun thFromIni = - -[REPORT] -# which result parameters shall be included as plots in report - separated by | -plotFields = ppr|pft|pfv -# units for output variables -unitppr = kPa -unitpft = m -unitpfv = ms-1 - - [EXPORTS] # peak files and plots are exported, option to turn off exports when exportData is set to False # this affects export of peak files and also generation of peak file plots diff --git a/avaframe/com3Hybrid/com3HybridCfg.ini b/avaframe/com3Hybrid/com3HybridCfg.ini index 31983cb54..032be1938 100644 --- a/avaframe/com3Hybrid/com3HybridCfg.ini +++ b/avaframe/com3Hybrid/com3HybridCfg.ini @@ -97,9 +97,6 @@ frictModel = Coulomb # tan of bed friction angle used for: samosAT, Coulomb, Voellmy mucoulomb = 0.4 -# which result parameters shall be included as plots in report, - separated by | -plotFields = ppr|pft|pfv|TA|pta - [com2AB_com2AB_override] # use default com2AB config as base configuration (True) and override following parameters diff --git a/avaframe/com6RockAvalanche/com6RockAvalancheCfg.ini b/avaframe/com6RockAvalanche/com6RockAvalancheCfg.ini index 1ccf70d93..852e8fc12 100644 --- a/avaframe/com6RockAvalanche/com6RockAvalancheCfg.ini +++ b/avaframe/com6RockAvalanche/com6RockAvalancheCfg.ini @@ -48,6 +48,3 @@ frictModel = Voellmy #+++++++++++++Voellmy friction model muvoellmy = 0.035 xsivoellmy = 700. - -# which result parameters shall be included as plots in report, - separated by | -plotFields = pfv|pft|FT diff --git a/avaframe/in3Utils/fileHandlerUtils.py b/avaframe/in3Utils/fileHandlerUtils.py index 1f217df5e..1c1b76b71 100644 --- a/avaframe/in3Utils/fileHandlerUtils.py +++ b/avaframe/in3Utils/fileHandlerUtils.py @@ -384,9 +384,6 @@ def splitTimeValueToArrayInterval(cfgValues, endTime): items = np.array(itemsL, dtype=float) items = np.sort(items) - # make sure that 0 is not in the array (initial time step is any ways saved) - if items[0] == 0: - items = np.delete(items, 0) # make sure the array is not empty # ToDo : make it work without this arbitrary 2*timeEnd if items.size == 0: diff --git a/avaframe/log2Report/generateReport.py b/avaframe/log2Report/generateReport.py index b260c6ee4..00ea810fd 100644 --- a/avaframe/log2Report/generateReport.py +++ b/avaframe/log2Report/generateReport.py @@ -203,7 +203,7 @@ def writeReport(outDir, reportDictList, reportOneFile, plotDict='', standaloneRe # Loop through all simulations for reportD in reportDictList: - if plotDict != '' and ('simName' in reportD): + if plotDict != '' and ('simName' in reportD) and (reportD['simName']['name'] in plotDict): # add plot info to general report Dict reportD['Simulation Results'] = plotDict[reportD['simName']['name']] reportD['Simulation Results'].update({'type': 'image'}) @@ -222,7 +222,7 @@ def writeReport(outDir, reportDictList, reportOneFile, plotDict='', standaloneRe # Loop through all simulations for reportD in reportDictList: - if plotDict != '': + if plotDict != '' and (reportD['simName']['name'] in plotDict): # add plot info to general report Dict reportD['Simulation Results'] = plotDict[reportD['simName']['name']] reportD['Simulation Results'].update({'type': 'image'}) diff --git a/avaframe/tests/test_com1DFA.py b/avaframe/tests/test_com1DFA.py index ee2fa9713..33374be59 100644 --- a/avaframe/tests/test_com1DFA.py +++ b/avaframe/tests/test_com1DFA.py @@ -1395,7 +1395,7 @@ def test_initializeParticles(): # setup required input cfg = configparser.ConfigParser() - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv"} + cfg["REPORT"] = {} cfg["GENERAL"] = { "resType": "ppr|pft|pfv", "rho": "200.", @@ -1746,8 +1746,8 @@ def test_exportFields(tmp_path): # setup required input cfg = configparser.ConfigParser() - cfg["GENERAL"] = {"resType": "ppr|pft|FT"} - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv|pke"} + cfg["GENERAL"] = {"resType": "ppr|pft|FT|pfv|pke"} + cfg["REPORT"] = {} cfg["EXPORTS"] = {"useCompression": "True"} Tsave = [0, 10, 15, 25, 40] demHeader = {} @@ -1837,13 +1837,15 @@ def test_exportFields(tmp_path): assert np.array_equal(fieldFinal, pprFinal) assert np.array_equal(field10, pftt10) - assert len(fieldsListTest) == 8 + # With new behavior: both intermediate and final export all fields from resType + # resType has 5 fields (ppr, pft, FT, pfv, pke), exported at 2 time steps = 10 files + assert len(fieldsListTest) == 10 # call function to be tested outDir2 = pathlib.Path(tmp_path, "testDir2") outDir2.mkdir() - cfg["GENERAL"]["resType"] = "" - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv"} + cfg["GENERAL"]["resType"] = "ppr|pft|pfv" + cfg["REPORT"] = {} com1DFA.exportFields(cfg, 0.00, fields1, dem, outDir2, logName, TSave="initial") com1DFA.exportFields(cfg, 10.00, fields2, dem, outDir2, logName, TSave="intermediate") @@ -1865,7 +1867,10 @@ def test_exportFields(tmp_path): for f in fieldFiles3: fieldsListTest3.append(f.name) - assert len(fieldsListTest2) == 6 + # With new behavior: all time steps export fields from resType + # resType has 3 fields (ppr, pft, pfv), exported at 5 time steps = 15 files in timeSteps/ + # final time step also exports 3 files to peakFiles/ = 3 files + assert len(fieldsListTest2) == 15 assert len(fieldsListTest3) == 3 @@ -1894,7 +1899,7 @@ def test_initializeFields(): "stoppedParticles": {"m": np.empty(0), "x": np.empty(0), "y": np.empty(0)}, } cfg = configparser.ConfigParser() - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv"} + cfg["REPORT"] = {} cfg["GENERAL"] = { "rho": "200.", "interpOption": "2", @@ -1941,7 +1946,7 @@ def test_initializeFields(): assert np.sum(fields["timeInfo"]) == 0.0 assert np.sum(fields["sfcChangeTotal"]) == 0.0 - cfg["REPORT"] = {"plotFields": "pft|pfv"} + cfg["REPORT"] = {} cfg["GENERAL"] = { "resType": "pke|pta|pft|pfv", "rho": "200.", @@ -2229,7 +2234,7 @@ def test_initializeSimulation(tmp_path): # setup required input cfg = configparser.ConfigParser() - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv"} + cfg["REPORT"] = {} cfg["GENERAL"] = { "methodMeshNormal": "1", "thresholdPointInPoly": "0.001", @@ -2412,7 +2417,7 @@ def test_initializeSimulation(tmp_path): # test if dam is found # setup required input cfg = configparser.ConfigParser() - cfg["REPORT"] = {"plotFields": "ppr|pft|pfv"} + cfg["REPORT"] = {} cfg["GENERAL"] = { "methodMeshNormal": "1", "thresholdPointInPoly": "0.001", @@ -2597,6 +2602,8 @@ def test_runCom1DFA(tmp_path, caplog): # print("there is an extra key in particles: ", particlesList[-1].keys() - set(dictKeys)) assert all(key in dictKeys for key in particlesList[-1]) + # With dtSave bug fixed: 2 simulations × 6 timesteps = 12 files + # Timesteps: t=0, 10, 20, 30, 40, 50 (from tSteps=0:10) assert len(particlesList) == 12 # print(simDF["simName"]) @@ -2917,3 +2924,93 @@ def test_adaptDEM(): assert np.any(dem["areaRaster"] != demAdapted["areaRaster"]) assert np.all(fieldsAdapted["sfcChange"] == fields["FTDet"] / NzNormed) assert np.all(fieldsAdapted["sfcChangeTotal"] == fields["FTDet"] / NzNormed) + + +def test_tSteps_output_behavior(tmp_path, caplog): + """Test that tSteps controls which timesteps are exported correctly. + + - Empty tSteps (default): only final timestep is exported + - Explicit tSteps with t=0: t=0 timestep is exported + """ + testDir = pathlib.Path(__file__).parents[0] + inputDir = testDir / "data" / "testCom1DFA" + + # Test 1: Empty tSteps should only export final timestep + avaDir1 = pathlib.Path(tmp_path, "testEmptyTSteps") + shutil.copytree(inputDir, avaDir1) + cfgFile1 = avaDir1 / "test_com1DFACfg.ini" + + # Get main configuration + cfgMain = cfgUtils.getGeneralConfig() + cfgMain['MAIN']['avalancheDir'] = str(avaDir1) + # Modify config to have empty tSteps and NO parameter variations + cfg = cfgUtils.getModuleConfig(com1DFA, cfgFile1) + cfg["GENERAL"]["tSteps"] = "" + cfg["GENERAL"]["tEnd"] = "10" # Short simulation + cfg["GENERAL"]["dt"] = "0.1" # Single value, no variations + cfg["GENERAL"]["simTypeList"] = "null" # Simple simulation, no entrainment/resistance + with open(cfgFile1, "w") as f: + cfg.write(f) + + dem, plotDict, reportDictList, simDF = com1DFA.com1DFAMain(cfgMain, cfgInfo=cfgFile1) + + # Check that only final timestep files exist in timeSteps directory + timeStepsDir1 = avaDir1 / "Outputs" / "com1DFA" / "peakFiles" / "timeSteps" + if timeStepsDir1.exists(): + tStepFiles1 = list(timeStepsDir1.glob("*.asc")) + # Should only have final timestep files (one per result type: ppr, pft, pfv) + # Not initial timestep at t=0 + for tFile in tStepFiles1: + assert "_t0.0" not in tFile.stem, f"Found initial timestep file {tFile} but tSteps was empty" + + # Test 2: Explicit tSteps with t=0 should export t=0 timestep + avaDir2 = pathlib.Path(tmp_path, "testExplicitTSteps") + shutil.copytree(inputDir, avaDir2) + cfgFile2 = avaDir2 / "test_com1DFACfg.ini" + + cfgMain['MAIN']['avalancheDir'] = str(avaDir2) + + # Modify config to have explicit tSteps including t=0 and NO parameter variations + cfg2 = cfgUtils.getModuleConfig(com1DFA, cfgFile2) + cfg2["GENERAL"]["tSteps"] = "0|5" + cfg2["GENERAL"]["tEnd"] = "10" # Short simulation + cfg2["GENERAL"]["dt"] = "0.1" # Single value, no variations + cfg2["GENERAL"]["simTypeList"] = "null" # Simple simulation, no entrainment/resistance + with open(cfgFile2, "w") as f: + cfg2.write(f) + + dem2, plotDict2, reportDictList2, simDF2 = com1DFA.com1DFAMain(cfgMain, cfgInfo=cfgFile2) + + # Check that t=0 timestep files exist + timeStepsDir2 = avaDir2 / "Outputs" / "com1DFA" / "peakFiles" / "timeSteps" + assert timeStepsDir2.exists(), "timeSteps directory should exist" + tStepFiles2 = list(timeStepsDir2.glob("*_t0.0*.asc")) + assert len(tStepFiles2) > 0, "Should have initial timestep files at t=0 when tSteps includes 0" + + # Test 3: exportData = False should trigger contour fetching in else block + avaDir3 = pathlib.Path(tmp_path, "testExportDataFalse") + shutil.copytree(inputDir, avaDir3) + cfgFile3 = avaDir3 / "test_com1DFACfg.ini" + + cfgMain['MAIN']['avalancheDir'] = str(avaDir3) + + # Modify config to have exportData = False + cfg3 = cfgUtils.getModuleConfig(com1DFA, cfgFile3) + cfg3["GENERAL"]["tSteps"] = "" + cfg3["GENERAL"]["tEnd"] = "5" # Very short simulation + cfg3["GENERAL"]["dt"] = "0.1" + cfg3["GENERAL"]["simTypeList"] = "null" + cfg3["EXPORTS"]["exportData"] = "False" # Key setting to test else block + with open(cfgFile3, "w") as f: + cfg3.write(f) + + dem3, plotDict3, reportDictList3, simDF3 = com1DFA.com1DFAMain(cfgMain, cfgInfo=cfgFile3) + + # Check that contour data was generated (stored in reportDict) instead of exported files + assert len(reportDictList3) > 0, "Should have report dict even with exportData=False" + # Verify that timeSteps directory doesn't exist (no data exported) + timeStepsDir3 = avaDir3 / "Outputs" / "com1DFA" / "peakFiles" / "timeSteps" + if timeStepsDir3.exists(): + tStepFiles3 = list(timeStepsDir3.glob("*.asc")) + # With exportData=False, intermediate timesteps should not be exported + assert len(tStepFiles3) == 0, "No timestep files should be exported when exportData=False" diff --git a/avaframe/tests/test_fileHandlerUtils.py b/avaframe/tests/test_fileHandlerUtils.py index c2a14e933..3f129a82e 100644 --- a/avaframe/tests/test_fileHandlerUtils.py +++ b/avaframe/tests/test_fileHandlerUtils.py @@ -283,19 +283,19 @@ def test_splitTimeValueToArrayInterval(): cfgValuesList = np.asarray([1.0, 2.5, 3.8]) cfgValues1 = '0.|2.5|3.8' - cfgValuesList1 = np.asarray([2.5, 3.8]) + cfgValuesList1 = np.asarray([0., 2.5, 3.8]) cfgValues2 = '0:5' - cfgValuesList2 = np.asarray([5., 10., 15.]) + cfgValuesList2 = np.asarray([0., 5., 10., 15.]) cfgValues3 = '' cfgValuesList3 = np.asarray([40.]) cfgValues4 = '0:22' - cfgValuesList4 = np.asarray([20.]) + cfgValuesList4 = np.asarray([0., 20.]) cfgValues5 = '0' - cfgValuesList5 = np.asarray([40.]) + cfgValuesList5 = np.asarray([0.]) cfg = configparser.ConfigParser() cfg['GENERAL'] = {'tEnd': '20'} @@ -322,12 +322,15 @@ def test_splitTimeValueToArrayInterval(): assert len(items1) == len(cfgValuesList1) assert items1[0] == cfgValuesList1[0] assert items1[1] == cfgValuesList1[1] + assert items1[2] == cfgValuesList1[2] assert len(items2) == len(cfgValuesList2) assert items2[0] == cfgValuesList2[0] assert items2[1] == cfgValuesList2[1] assert items2[2] == cfgValuesList2[2] + assert items2[3] == cfgValuesList2[3] assert len(items4) == len(cfgValuesList4) assert items4[0] == cfgValuesList4[0] + assert items4[1] == cfgValuesList4[1] assert len(items5) == len(cfgValuesList5) assert items5[0] == cfgValuesList5[0] diff --git a/docs/moduleCom1DFA.rst b/docs/moduleCom1DFA.rst index 77cb853c8..594d48db2 100644 --- a/docs/moduleCom1DFA.rst +++ b/docs/moduleCom1DFA.rst @@ -256,7 +256,7 @@ Output Using the default configuration, the simulation results are saved to: *Outputs/com1DFA* and include: * raster files of the peak values for pressure, flow thickness and flow velocity (*Outputs/com1DFA/peakFiles*) -* raster files of the peak values for pressure, flow thickness and flow velocity for the initial time step (*Outputs/com1DFA/peakFiles/timeSteps*) +* raster files of the peak values for pressure, flow thickness and flow velocity for the final time step (*Outputs/com1DFA/peakFiles/timeSteps*) * markdown report including figures for all simulations (*Outputs/com1DFA/reports*) - if a ``_cropshape.shp`` file provided in Inputs/POLYGONS, plots are cropped to the rectangular bounds of the polygon - if ``showOnlineBackground = True`` in avaFrameCfg.ini and a suitable ``mapProvider`` is set, peak fields are plotted onto the corresponding map