From 7cddfde90e68911ebb0f8f4b1b915bf95f96abf2 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 1 Apr 2025 22:23:50 +0800 Subject: [PATCH] add eno --- .../eno2/fortran/01/CMakeLists.txt | 28 + .../eno2/fortran/01/README.txt | 1 + .../eno2/fortran/01/enoburgers.f90 | 267 ++++++ .../eno3/cpp/01/BurgersField.cpp | 366 ++++++++ .../eno3/cpp/01/BurgersField.h | 31 + .../eno3/cpp/01/CMakeLists.txt | 106 +++ .../eno3/cpp/01/CgnsUtil.cpp | 584 +++++++++++++ .../eno3/cpp/01/CgnsUtil.h | 50 ++ .../eno3/cpp/01/ConvectionField.cpp | 287 ++++++ .../eno3/cpp/01/ConvectionField.h | 33 + .../1d-linear-convection/eno3/cpp/01/Eno.cpp | 135 +++ .../1d-linear-convection/eno3/cpp/01/Eno.h | 7 + .../eno3/cpp/01/EulerField.cpp | 818 ++++++++++++++++++ .../eno3/cpp/01/EulerField.h | 45 + .../eno3/cpp/01/Field.cpp | 342 ++++++++ .../1d-linear-convection/eno3/cpp/01/Field.h | 54 ++ .../eno3/cpp/01/Global.cpp | 465 ++++++++++ .../1d-linear-convection/eno3/cpp/01/Global.h | 180 ++++ .../1d-linear-convection/eno3/cpp/01/Grid.cpp | 290 +++++++ .../1d-linear-convection/eno3/cpp/01/Grid.h | 115 +++ .../eno3/cpp/01/HeatField.cpp | 228 +++++ .../eno3/cpp/01/HeatField.h | 28 + .../eno3/cpp/01/Linear Convection_plot.py | 70 ++ .../eno3/cpp/01/Linear Convection_plotBAK.py | 69 ++ .../eno3/cpp/01/LogFile.cpp | 138 +++ .../eno3/cpp/01/LogFile.h | 27 + .../eno3/cpp/01/MyCRWenoPlot.py | 64 ++ .../eno3/cpp/01/MyWenoPlot.py | 53 ++ .../eno3/cpp/01/Parallel.cpp | 100 +++ .../eno3/cpp/01/Parallel.h | 85 ++ .../1d-linear-convection/eno3/cpp/01/Post.cpp | 38 + .../1d-linear-convection/eno3/cpp/01/Post.h | 6 + .../eno3/cpp/01/README.txt | 3 + .../eno3/cpp/01/Solver.cpp | 795 +++++++++++++++++ .../1d-linear-convection/eno3/cpp/01/Solver.h | 50 ++ .../eno3/cpp/01/Vec1d.cpp | 10 + .../1d-linear-convection/eno3/cpp/01/Vec1d.h | 72 ++ .../1d-linear-convection/eno3/cpp/01/Weno.cpp | 399 +++++++++ .../1d-linear-convection/eno3/cpp/01/Weno.h | 36 + .../eno3/cpp/01/ZoneState.cpp | 20 + .../eno3/cpp/01/ZoneState.h | 21 + .../eno3/cpp/01/burgers.json | 17 + .../eno3/cpp/01/burgers_ftcs.json | 15 + .../eno3/cpp/01/burgers_plot.py | 64 ++ .../1d-linear-convection/eno3/cpp/01/cfd.json | 12 + .../eno3/cpp/01/heat.json | 17 + .../eno3/cpp/01/heat_plot.py | 116 +++ .../eno3/cpp/01/heaticp.json | 13 + .../eno3/cpp/01/hxmath.cpp | 30 + .../1d-linear-convection/eno3/cpp/01/hxmath.h | 16 + .../eno3/cpp/01/linearconvection.json | 19 + .../eno3/cpp/01/linearconvection1d.cgns | Bin 0 -> 10746 bytes .../eno3/cpp/01/linearconvectionBAK.json | 19 + .../1d-linear-convection/eno3/cpp/01/main.cpp | 8 + .../1d-linear-convection/eno3/cpp/01/plot.py | 58 ++ .../eno3/cpp/01/plotting2.jl | 49 ++ .../1d-linear-convection/eno3/cpp/01/sod.json | 19 + .../eno3/cpp/01/sod_plot.py | 173 ++++ .../eno3/cpp/01/sod_sort.py | 68 ++ .../eno3/cpp/01/sod_sort_on_xcoor.py | 85 ++ .../eno3/cpp/01/sod_theory.plt | 29 + .../ftbs/cpp/01/BurgersField.cpp | 366 ++++++++ .../ftbs/cpp/01/BurgersField.h | 31 + .../ftbs/cpp/01/CMakeLists.txt | 105 +++ .../ftbs/cpp/01/CgnsUtil.cpp | 584 +++++++++++++ .../ftbs/cpp/01/CgnsUtil.h | 50 ++ .../ftbs/cpp/01/ConvectionField.cpp | 281 ++++++ .../ftbs/cpp/01/ConvectionField.h | 33 + .../ftbs/cpp/01/EulerField.cpp | 818 ++++++++++++++++++ .../ftbs/cpp/01/EulerField.h | 45 + .../ftbs/cpp/01/Field.cpp | 342 ++++++++ .../1d-linear-convection/ftbs/cpp/01/Field.h | 54 ++ .../ftbs/cpp/01/Global.cpp | 461 ++++++++++ .../1d-linear-convection/ftbs/cpp/01/Global.h | 179 ++++ .../1d-linear-convection/ftbs/cpp/01/Grid.cpp | 290 +++++++ .../1d-linear-convection/ftbs/cpp/01/Grid.h | 115 +++ .../ftbs/cpp/01/HeatField.cpp | 228 +++++ .../ftbs/cpp/01/HeatField.h | 28 + .../ftbs/cpp/01/Linear Convection_plot.py | 69 ++ .../ftbs/cpp/01/LogFile.cpp | 138 +++ .../ftbs/cpp/01/LogFile.h | 27 + .../ftbs/cpp/01/MyCRWenoPlot.py | 64 ++ .../ftbs/cpp/01/MyWenoPlot.py | 53 ++ .../ftbs/cpp/01/Parallel.cpp | 100 +++ .../ftbs/cpp/01/Parallel.h | 85 ++ .../1d-linear-convection/ftbs/cpp/01/Post.cpp | 38 + .../1d-linear-convection/ftbs/cpp/01/Post.h | 6 + .../ftbs/cpp/01/README.txt | 3 + .../ftbs/cpp/01/Solver.cpp | 793 +++++++++++++++++ .../1d-linear-convection/ftbs/cpp/01/Solver.h | 50 ++ .../ftbs/cpp/01/Vec1d.cpp | 10 + .../1d-linear-convection/ftbs/cpp/01/Vec1d.h | 72 ++ .../1d-linear-convection/ftbs/cpp/01/Weno.cpp | 363 ++++++++ .../1d-linear-convection/ftbs/cpp/01/Weno.h | 36 + .../ftbs/cpp/01/ZoneState.cpp | 20 + .../ftbs/cpp/01/ZoneState.h | 21 + .../ftbs/cpp/01/burgers.json | 17 + .../ftbs/cpp/01/burgers_ftcs.json | 15 + .../ftbs/cpp/01/burgers_plot.py | 64 ++ .../1d-linear-convection/ftbs/cpp/01/cfd.json | 12 + .../ftbs/cpp/01/heat.json | 17 + .../ftbs/cpp/01/heat_plot.py | 116 +++ .../ftbs/cpp/01/heaticp.json | 13 + .../ftbs/cpp/01/hxmath.cpp | 30 + .../1d-linear-convection/ftbs/cpp/01/hxmath.h | 16 + .../ftbs/cpp/01/linearconvection.json | 19 + .../ftbs/cpp/01/linearconvection1d.cgns | Bin 0 -> 10746 bytes .../1d-linear-convection/ftbs/cpp/01/main.cpp | 8 + .../1d-linear-convection/ftbs/cpp/01/plot.py | 58 ++ .../ftbs/cpp/01/plotting2.jl | 49 ++ .../1d-linear-convection/ftbs/cpp/01/sod.json | 19 + .../ftbs/cpp/01/sod_plot.py | 173 ++++ .../ftbs/cpp/01/sod_sort.py | 68 ++ .../ftbs/cpp/01/sod_sort_on_xcoor.py | 85 ++ .../ftbs/cpp/01/sod_theory.plt | 29 + .../ftbs/python/01/ftbs.py | 17 + .../ftbs/python/01a/ftbs.py | 27 + .../ftbs/python/01b/ftbs.py | 39 + .../ftbs/python/01c/ftbs.py | 50 ++ .../ftbs/python/01d/ftbs.py | 41 + .../weno3/cpp/01/BurgersField.cpp | 366 ++++++++ .../weno3/cpp/01/BurgersField.h | 31 + .../weno3/cpp/01/CMakeLists.txt | 105 +++ .../weno3/cpp/01/CgnsUtil.cpp | 584 +++++++++++++ .../weno3/cpp/01/CgnsUtil.h | 50 ++ .../weno3/cpp/01/ConvectionField.cpp | 281 ++++++ .../weno3/cpp/01/ConvectionField.h | 33 + .../weno3/cpp/01/EulerField.cpp | 818 ++++++++++++++++++ .../weno3/cpp/01/EulerField.h | 45 + .../weno3/cpp/01/Field.cpp | 342 ++++++++ .../1d-linear-convection/weno3/cpp/01/Field.h | 54 ++ .../weno3/cpp/01/Global.cpp | 461 ++++++++++ .../weno3/cpp/01/Global.h | 179 ++++ .../weno3/cpp/01/Grid.cpp | 290 +++++++ .../1d-linear-convection/weno3/cpp/01/Grid.h | 115 +++ .../weno3/cpp/01/HeatField.cpp | 228 +++++ .../weno3/cpp/01/HeatField.h | 28 + .../weno3/cpp/01/Linear Convection_plot.py | 69 ++ .../weno3/cpp/01/LogFile.cpp | 138 +++ .../weno3/cpp/01/LogFile.h | 27 + .../weno3/cpp/01/MyCRWenoPlot.py | 64 ++ .../weno3/cpp/01/MyWenoPlot.py | 53 ++ .../weno3/cpp/01/Parallel.cpp | 100 +++ .../weno3/cpp/01/Parallel.h | 85 ++ .../weno3/cpp/01/Post.cpp | 38 + .../1d-linear-convection/weno3/cpp/01/Post.h | 6 + .../weno3/cpp/01/README.txt | 3 + .../weno3/cpp/01/Solver.cpp | 793 +++++++++++++++++ .../weno3/cpp/01/Solver.h | 50 ++ .../weno3/cpp/01/Vec1d.cpp | 10 + .../1d-linear-convection/weno3/cpp/01/Vec1d.h | 72 ++ .../weno3/cpp/01/Weno.cpp | 420 +++++++++ .../1d-linear-convection/weno3/cpp/01/Weno.h | 36 + .../weno3/cpp/01/ZoneState.cpp | 20 + .../weno3/cpp/01/ZoneState.h | 21 + .../weno3/cpp/01/burgers.json | 17 + .../weno3/cpp/01/burgers_ftcs.json | 15 + .../weno3/cpp/01/burgers_plot.py | 64 ++ .../weno3/cpp/01/cfd.json | 12 + .../weno3/cpp/01/heat.json | 17 + .../weno3/cpp/01/heat_plot.py | 116 +++ .../weno3/cpp/01/heaticp.json | 13 + .../weno3/cpp/01/hxmath.cpp | 30 + .../weno3/cpp/01/hxmath.h | 16 + .../weno3/cpp/01/linearconvection.json | 19 + .../weno3/cpp/01/linearconvection1d.cgns | Bin 0 -> 10746 bytes .../weno3/cpp/01/main.cpp | 8 + .../1d-linear-convection/weno3/cpp/01/plot.py | 58 ++ .../weno3/cpp/01/plotting2.jl | 49 ++ .../weno3/cpp/01/sod.json | 19 + .../weno3/cpp/01/sod_plot.py | 173 ++++ .../weno3/cpp/01/sod_sort.py | 68 ++ .../weno3/cpp/01/sod_sort_on_xcoor.py | 85 ++ .../weno3/cpp/01/sod_theory.plt | 29 + .../weno3/python/01/weno3.py | 68 ++ .../data_compare/solution_total_eno1.plt | 61 ++ .../data_compare/solution_total_eno2.plt | 61 ++ .../data_compare/solution_total_eno3.plt | 61 ++ .../data_compare/solution_total_eno4.plt | 61 ++ .../data_compare/solution_total_eno5.plt | 61 ++ .../data_compare/solution_total_eno6.plt | 61 ++ .../data_compare/solution_total_eno7.plt | 61 ++ .../eno1/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno1/fortran/01/README.txt | 1 + .../eno1/fortran/01/enoburgers.f90 | 284 ++++++ .../inviscid-1d/eno1/fortran/01/plot.py | 42 + .../burgers/inviscid-1d/eno1/julia/01/eno.jl | 206 +++++ .../burgers/inviscid-1d/eno1/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno1/python/01/eno.py | 169 ++++ .../inviscid-1d/eno1/python/01/plot.py | 53 ++ .../inviscid-1d/eno1/python/01a/eno.py | 169 ++++ .../inviscid-1d/eno1/python/01a/plot.py | 53 ++ .../inviscid-1d/eno1/python/01b/eno.py | 166 ++++ .../inviscid-1d/eno1/python/01b/plot.py | 53 ++ .../inviscid-1d/eno1/python/01c/eno.py | 198 +++++ .../inviscid-1d/eno1/python/01c/plot.py | 53 ++ .../inviscid-1d/eno1/python/01d/eno.py | 185 ++++ .../inviscid-1d/eno1/python/01d/plot.py | 53 ++ .../burgers/inviscid-1d/eno1/python/02/eno.py | 175 ++++ .../inviscid-1d/eno1/python/02/plot.py | 53 ++ .../eno2/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01/README.txt | 1 + .../eno2/fortran/01/enoburgers.f90 | 265 ++++++ .../inviscid-1d/eno2/fortran/01/plot.py | 42 + .../eno2/fortran/01a/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01a/README.txt | 1 + .../eno2/fortran/01a/enoburgers.f90 | 265 ++++++ .../inviscid-1d/eno2/fortran/01a/plot.py | 42 + .../eno2/fortran/01b/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01b/README.txt | 1 + .../eno2/fortran/01b/enoburgers.f90 | 265 ++++++ .../inviscid-1d/eno2/fortran/01b/plot.py | 42 + .../eno2/fortran/01c/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01c/README.txt | 1 + .../eno2/fortran/01c/enoburgers.f90 | 272 ++++++ .../inviscid-1d/eno2/fortran/01c/plot.py | 42 + .../eno2/fortran/01d/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01d/README.txt | 1 + .../eno2/fortran/01d/enoburgers.f90 | 271 ++++++ .../inviscid-1d/eno2/fortran/01d/plot.py | 42 + .../eno2/fortran/01e/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01e/README.txt | 1 + .../eno2/fortran/01e/enoburgers.f90 | 276 ++++++ .../inviscid-1d/eno2/fortran/01e/plot.py | 42 + .../eno2/fortran/01f/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01f/README.txt | 1 + .../eno2/fortran/01f/enoburgers.f90 | 276 ++++++ .../inviscid-1d/eno2/fortran/01f/plot.py | 42 + .../eno2/fortran/01g/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01g/README.txt | 1 + .../eno2/fortran/01g/enoburgers.f90 | 278 ++++++ .../inviscid-1d/eno2/fortran/01g/plot.py | 42 + .../eno2/fortran/01h/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01h/README.txt | 1 + .../eno2/fortran/01h/enoburgers.f90 | 276 ++++++ .../inviscid-1d/eno2/fortran/01h/plot.py | 42 + .../eno2/fortran/01i/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01i/README.txt | 1 + .../eno2/fortran/01i/enoburgers.f90 | 279 ++++++ .../inviscid-1d/eno2/fortran/01i/plot.py | 42 + .../eno2/fortran/01j/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01j/README.txt | 1 + .../eno2/fortran/01j/enoburgers.f90 | 279 ++++++ .../inviscid-1d/eno2/fortran/01j/plot.py | 42 + .../eno2/fortran/01k/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01k/README.txt | 1 + .../eno2/fortran/01k/enoburgers.f90 | 276 ++++++ .../inviscid-1d/eno2/fortran/01k/plot.py | 42 + .../eno2/fortran/01l/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/01l/README.txt | 1 + .../eno2/fortran/01l/enoburgers.f90 | 284 ++++++ .../inviscid-1d/eno2/fortran/01l/plot.py | 42 + .../eno2/fortran/02/CMakeLists.txt | 28 + .../inviscid-1d/eno2/fortran/02/README.txt | 1 + .../eno2/fortran/02/enoburgers.f90 | 286 ++++++ .../inviscid-1d/eno2/fortran/02/plot.py | 42 + .../burgers/inviscid-1d/eno2/julia/01/eno.jl | 207 +++++ .../burgers/inviscid-1d/eno2/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno2/python/01/eno.py | 171 ++++ .../inviscid-1d/eno2/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno2/python/02/eno.py | 171 ++++ .../inviscid-1d/eno2/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno2/python/03/eno.py | 171 ++++ .../inviscid-1d/eno2/python/03/plot.py | 53 ++ .../eno3/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno3/fortran/01/README.txt | 1 + .../eno3/fortran/01/enoburgers.f90 | 287 ++++++ .../inviscid-1d/eno3/fortran/01/plot.py | 38 + .../burgers/inviscid-1d/eno3/julia/01/eno.jl | 208 +++++ .../burgers/inviscid-1d/eno3/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno3/python/01/eno.py | 172 ++++ .../inviscid-1d/eno3/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno3/python/02/eno.py | 173 ++++ .../inviscid-1d/eno3/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno3/python/03/eno.py | 173 ++++ .../inviscid-1d/eno3/python/03/plot.py | 53 ++ .../eno4/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno4/fortran/01/README.txt | 1 + .../eno4/fortran/01/enoburgers.f90 | 299 +++++++ .../inviscid-1d/eno4/fortran/01/plot.py | 38 + .../burgers/inviscid-1d/eno4/julia/01/eno.jl | 209 +++++ .../burgers/inviscid-1d/eno4/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno4/python/01/eno.py | 173 ++++ .../inviscid-1d/eno4/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno4/python/02/eno.py | 174 ++++ .../inviscid-1d/eno4/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno4/python/03/eno.py | 174 ++++ .../inviscid-1d/eno4/python/03/plot.py | 53 ++ .../eno5/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno5/fortran/01/README.txt | 1 + .../eno5/fortran/01/enoburgers.f90 | 310 +++++++ .../inviscid-1d/eno5/fortran/01/plot.py | 38 + .../burgers/inviscid-1d/eno5/julia/01/eno.jl | 210 +++++ .../burgers/inviscid-1d/eno5/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno5/python/01/eno.py | 174 ++++ .../inviscid-1d/eno5/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno5/python/02/eno.py | 175 ++++ .../inviscid-1d/eno5/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno5/python/03/eno.py | 175 ++++ .../inviscid-1d/eno5/python/03/plot.py | 53 ++ .../eno6/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno6/fortran/01/README.txt | 1 + .../eno6/fortran/01/enoburgers.f90 | 323 +++++++ .../inviscid-1d/eno6/fortran/01/plot.py | 38 + .../burgers/inviscid-1d/eno6/julia/01/eno.jl | 211 +++++ .../burgers/inviscid-1d/eno6/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno6/python/01/eno.py | 175 ++++ .../inviscid-1d/eno6/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno6/python/02/eno.py | 176 ++++ .../inviscid-1d/eno6/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno6/python/03/eno.py | 176 ++++ .../inviscid-1d/eno6/python/03/plot.py | 53 ++ .../eno7/fortran/01/CMakeLists.txt | 28 + .../inviscid-1d/eno7/fortran/01/README.txt | 1 + .../eno7/fortran/01/enoburgers.f90 | 338 ++++++++ .../inviscid-1d/eno7/fortran/01/plot.py | 38 + .../burgers/inviscid-1d/eno7/julia/01/eno.jl | 212 +++++ .../burgers/inviscid-1d/eno7/julia/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno7/python/01/eno.py | 176 ++++ .../inviscid-1d/eno7/python/01/plot.py | 53 ++ .../burgers/inviscid-1d/eno7/python/02/eno.py | 177 ++++ .../inviscid-1d/eno7/python/02/plot.py | 53 ++ .../burgers/inviscid-1d/eno7/python/03/eno.py | 177 ++++ .../inviscid-1d/eno7/python/03/plot.py | 53 ++ example/burgers/theory/python/01/testprj.py | 20 + .../eno/enoburgers/fortran/01/CMakeLists.txt | 28 + example/eno/enoburgers/fortran/01/README.txt | 3 + .../eno/enoburgers/fortran/01/enoburgers.f90 | 291 +++++++ .../fortran/01_debug/CMakeLists.txt | 28 + .../enoburgers/fortran/01_debug/README.txt | 3 + .../fortran/01_debug/enoburgers.f90 | 289 +++++++ .../eno/enoburgers/fortran/01a/CMakeLists.txt | 28 + example/eno/enoburgers/fortran/01a/README.txt | 3 + .../eno/enoburgers/fortran/01a/enoburgers.f90 | 336 +++++++ .../eno/enoburgers/fortran/01b/CMakeLists.txt | 28 + example/eno/enoburgers/fortran/01b/README.txt | 3 + .../eno/enoburgers/fortran/01b/enoburgers.f90 | 230 +++++ .../eno/enoburgers/fortran/01c/CMakeLists.txt | 28 + example/eno/enoburgers/fortran/01c/README.txt | 3 + .../eno/enoburgers/fortran/01c/enoburgers.f90 | 218 +++++ .../eno/enolinear/fortran/01/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01/README.txt | 2 + .../eno/enolinear/fortran/01/enolinear.f90 | 184 ++++ .../eno/enolinear/fortran/01a/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01a/README.txt | 2 + .../eno/enolinear/fortran/01a/enolinear.f90 | 163 ++++ .../eno/enolinear/fortran/01b/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01b/README.txt | 2 + .../eno/enolinear/fortran/01b/enolinear.f90 | 170 ++++ .../eno/enolinear/fortran/01c/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01c/README.txt | 2 + .../eno/enolinear/fortran/01c/enolinear.f90 | 169 ++++ .../eno/enolinear/fortran/01d/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01d/README.txt | 2 + .../eno/enolinear/fortran/01d/enolinear.f90 | 194 +++++ .../eno/enolinear/fortran/01e/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01e/README.txt | 2 + .../eno/enolinear/fortran/01e/enolinear.f90 | 159 ++++ .../eno/enolinear/fortran/01f/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01f/README.txt | 2 + .../eno/enolinear/fortran/01f/enolinear.f90 | 158 ++++ .../eno/enolinear/fortran/01g/CMakeLists.txt | 28 + example/eno/enolinear/fortran/01g/README.txt | 2 + .../eno/enolinear/fortran/01g/enolinear.f90 | 161 ++++ example/figure/1d/03/testprj.py | 32 + example/figure/1d/03a/testprj.py | 46 + example/figure/1d/03b/testprj.py | 83 ++ example/figure/1d/03c/testprj.py | 68 ++ example/figure/1d/03d/testprj.py | 30 + example/figure/1d/03e/testprj.py | 34 + example/figure/1d/03f/testprj.py | 44 + example/figure/1d/03g/testprj.py | 48 + example/figure/1d/03h/testprj.py | 50 ++ example/figure/1d/03i/testprj.py | 45 + example/figure/1d/03j/testprj.py | 49 ++ example/figure/1d/03k/testprj.py | 53 ++ example/figure/1d/03l/testprj.py | 66 ++ example/figure/1d/03m/testprj.py | 55 ++ example/figure/1d/03n/testprj.py | 60 ++ example/figure/1d/03o/testprj.py | 52 ++ example/figure/1d/03p/testprj.py | 55 ++ example/figure/1d/03q/testprj.py | 55 ++ example/figure/1d/03r/testprj.py | 79 ++ example/figure/1d/03s/testprj.py | 85 ++ example/figure/1d/03t/testprj.py | 90 ++ example/figure/1d/03u/cfd.png | Bin 0 -> 32092 bytes example/figure/1d/03u/testprj.py | 93 ++ example/figure/1d/04/testprj.py | 105 +++ example/figure/1d/04a/testprj.py | 101 +++ example/figure/1d/04b/testprj.py | 115 +++ example/figure/1d/04c/cfd.png | Bin 0 -> 63137 bytes example/figure/1d/04c/testprj.py | 117 +++ example/figure/1d/04d/testprj.py | 118 +++ example/figure/1d/04e/testprj.py | 125 +++ example/figure/1d/eno/01/cfd.png | Bin 0 -> 24534 bytes example/figure/1d/eno/01/testprj.py | 69 ++ example/figure/1d/eno/01a/cfd.png | Bin 0 -> 27153 bytes example/figure/1d/eno/01a/testprj.py | 113 +++ example/figure/1d/eno/01b/cfd.png | Bin 0 -> 34422 bytes example/figure/1d/eno/01b/testprj.py | 153 ++++ example/figure/1d/eno/01c/cfd.png | Bin 0 -> 36535 bytes example/figure/1d/eno/01c/testprj.py | 196 +++++ example/figure/1d/eno/01d/testprj.py | 240 +++++ example/figure/1d/eno/01e/cfd.png | Bin 0 -> 36158 bytes example/figure/1d/eno/01e/testprj.py | 272 ++++++ example/figure/1d/eno/01f/cfd.png | Bin 0 -> 36295 bytes example/figure/1d/eno/01f/testprj.py | 312 +++++++ example/figure/1d/eno/01g/testprj.py | 313 +++++++ example/figure/1d/eno/01h/testprj.py | 310 +++++++ example/figure/1d/eno/01i/testprj.py | 307 +++++++ example/figure/1d/eno/01i0/testprj.py | 307 +++++++ example/figure/1d/eno/01j/testprj.py | 314 +++++++ example/figure/1d/eno/01j0/testprj.py | 318 +++++++ example/figure/1d/eno/01j1/testprj.py | 315 +++++++ example/figure/1d/eno/02/testprj.py | 120 +++ example/figure/1d/eno/02a/testprj.py | 150 ++++ example/figure/1d/eno/02b/testprj.py | 159 ++++ example/figure/1d/eno/02c/testprj.py | 188 ++++ example/figure/1d/eno/02d/testprj.py | 204 +++++ example/figure/1d/eno/02e/cfd.png | Bin 0 -> 35387 bytes example/figure/1d/eno/02e/testprj.py | 218 +++++ example/figure/1d/eno/02f/testprj.py | 209 +++++ example/figure/1d/eno/02g/cfd.png | Bin 0 -> 47257 bytes example/figure/1d/eno/02g/testprj.py | 207 +++++ example/figure/1d/eno/02h/cfd.png | Bin 0 -> 37308 bytes example/figure/1d/eno/02h/testprj.py | 208 +++++ example/figure/1d/eno/02i/testprj.py | 221 +++++ example/figure/1d/eno/latex/01/README.txt | 2 + example/figure/1d/eno/latex/01/plot.tex | 41 + example/figure/1d/eno/latex/02/README.txt | 2 + example/figure/1d/eno/latex/02/plot.tex | 78 ++ example/figure/1d/eno/latex/02a/README.txt | 2 + example/figure/1d/eno/latex/02a/plot.tex | 76 ++ example/figure/1d/eno/latex/02b/README.txt | 2 + example/figure/1d/eno/latex/02b/plot.tex | 56 ++ example/figure/1d/eno/latex/02c/README.txt | 2 + example/figure/1d/eno/latex/02c/plot.tex | 115 +++ example/figure/1d/eno/latex/02d/README.txt | 2 + example/figure/1d/eno/latex/02d/plot.tex | 38 + example/figure/1d/eno/latex/02e/README.txt | 2 + example/figure/1d/eno/latex/02e/plot.tex | 47 + .../figure/1d/eno/latex/02etest/README.txt | 2 + example/figure/1d/eno/latex/02etest/plot.tex | 12 + example/figure/1d/eno/latex/02f/README.txt | 3 + example/figure/1d/eno/latex/02f/plot.tex | 29 + example/figure/1d/eno/latex/README.txt | 2 + example/figure/arrow/01/testprj.py | 29 + example/figure/arrow/01a/testprj.py | 32 + example/figure/integral/latex/01/README.txt | 1 + example/figure/integral/latex/01/plot.tex | 42 + example/figure/integral/python/01/testprj.py | 33 + example/figure/latex/01/README.txt | 1 + example/figure/latex/01/plot.tex | 70 ++ example/grid/1d/01/Mesh/CMakeLists.txt | 87 ++ example/grid/1d/01/Mesh/CMakeLists.txt.user | 462 ++++++++++ example/grid/1d/01/Mesh/README.txt | 1 + example/grid/1d/01/Mesh/grid.cpp | 109 +++ example/grid/1d/01/Mesh/grid.h | 15 + example/grid/1d/01/Mesh/main.cpp | 12 + example/grid/1d/01/Mesh/mainwindow.cpp | 33 + example/grid/1d/01/Mesh/mainwindow.h | 30 + example/grid/1d/01/Mesh/mainwindow.ui | 31 + example/grid/1d/01/Mesh/meshdialog.cpp | 78 ++ example/grid/1d/01/Mesh/meshdialog.h | 30 + example/grid/1d/01/Mesh/meshdialog.ui | 296 +++++++ example/weno-coef/crj/fortran/01/coef.f90 | 13 + example/weno-coef/crj/python/01/crj.py | 44 + example/weno-coef/crj/python/01a/crj.py | 59 ++ example/weno-coef/crj/python/01b/crj.py | 46 + example/weno-coef/crj/python/01c/crj.py | 54 ++ example/weno-coef/crj/python/01d/crj.py | 54 ++ example/weno-coef/crj/python/02/crj.py | 27 + example/weno-coef/crj/python/02a/crj.py | 35 + .../divide_as_simplified_fraction/div.py | 21 + example/weno-coef/eno/01/testprj.py | 58 ++ example/weno-coef/eno/01a/testprj.py | 18 + example/weno-coef/eno/01b/testprj.py | 70 ++ example/weno-coef/eno/01c/testprj.py | 76 ++ example/weno-coef/eno/02/testprj.py | 133 +++ example/weno-coef/eno/03/matrix_data.txt | 6 + example/weno-coef/eno/03/testprj.py | 23 + example/weno-coef/eno/03a/matrix_data.txt | 6 + example/weno-coef/eno/03a/testprj.py | 23 + example/weno-coef/eno/03b/matrix_data.txt | 7 + example/weno-coef/eno/03b/matrix_output.txt | 42 + example/weno-coef/eno/03b/testprj.py | 35 + example/weno-coef/eno/03c/matrix_data.txt | 8 + example/weno-coef/eno/03c/matrix_output.txt | 56 ++ example/weno-coef/eno/03c/testprj.py | 35 + example/weno-coef/fractions/01/testprj.py | 23 + example/weno-coef/fractions/02/testprj.py | 12 + example/weno-coef/fractions/02a/testprj.py | 30 + example/weno-coef/fractions/03/testprj.py | 12 + example/weno-coef/fractions/03a/testprj.py | 31 + example/weno-coef/fractions/03b/testprj.py | 18 + example/weno-coef/fractions/03c/testprj.py | 19 + example/weno-coef/fractions/03d/testprj.py | 25 + example/weno-coef/fractions/03e/testprj.py | 45 + example/weno-coef/fractions/03f/testprj.py | 52 ++ example/weno-coef/fractions/03g/testprj.py | 71 ++ example/weno-coef/fractions/03h/testprj.py | 70 ++ example/weno-coef/fractions/04/testprj.py | 37 + example/weno-coef/fractions/04a/testprj.py | 51 ++ example/weno-coef/fractions/04b/testprj.py | 52 ++ example/weno-coef/fractions/04c/testprj.py | 11 + example/weno-coef/fractions/04d/testprj.py | 11 + example/weno-coef/fractions/04e/testprj.py | 13 + example/weno-coef/fractions/04f/testprj.py | 19 + example/weno-coef/fractions/05/testprj.py | 77 ++ example/weno-coef/fractions/05a/testprj.py | 112 +++ example/weno-coef/fractions/05b/testprj.py | 120 +++ example/weno-coef/fractions/05c/testprj.py | 148 ++++ example/weno-coef/fractions/05d/testprj.py | 120 +++ example/weno-coef/fractions/05e/testprj.py | 127 +++ example/weno-coef/fractions/05f/testprj.py | 117 +++ example/weno-coef/fractions/05g/testprj.py | 124 +++ example/weno-coef/fractions/05h/testprj.py | 122 +++ example/weno-coef/fractions/05i/testprj.py | 127 +++ example/weno-coef/fractions/06/testprj.py | 124 +++ example/weno-coef/fractions/06a/testprj.py | 124 +++ example/weno-coef/fractions/06b/testprj.py | 125 +++ example/weno-coef/fractions/06c/testprj.py | 125 +++ 522 files changed, 51652 insertions(+) create mode 100644 example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt create mode 100644 example/1d-linear-convection/eno2/fortran/01/README.txt create mode 100644 example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 create mode 100644 example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/BurgersField.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt create mode 100644 example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/ConvectionField.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Eno.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Eno.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/EulerField.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/EulerField.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Field.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Field.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Global.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Global.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Grid.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Grid.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/HeatField.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/HeatField.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/LogFile.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/LogFile.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/Parallel.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Parallel.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Post.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Post.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/README.txt create mode 100644 example/1d-linear-convection/eno3/cpp/01/Solver.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Solver.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Vec1d.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/Weno.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/Weno.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/ZoneState.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/burgers.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/burgers_plot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/cfd.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/heat.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/heat_plot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/heaticp.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/hxmath.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/hxmath.h create mode 100644 example/1d-linear-convection/eno3/cpp/01/linearconvection.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns create mode 100644 example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/main.cpp create mode 100644 example/1d-linear-convection/eno3/cpp/01/plot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/plotting2.jl create mode 100644 example/1d-linear-convection/eno3/cpp/01/sod.json create mode 100644 example/1d-linear-convection/eno3/cpp/01/sod_plot.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/sod_sort.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py create mode 100644 example/1d-linear-convection/eno3/cpp/01/sod_theory.plt create mode 100644 example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/BurgersField.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt create mode 100644 example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/EulerField.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Field.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Field.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Global.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Global.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Grid.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Grid.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/HeatField.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/LogFile.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Parallel.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Post.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Post.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/README.txt create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Solver.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Solver.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Vec1d.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Weno.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/Weno.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/ZoneState.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/burgers.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/cfd.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/heat.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/heat_plot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/heaticp.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/hxmath.h create mode 100644 example/1d-linear-convection/ftbs/cpp/01/linearconvection.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns create mode 100644 example/1d-linear-convection/ftbs/cpp/01/main.cpp create mode 100644 example/1d-linear-convection/ftbs/cpp/01/plot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/plotting2.jl create mode 100644 example/1d-linear-convection/ftbs/cpp/01/sod.json create mode 100644 example/1d-linear-convection/ftbs/cpp/01/sod_plot.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/sod_sort.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py create mode 100644 example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt create mode 100644 example/1d-linear-convection/ftbs/python/01/ftbs.py create mode 100644 example/1d-linear-convection/ftbs/python/01a/ftbs.py create mode 100644 example/1d-linear-convection/ftbs/python/01b/ftbs.py create mode 100644 example/1d-linear-convection/ftbs/python/01c/ftbs.py create mode 100644 example/1d-linear-convection/ftbs/python/01d/ftbs.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/BurgersField.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt create mode 100644 example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/ConvectionField.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/EulerField.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/EulerField.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Field.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Field.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Global.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Global.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Grid.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Grid.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/HeatField.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/HeatField.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/LogFile.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/LogFile.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/Parallel.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Parallel.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Post.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Post.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/README.txt create mode 100644 example/1d-linear-convection/weno3/cpp/01/Solver.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Solver.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Vec1d.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/Weno.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/Weno.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/ZoneState.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/burgers.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/burgers_plot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/cfd.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/heat.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/heat_plot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/heaticp.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/hxmath.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/hxmath.h create mode 100644 example/1d-linear-convection/weno3/cpp/01/linearconvection.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns create mode 100644 example/1d-linear-convection/weno3/cpp/01/main.cpp create mode 100644 example/1d-linear-convection/weno3/cpp/01/plot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/plotting2.jl create mode 100644 example/1d-linear-convection/weno3/cpp/01/sod.json create mode 100644 example/1d-linear-convection/weno3/cpp/01/sod_plot.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/sod_sort.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py create mode 100644 example/1d-linear-convection/weno3/cpp/01/sod_theory.plt create mode 100644 example/1d-linear-convection/weno3/python/01/weno3.py create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt create mode 100644 example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt create mode 100644 example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno1/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno1/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno1/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01a/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01a/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01b/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01b/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01c/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01c/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01d/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/01d/plot.py create mode 100644 example/burgers/inviscid-1d/eno1/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno1/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01a/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01a/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01b/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01b/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01c/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01c/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01d/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01d/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01e/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01e/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01f/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01f/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01g/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01g/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01h/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01h/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01i/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01i/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01j/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01j/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01k/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01k/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01l/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/01l/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/02/README.txt create mode 100644 example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno2/fortran/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno2/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno2/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno2/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno2/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno2/python/03/plot.py create mode 100644 example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno3/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno3/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno3/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno3/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno3/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno3/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno3/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno3/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno3/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno3/python/03/plot.py create mode 100644 example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno4/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno4/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno4/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno4/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno4/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno4/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno4/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno4/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno4/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno4/python/03/plot.py create mode 100644 example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno5/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno5/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno5/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno5/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno5/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno5/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno5/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno5/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno5/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno5/python/03/plot.py create mode 100644 example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno6/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno6/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno6/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno6/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno6/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno6/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno6/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno6/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno6/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno6/python/03/plot.py create mode 100644 example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt create mode 100644 example/burgers/inviscid-1d/eno7/fortran/01/README.txt create mode 100644 example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 create mode 100644 example/burgers/inviscid-1d/eno7/fortran/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno7/julia/01/eno.jl create mode 100644 example/burgers/inviscid-1d/eno7/julia/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno7/python/01/eno.py create mode 100644 example/burgers/inviscid-1d/eno7/python/01/plot.py create mode 100644 example/burgers/inviscid-1d/eno7/python/02/eno.py create mode 100644 example/burgers/inviscid-1d/eno7/python/02/plot.py create mode 100644 example/burgers/inviscid-1d/eno7/python/03/eno.py create mode 100644 example/burgers/inviscid-1d/eno7/python/03/plot.py create mode 100644 example/burgers/theory/python/01/testprj.py create mode 100644 example/eno/enoburgers/fortran/01/CMakeLists.txt create mode 100644 example/eno/enoburgers/fortran/01/README.txt create mode 100644 example/eno/enoburgers/fortran/01/enoburgers.f90 create mode 100644 example/eno/enoburgers/fortran/01_debug/CMakeLists.txt create mode 100644 example/eno/enoburgers/fortran/01_debug/README.txt create mode 100644 example/eno/enoburgers/fortran/01_debug/enoburgers.f90 create mode 100644 example/eno/enoburgers/fortran/01a/CMakeLists.txt create mode 100644 example/eno/enoburgers/fortran/01a/README.txt create mode 100644 example/eno/enoburgers/fortran/01a/enoburgers.f90 create mode 100644 example/eno/enoburgers/fortran/01b/CMakeLists.txt create mode 100644 example/eno/enoburgers/fortran/01b/README.txt create mode 100644 example/eno/enoburgers/fortran/01b/enoburgers.f90 create mode 100644 example/eno/enoburgers/fortran/01c/CMakeLists.txt create mode 100644 example/eno/enoburgers/fortran/01c/README.txt create mode 100644 example/eno/enoburgers/fortran/01c/enoburgers.f90 create mode 100644 example/eno/enolinear/fortran/01/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01/README.txt create mode 100644 example/eno/enolinear/fortran/01/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01a/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01a/README.txt create mode 100644 example/eno/enolinear/fortran/01a/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01b/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01b/README.txt create mode 100644 example/eno/enolinear/fortran/01b/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01c/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01c/README.txt create mode 100644 example/eno/enolinear/fortran/01c/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01d/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01d/README.txt create mode 100644 example/eno/enolinear/fortran/01d/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01e/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01e/README.txt create mode 100644 example/eno/enolinear/fortran/01e/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01f/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01f/README.txt create mode 100644 example/eno/enolinear/fortran/01f/enolinear.f90 create mode 100644 example/eno/enolinear/fortran/01g/CMakeLists.txt create mode 100644 example/eno/enolinear/fortran/01g/README.txt create mode 100644 example/eno/enolinear/fortran/01g/enolinear.f90 create mode 100644 example/figure/1d/03/testprj.py create mode 100644 example/figure/1d/03a/testprj.py create mode 100644 example/figure/1d/03b/testprj.py create mode 100644 example/figure/1d/03c/testprj.py create mode 100644 example/figure/1d/03d/testprj.py create mode 100644 example/figure/1d/03e/testprj.py create mode 100644 example/figure/1d/03f/testprj.py create mode 100644 example/figure/1d/03g/testprj.py create mode 100644 example/figure/1d/03h/testprj.py create mode 100644 example/figure/1d/03i/testprj.py create mode 100644 example/figure/1d/03j/testprj.py create mode 100644 example/figure/1d/03k/testprj.py create mode 100644 example/figure/1d/03l/testprj.py create mode 100644 example/figure/1d/03m/testprj.py create mode 100644 example/figure/1d/03n/testprj.py create mode 100644 example/figure/1d/03o/testprj.py create mode 100644 example/figure/1d/03p/testprj.py create mode 100644 example/figure/1d/03q/testprj.py create mode 100644 example/figure/1d/03r/testprj.py create mode 100644 example/figure/1d/03s/testprj.py create mode 100644 example/figure/1d/03t/testprj.py create mode 100644 example/figure/1d/03u/cfd.png create mode 100644 example/figure/1d/03u/testprj.py create mode 100644 example/figure/1d/04/testprj.py create mode 100644 example/figure/1d/04a/testprj.py create mode 100644 example/figure/1d/04b/testprj.py create mode 100644 example/figure/1d/04c/cfd.png create mode 100644 example/figure/1d/04c/testprj.py create mode 100644 example/figure/1d/04d/testprj.py create mode 100644 example/figure/1d/04e/testprj.py create mode 100644 example/figure/1d/eno/01/cfd.png create mode 100644 example/figure/1d/eno/01/testprj.py create mode 100644 example/figure/1d/eno/01a/cfd.png create mode 100644 example/figure/1d/eno/01a/testprj.py create mode 100644 example/figure/1d/eno/01b/cfd.png create mode 100644 example/figure/1d/eno/01b/testprj.py create mode 100644 example/figure/1d/eno/01c/cfd.png create mode 100644 example/figure/1d/eno/01c/testprj.py create mode 100644 example/figure/1d/eno/01d/testprj.py create mode 100644 example/figure/1d/eno/01e/cfd.png create mode 100644 example/figure/1d/eno/01e/testprj.py create mode 100644 example/figure/1d/eno/01f/cfd.png create mode 100644 example/figure/1d/eno/01f/testprj.py create mode 100644 example/figure/1d/eno/01g/testprj.py create mode 100644 example/figure/1d/eno/01h/testprj.py create mode 100644 example/figure/1d/eno/01i/testprj.py create mode 100644 example/figure/1d/eno/01i0/testprj.py create mode 100644 example/figure/1d/eno/01j/testprj.py create mode 100644 example/figure/1d/eno/01j0/testprj.py create mode 100644 example/figure/1d/eno/01j1/testprj.py create mode 100644 example/figure/1d/eno/02/testprj.py create mode 100644 example/figure/1d/eno/02a/testprj.py create mode 100644 example/figure/1d/eno/02b/testprj.py create mode 100644 example/figure/1d/eno/02c/testprj.py create mode 100644 example/figure/1d/eno/02d/testprj.py create mode 100644 example/figure/1d/eno/02e/cfd.png create mode 100644 example/figure/1d/eno/02e/testprj.py create mode 100644 example/figure/1d/eno/02f/testprj.py create mode 100644 example/figure/1d/eno/02g/cfd.png create mode 100644 example/figure/1d/eno/02g/testprj.py create mode 100644 example/figure/1d/eno/02h/cfd.png create mode 100644 example/figure/1d/eno/02h/testprj.py create mode 100644 example/figure/1d/eno/02i/testprj.py create mode 100644 example/figure/1d/eno/latex/01/README.txt create mode 100644 example/figure/1d/eno/latex/01/plot.tex create mode 100644 example/figure/1d/eno/latex/02/README.txt create mode 100644 example/figure/1d/eno/latex/02/plot.tex create mode 100644 example/figure/1d/eno/latex/02a/README.txt create mode 100644 example/figure/1d/eno/latex/02a/plot.tex create mode 100644 example/figure/1d/eno/latex/02b/README.txt create mode 100644 example/figure/1d/eno/latex/02b/plot.tex create mode 100644 example/figure/1d/eno/latex/02c/README.txt create mode 100644 example/figure/1d/eno/latex/02c/plot.tex create mode 100644 example/figure/1d/eno/latex/02d/README.txt create mode 100644 example/figure/1d/eno/latex/02d/plot.tex create mode 100644 example/figure/1d/eno/latex/02e/README.txt create mode 100644 example/figure/1d/eno/latex/02e/plot.tex create mode 100644 example/figure/1d/eno/latex/02etest/README.txt create mode 100644 example/figure/1d/eno/latex/02etest/plot.tex create mode 100644 example/figure/1d/eno/latex/02f/README.txt create mode 100644 example/figure/1d/eno/latex/02f/plot.tex create mode 100644 example/figure/1d/eno/latex/README.txt create mode 100644 example/figure/arrow/01/testprj.py create mode 100644 example/figure/arrow/01a/testprj.py create mode 100644 example/figure/integral/latex/01/README.txt create mode 100644 example/figure/integral/latex/01/plot.tex create mode 100644 example/figure/integral/python/01/testprj.py create mode 100644 example/figure/latex/01/README.txt create mode 100644 example/figure/latex/01/plot.tex create mode 100644 example/grid/1d/01/Mesh/CMakeLists.txt create mode 100644 example/grid/1d/01/Mesh/CMakeLists.txt.user create mode 100644 example/grid/1d/01/Mesh/README.txt create mode 100644 example/grid/1d/01/Mesh/grid.cpp create mode 100644 example/grid/1d/01/Mesh/grid.h create mode 100644 example/grid/1d/01/Mesh/main.cpp create mode 100644 example/grid/1d/01/Mesh/mainwindow.cpp create mode 100644 example/grid/1d/01/Mesh/mainwindow.h create mode 100644 example/grid/1d/01/Mesh/mainwindow.ui create mode 100644 example/grid/1d/01/Mesh/meshdialog.cpp create mode 100644 example/grid/1d/01/Mesh/meshdialog.h create mode 100644 example/grid/1d/01/Mesh/meshdialog.ui create mode 100644 example/weno-coef/crj/fortran/01/coef.f90 create mode 100644 example/weno-coef/crj/python/01/crj.py create mode 100644 example/weno-coef/crj/python/01a/crj.py create mode 100644 example/weno-coef/crj/python/01b/crj.py create mode 100644 example/weno-coef/crj/python/01c/crj.py create mode 100644 example/weno-coef/crj/python/01d/crj.py create mode 100644 example/weno-coef/crj/python/02/crj.py create mode 100644 example/weno-coef/crj/python/02a/crj.py create mode 100644 example/weno-coef/divide_as_simplified_fraction/div.py create mode 100644 example/weno-coef/eno/01/testprj.py create mode 100644 example/weno-coef/eno/01a/testprj.py create mode 100644 example/weno-coef/eno/01b/testprj.py create mode 100644 example/weno-coef/eno/01c/testprj.py create mode 100644 example/weno-coef/eno/02/testprj.py create mode 100644 example/weno-coef/eno/03/matrix_data.txt create mode 100644 example/weno-coef/eno/03/testprj.py create mode 100644 example/weno-coef/eno/03a/matrix_data.txt create mode 100644 example/weno-coef/eno/03a/testprj.py create mode 100644 example/weno-coef/eno/03b/matrix_data.txt create mode 100644 example/weno-coef/eno/03b/matrix_output.txt create mode 100644 example/weno-coef/eno/03b/testprj.py create mode 100644 example/weno-coef/eno/03c/matrix_data.txt create mode 100644 example/weno-coef/eno/03c/matrix_output.txt create mode 100644 example/weno-coef/eno/03c/testprj.py create mode 100644 example/weno-coef/fractions/01/testprj.py create mode 100644 example/weno-coef/fractions/02/testprj.py create mode 100644 example/weno-coef/fractions/02a/testprj.py create mode 100644 example/weno-coef/fractions/03/testprj.py create mode 100644 example/weno-coef/fractions/03a/testprj.py create mode 100644 example/weno-coef/fractions/03b/testprj.py create mode 100644 example/weno-coef/fractions/03c/testprj.py create mode 100644 example/weno-coef/fractions/03d/testprj.py create mode 100644 example/weno-coef/fractions/03e/testprj.py create mode 100644 example/weno-coef/fractions/03f/testprj.py create mode 100644 example/weno-coef/fractions/03g/testprj.py create mode 100644 example/weno-coef/fractions/03h/testprj.py create mode 100644 example/weno-coef/fractions/04/testprj.py create mode 100644 example/weno-coef/fractions/04a/testprj.py create mode 100644 example/weno-coef/fractions/04b/testprj.py create mode 100644 example/weno-coef/fractions/04c/testprj.py create mode 100644 example/weno-coef/fractions/04d/testprj.py create mode 100644 example/weno-coef/fractions/04e/testprj.py create mode 100644 example/weno-coef/fractions/04f/testprj.py create mode 100644 example/weno-coef/fractions/05/testprj.py create mode 100644 example/weno-coef/fractions/05a/testprj.py create mode 100644 example/weno-coef/fractions/05b/testprj.py create mode 100644 example/weno-coef/fractions/05c/testprj.py create mode 100644 example/weno-coef/fractions/05d/testprj.py create mode 100644 example/weno-coef/fractions/05e/testprj.py create mode 100644 example/weno-coef/fractions/05f/testprj.py create mode 100644 example/weno-coef/fractions/05g/testprj.py create mode 100644 example/weno-coef/fractions/05h/testprj.py create mode 100644 example/weno-coef/fractions/05i/testprj.py create mode 100644 example/weno-coef/fractions/06/testprj.py create mode 100644 example/weno-coef/fractions/06a/testprj.py create mode 100644 example/weno-coef/fractions/06b/testprj.py create mode 100644 example/weno-coef/fractions/06c/testprj.py diff --git a/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt b/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/1d-linear-convection/eno2/fortran/01/README.txt b/example/1d-linear-convection/eno2/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 b/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..7106d53c --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 @@ -0,0 +1,267 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time, xlen + xlen = 2.0 + dx = xlen / nx + dt = dx * 0.5 + write(*,*) 'nx=',nx + write(*,*) 'dx=',dx + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp b/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/BurgersField.h b/example/1d-linear-convection/eno3/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt b/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cbc3f9bb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt @@ -0,0 +1,106 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Eno.h Eno.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..4a4eddfb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp @@ -0,0 +1,287 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "Eno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::ENO ) ) + { + enoL( nx, u, uL ); + enoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + //double coef = this->alpha / ( dx * dx ); + //for ( int m = 0; m < nequ; ++ m ) + //{ + // Vec1d & u = this->u.vec( m ); + // Vec1d & res = this->res.vec( m ); + // for ( int i = 0; i < ni; ++ i ) + // { + // res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + // } + //} +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Eno.cpp b/example/1d-linear-convection/eno3/cpp/01/Eno.cpp new file mode 100644 index 00000000..deae576a --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Eno.cpp @@ -0,0 +1,135 @@ +#include "Eno.h" + +//std::vector> enocoef = { +// { 11.0/6, -7.0/6, 1.0/3 } +// { 1.0/3, 5.0/6, -1.0/6 }, +// { -1.0/6, 5.0/6, 1.0/3 }, +// { 1.0/3, -7.0/6, 11.0/6 } +//}; + +std::vector> enocoef = { + { 3.0/2, -1.0/2 }, + { 1.0/2, 1.0/2 }, + { -1.0/2, 3.0/2 } +}; + +void enoL( int N, Vec1d & u, Vec1d & f ) +{ + int ighost = 3; + int iorder = 2; + int ist = 0 - ighost; + int ied = N - 1 + ighost; + + VecWrap dd; + dd.Allocate( iorder, ist, ied, 0 ); + + std::vector ir( N + 1 ); + + for ( int j = -ighost; j < N + ighost; ++j ) + { + dd[ 0 ][ j ] = u[ j ]; + } + + for ( int i = 1; i < iorder; ++ i ) + { + for ( int j = -ighost; j < N + ighost - 1; ++j ) + { + dd[ i ][ j ] = dd[ i - 1 ][ j + 1 ] - dd[ i - 1 ][ j ]; + } + } + + for ( int j = 0; j <= N; ++ j ) + { + ir[ j ] = j; + for ( int i = 1; i < iorder; ++ i ) + { + if ( std::abs( dd[ i ][ ir[ j ] - 1 ] ) <= std::abs( dd[ i ][ ir[ j ] ] ) ) + { + ir[ j ] = ir[ j ] - 1; + } + } + } + + // reconstruction u(j+1_2) + for ( int i = 0; i <= N; ++ i ) + { + int kk = ir[ i ]; + int l = i - kk; + int L = l + 1; + f[ i ] = 0; + for ( int m = 0; m < iorder; ++ m ) + { + f[ i ] += u[ kk + m ] * enocoef[ L ][ m ]; + } + } +} + +void enoR( int N, Vec1d & u, Vec1d & f ) +{ + int ighost = 3; + int iorder = 2; + int ist = 0 - ighost; + int ied = N - 1 + ighost; + + VecWrap dd; + dd.Allocate( iorder, ist, ied, 0 ); + + std::vector ir( N + 1 ); + + for ( int j = -ighost; j < N + ighost; ++j ) + { + dd[ 0 ][ j ] = u[ j ]; + } + + for ( int i = 1; i < iorder; ++ i ) + { + for ( int j = -ighost; j < N + ighost - 1; ++j ) + { + dd[ i ][ j ] = dd[ i - 1 ][ j + 1 ] - dd[ i - 1 ][ j ]; + } + } + + for ( int j = 0; j <= N; ++ j ) + { + ir[ j ] = j + 1; + for ( int i = 1; i < iorder; ++ i ) + { + if ( std::abs( dd[ i ][ ir[ j ] - 1 ] ) <= std::abs( dd[ i ][ ir[ j ] ] ) ) + { + ir[ j ] = ir[ j ] - 1; + } + } + } + + // reconstruction u(j+1_2) + for ( int i = 0; i <= N; ++ i ) + { + int kk = ir[ i ]; + int l = i - kk; + int L = l + 1; + f[ i ] = 0; + for ( int m = 0; m < iorder; ++ m ) + { + f[ i ] += u[ kk + m ] * enocoef[ L ][ m ]; + } + } +} + +void enoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + enoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void enoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + enoR( ni, u.vec( m ), f.vec( m ) ); + } +} + diff --git a/example/1d-linear-convection/eno3/cpp/01/Eno.h b/example/1d-linear-convection/eno3/cpp/01/Eno.h new file mode 100644 index 00000000..7b2c1c11 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Eno.h @@ -0,0 +1,7 @@ +#pragma once +#include "Vec1d.h" + +void enoL( int N, Vec1d & u, Vec1d & f ); +void enoR( int N, Vec1d & u, Vec1d & f ); +void enoL( int ni, VecWrap & u, VecWrap & f ); +void enoR( int ni, VecWrap & u, VecWrap & f ); \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp b/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/EulerField.h b/example/1d-linear-convection/eno3/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/eno3/cpp/01/Field.cpp b/example/1d-linear-convection/eno3/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Field.h b/example/1d-linear-convection/eno3/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Global.cpp b/example/1d-linear-convection/eno3/cpp/01/Global.cpp new file mode 100644 index 00000000..f6f55f50 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Global.cpp @@ -0,0 +1,465 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "eno3" ) + { + this->reconstruction = to_int( BasicScheme::ENO ); + } + else if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Global.h b/example/1d-linear-convection/eno3/cpp/01/Global.h new file mode 100644 index 00000000..55498419 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Global.h @@ -0,0 +1,180 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + ENO, //Weighted Essentially Non-oscillatory + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/eno3/cpp/01/Grid.cpp b/example/1d-linear-convection/eno3/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Grid.h b/example/1d-linear-convection/eno3/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp b/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/HeatField.h b/example/1d-linear-convection/eno3/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..7efc5d78 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py @@ -0,0 +1,70 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +#total_t = 0.625 +total_t = 0.025 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp b/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/eno3/cpp/01/LogFile.h b/example/1d-linear-convection/eno3/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp b/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Parallel.h b/example/1d-linear-convection/eno3/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/Post.cpp b/example/1d-linear-convection/eno3/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Post.h b/example/1d-linear-convection/eno3/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/eno3/cpp/01/README.txt b/example/1d-linear-convection/eno3/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/eno3/cpp/01/Solver.cpp b/example/1d-linear-convection/eno3/cpp/01/Solver.cpp new file mode 100644 index 00000000..9b175c8d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Solver.cpp @@ -0,0 +1,795 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::ENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) + ) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Solver.h b/example/1d-linear-convection/eno3/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp b/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Vec1d.h b/example/1d-linear-convection/eno3/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Weno.cpp b/example/1d-linear-convection/eno3/cpp/01/Weno.cpp new file mode 100644 index 00000000..2a6402d0 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Weno.cpp @@ -0,0 +1,399 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double beta1 = SQR( v2 - v1 ); + double beta2 = SQR( v3 - v2 ); + + double d1 = 2.0 / 3.0; + double d2 = 1.0 / 3.0; + + // computing nonlinear weights w1, w2, w3 + double c1 = d1 / ( SQR( beta1 + eps ) ); + double c2 = d2 / ( SQR( beta2 + eps ) ); + + double w1 = c1 / ( c1 + c2 ); + double w2 = c2 / ( c1 + c2 ); + + // candiate stencils + double q1 = - v1 / 2.0 + 3.0 / 2.0 * v2; + double q2 = v2 / 2.0 + v3 / 2.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 ); + + return f; +} + +double wcR3( double v1, double v2, double v3 ) +{ + // reconstructed value at interface + double f = 0.0; + + return f; +} + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Weno.h b/example/1d-linear-convection/eno3/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp b/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/eno3/cpp/01/ZoneState.h b/example/1d-linear-convection/eno3/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers.json b/example/1d-linear-convection/eno3/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py b/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/cfd.json b/example/1d-linear-convection/eno3/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/heat.json b/example/1d-linear-convection/eno3/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/heat_plot.py b/example/1d-linear-convection/eno3/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/heaticp.json b/example/1d-linear-convection/eno3/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp b/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/hxmath.h b/example/1d-linear-convection/eno3/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvection.json b/example/1d-linear-convection/eno3/cpp/01/linearconvection.json new file mode 100644 index 00000000..3ecf618c --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.025, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "eno3", + "reconstruction" : "eno3", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns new file mode 100644 index 0000000000000000000000000000000000000000..9bd4494619d6bc5b5cb79dc5fc262b23eacc09e6 GIT binary patch literal 10746 zcmeHNeQZ-z6u)iPQnupCKsOOs2SY(VH--vMR`$WRY%nYvK_h|Ux>2*WvnwzpaT@A7JEjoMTz!_O5Yw z7Q0Iw*e8gXxEvibi0&2k)sBiD{cUcy*8)8)?lOxcY@xFvSd3|0(D2?3RbqG@4!@|F z|M+75TS?O5lY$oxzhgC;(R`j7jV2bSL{w*D8Z*}`Uo>wL8r3VU{wtr_%17E;Ph> z-oDa$N?y%Lel-Iupb_mu&67aQNdi2}9G+^Y+hs|ak&-rp>$*o9G>Y%4X>B6K|AI=+ z#ibe&LGh$#lVwe5*_?GkD_hYSxwUprTPpA2p9&AB{-K^t*8vZ2HHd-d;rPlPo|U_J zX`yqq$L`sHrs`oK5j4i?#Z4bQ8%aNcXi??VW2A$YVdBADd~V>7&_vN{<9ZJo=SOBj zZ0;ry6DG3s7O~O`gOQ%*Dn}Mu8Z*rnq07X05Gkv$msc|g8Db(9DXfsNVA@=8zEj>$ zqWpdm%ny^&jb@sWmPEhocq5Ci<@cqqq=yYa$Df@%vB}B~0RKR4E3R+s0{cB22g@aR z5;Y_QM?7zX`#Ki?s1o(iO<iyiwX zO(wMw-9tYH8eO&CY6hD^IBeh_XxV}=xnRF71|PD*+ry73f}T`NAP=Ph&^KbcO{lOhwm=UGmE+&T+mfrXf;5?cw^?KI6>|N_|ln$Qa>gY$$S;30x6Pqnu z8_*8UYgSHd$ikrrr|SUHUx*VTt%5M+#{U1;_WOaD$Nkes3TpX_ei8pBY4$ z*}wnsJNF(?Kq}$!9-6v<6fn_p)~A`aqvd^)VE!d%rsrcWPF29@crX<8j|m#~0~GfA z#dD1+Oq9*D_5~h~eS_aPLMWLi%nogfc!!>pTGu8YshB@f(H=`w6ki!U<%DKsX)!GA zKHs)69gX8BLz)s^0z%896?`SG2h#UASIa*%-}>#)c4Y{wed1NpDu^G@v7 zg?!z}*NuEvk?$JvT}Qqf$ae$zZX(|;i@G%%!r zAq@;^U;t@AA@`Fxewquf`gp7Bu2X*bK)F5DBcU`($tnEg^n^W3um1vi9)1L5a}Irdy=@I44gGBtY5ES9qCvc z`?Dw*b~?hS%UYAK!Zw*%+%B~wAwX5yCi0V$f~~LD$=4$z{PhSP0x_a}oSg6qOviaL zvvO*@9($F$f_uf_IXr2M|Er&8<3|x#yR;vQ_ierY`_S(n%+SC!X3m6i%9Ht$M+Em& z>di!`w&UaY8pt2;Pt9yQDIs23CK*#N z4KN-z?N8#DwW|PoxY!=%I56_qe*SyyM0v0e#dfs4ApMW+I}t-Ahbp%zBAt*EnsCx} zAn|NM>^;EP-i@dxq|2VTCfkx%NJ#H1wi{8(%<-nHD&RhdV>?9$q60U!TgTj0`kRML PY~PA+eD`hq^1J^43|weL literal 0 HcmV?d00001 diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json b/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json new file mode 100644 index 00000000..ceb082b6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "eno3", + "reconstruction" : "eno3", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/main.cpp b/example/1d-linear-convection/eno3/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/plot.py b/example/1d-linear-convection/eno3/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/plotting2.jl b/example/1d-linear-convection/eno3/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/eno3/cpp/01/sod.json b/example/1d-linear-convection/eno3/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_plot.py b/example/1d-linear-convection/eno3/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_sort.py b/example/1d-linear-convection/eno3/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt b/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt b/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cdd5e14a --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt @@ -0,0 +1,105 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..6b06414c --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp @@ -0,0 +1,281 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp b/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/EulerField.h b/example/1d-linear-convection/ftbs/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Field.cpp b/example/1d-linear-convection/ftbs/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Field.h b/example/1d-linear-convection/ftbs/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Global.cpp b/example/1d-linear-convection/ftbs/cpp/01/Global.cpp new file mode 100644 index 00000000..3f560f56 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Global.cpp @@ -0,0 +1,461 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Global.h b/example/1d-linear-convection/ftbs/cpp/01/Global.h new file mode 100644 index 00000000..f89bc3c0 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Global.h @@ -0,0 +1,179 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp b/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Grid.h b/example/1d-linear-convection/ftbs/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp b/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/HeatField.h b/example/1d-linear-convection/ftbs/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp b/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/LogFile.h b/example/1d-linear-convection/ftbs/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp b/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Parallel.h b/example/1d-linear-convection/ftbs/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Post.cpp b/example/1d-linear-convection/ftbs/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Post.h b/example/1d-linear-convection/ftbs/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/ftbs/cpp/01/README.txt b/example/1d-linear-convection/ftbs/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp b/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp new file mode 100644 index 00000000..45259b3c --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp @@ -0,0 +1,793 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Solver.h b/example/1d-linear-convection/ftbs/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp b/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp new file mode 100644 index 00000000..c24809de --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp @@ -0,0 +1,363 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Weno.h b/example/1d-linear-convection/ftbs/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers.json b/example/1d-linear-convection/ftbs/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py b/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/cfd.json b/example/1d-linear-convection/ftbs/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/heat.json b/example/1d-linear-convection/ftbs/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py b/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/heaticp.json b/example/1d-linear-convection/ftbs/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp b/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/hxmath.h b/example/1d-linear-convection/ftbs/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json b/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json new file mode 100644 index 00000000..9491dce2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "upwind1", + "reconstruction" : "upwind1", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns new file mode 100644 index 0000000000000000000000000000000000000000..9bd4494619d6bc5b5cb79dc5fc262b23eacc09e6 GIT binary patch literal 10746 zcmeHNeQZ-z6u)iPQnupCKsOOs2SY(VH--vMR`$WRY%nYvK_h|Ux>2*WvnwzpaT@A7JEjoMTz!_O5Yw z7Q0Iw*e8gXxEvibi0&2k)sBiD{cUcy*8)8)?lOxcY@xFvSd3|0(D2?3RbqG@4!@|F z|M+75TS?O5lY$oxzhgC;(R`j7jV2bSL{w*D8Z*}`Uo>wL8r3VU{wtr_%17E;Ph> z-oDa$N?y%Lel-Iupb_mu&67aQNdi2}9G+^Y+hs|ak&-rp>$*o9G>Y%4X>B6K|AI=+ z#ibe&LGh$#lVwe5*_?GkD_hYSxwUprTPpA2p9&AB{-K^t*8vZ2HHd-d;rPlPo|U_J zX`yqq$L`sHrs`oK5j4i?#Z4bQ8%aNcXi??VW2A$YVdBADd~V>7&_vN{<9ZJo=SOBj zZ0;ry6DG3s7O~O`gOQ%*Dn}Mu8Z*rnq07X05Gkv$msc|g8Db(9DXfsNVA@=8zEj>$ zqWpdm%ny^&jb@sWmPEhocq5Ci<@cqqq=yYa$Df@%vB}B~0RKR4E3R+s0{cB22g@aR z5;Y_QM?7zX`#Ki?s1o(iO<iyiwX zO(wMw-9tYH8eO&CY6hD^IBeh_XxV}=xnRF71|PD*+ry73f}T`NAP=Ph&^KbcO{lOhwm=UGmE+&T+mfrXf;5?cw^?KI6>|N_|ln$Qa>gY$$S;30x6Pqnu z8_*8UYgSHd$ikrrr|SUHUx*VTt%5M+#{U1;_WOaD$Nkes3TpX_ei8pBY4$ z*}wnsJNF(?Kq}$!9-6v<6fn_p)~A`aqvd^)VE!d%rsrcWPF29@crX<8j|m#~0~GfA z#dD1+Oq9*D_5~h~eS_aPLMWLi%nogfc!!>pTGu8YshB@f(H=`w6ki!U<%DKsX)!GA zKHs)69gX8BLz)s^0z%896?`SG2h#UASIa*%-}>#)c4Y{wed1NpDu^G@v7 zg?!z}*NuEvk?$JvT}Qqf$ae$zZX(|;i@G%%!r zAq@;^U;t@AA@`Fxewquf`gp7Bu2X*bK)F5DBcU`($tnEg^n^W3um1vi9)1L5a}Irdy=@I44gGBtY5ES9qCvc z`?Dw*b~?hS%UYAK!Zw*%+%B~wAwX5yCi0V$f~~LD$=4$z{PhSP0x_a}oSg6qOviaL zvvO*@9($F$f_uf_IXr2M|Er&8<3|x#yR;vQ_ierY`_S(n%+SC!X3m6i%9Ht$M+Em& z>di!`w&UaY8pt2;Pt9yQDIs23CK*#N z4KN-z?N8#DwW|PoxY!=%I56_qe*SyyM0v0e#dfs4ApMW+I}t-Ahbp%zBAt*EnsCx} zAn|NM>^;EP-i@dxq|2VTCfkx%NJ#H1wi{8(%<-nHD&RhdV>?9$q60U!TgTj0`kRML PY~PA+eD`hq^1J^43|weL literal 0 HcmV?d00001 diff --git a/example/1d-linear-convection/ftbs/cpp/01/main.cpp b/example/1d-linear-convection/ftbs/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/plot.py b/example/1d-linear-convection/ftbs/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl b/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod.json b/example/1d-linear-convection/ftbs/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py b/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py b/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt b/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/ftbs/python/01/ftbs.py b/example/1d-linear-convection/ftbs/python/01/ftbs.py new file mode 100644 index 00000000..8d309a89 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01/ftbs.py @@ -0,0 +1,17 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print(u) + +pyplot.plot(numpy.linspace(0, 2, nx), u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01a/ftbs.py b/example/1d-linear-convection/ftbs/python/01a/ftbs.py new file mode 100644 index 00000000..12837e6e --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01a/ftbs.py @@ -0,0 +1,27 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +pyplot.plot(numpy.linspace(0, 2, nx), u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01b/ftbs.py b/example/1d-linear-convection/ftbs/python/01b/ftbs.py new file mode 100644 index 00000000..69f21b40 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01b/ftbs.py @@ -0,0 +1,39 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +utheory = numpy.ones(nx) + +x = numpy.linspace(0, 2, nx) + +pyplot.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +pyplot.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +pyplot.xlabel("$x$") +pyplot.ylabel("$u$") +pyplot.title("Solution field") +pyplot.legend() +pyplot.tight_layout() + +#pyplot.plot(x, u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01c/ftbs.py b/example/1d-linear-convection/ftbs/python/01c/ftbs.py new file mode 100644 index 00000000..8c2b7984 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01c/ftbs.py @@ -0,0 +1,50 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + + +def set_fuction(u, ct) : + for i in range(nx): + xm = i * dx + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +total_t = dt * nt +utheory = numpy.ones(nx) +x = numpy.linspace(0, 2, nx) +print('x=',x) +u = numpy.ones(nx) #numpy function ones() + +set_fuction(u,0) +set_fuction(utheory,c * total_t) + +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) +print(utheory) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +pyplot.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +pyplot.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +pyplot.xlabel("$x$") +pyplot.ylabel("$u$") +pyplot.title("Solution field") +pyplot.legend() +pyplot.tight_layout() +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01d/ftbs.py b/example/1d-linear-convection/ftbs/python/01d/ftbs.py new file mode 100644 index 00000000..5eed5acb --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01d/ftbs.py @@ -0,0 +1,41 @@ +import numpy as np +import matplotlib.pyplot as plt +import time, sys #and load some utilities + +def set_fuction(u, ct) : + for i in range(nx): + xm = i * dx + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +total_t = dt * nt +utheory = np.ones(nx) +x = np.linspace(0, 2, nx) +u = np.ones(nx) + +set_fuction(u,0) +set_fuction(utheory,c * total_t) + +un = np.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp b/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/BurgersField.h b/example/1d-linear-convection/weno3/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt b/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cdd5e14a --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt @@ -0,0 +1,105 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..6b06414c --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp @@ -0,0 +1,281 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp b/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/EulerField.h b/example/1d-linear-convection/weno3/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/weno3/cpp/01/Field.cpp b/example/1d-linear-convection/weno3/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Field.h b/example/1d-linear-convection/weno3/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/Global.cpp b/example/1d-linear-convection/weno3/cpp/01/Global.cpp new file mode 100644 index 00000000..3f560f56 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Global.cpp @@ -0,0 +1,461 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Global.h b/example/1d-linear-convection/weno3/cpp/01/Global.h new file mode 100644 index 00000000..f89bc3c0 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Global.h @@ -0,0 +1,179 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/weno3/cpp/01/Grid.cpp b/example/1d-linear-convection/weno3/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Grid.h b/example/1d-linear-convection/weno3/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp b/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/HeatField.h b/example/1d-linear-convection/weno3/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp b/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/weno3/cpp/01/LogFile.h b/example/1d-linear-convection/weno3/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp b/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Parallel.h b/example/1d-linear-convection/weno3/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/Post.cpp b/example/1d-linear-convection/weno3/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Post.h b/example/1d-linear-convection/weno3/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/weno3/cpp/01/README.txt b/example/1d-linear-convection/weno3/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/weno3/cpp/01/Solver.cpp b/example/1d-linear-convection/weno3/cpp/01/Solver.cpp new file mode 100644 index 00000000..45259b3c --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Solver.cpp @@ -0,0 +1,793 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Solver.h b/example/1d-linear-convection/weno3/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp b/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Vec1d.h b/example/1d-linear-convection/weno3/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Weno.cpp b/example/1d-linear-convection/weno3/cpp/01/Weno.cpp new file mode 100644 index 00000000..211463db --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Weno.cpp @@ -0,0 +1,420 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double beta1 = SQR( v2 - v1 ); + double beta2 = SQR( v3 - v2 ); + + double d1 = 2.0 / 3.0; + double d2 = 1.0 / 3.0; + + // computing nonlinear weights w1, w2, w3 + double c1 = d1 / ( SQR( beta1 + eps ) ); + double c2 = d2 / ( SQR( beta2 + eps ) ); + + double w1 = c1 / ( c1 + c2 ); + double w2 = c2 / ( c1 + c2 ); + + // candiate stencils + double q1 = - v1 / 2.0 + 3.0 / 2.0 * v2; + double q2 = v2 / 2.0 + v3 / 2.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 ); + + return f; +} + +double wcR3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Weno.h b/example/1d-linear-convection/weno3/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp b/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/weno3/cpp/01/ZoneState.h b/example/1d-linear-convection/weno3/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers.json b/example/1d-linear-convection/weno3/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py b/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/cfd.json b/example/1d-linear-convection/weno3/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/heat.json b/example/1d-linear-convection/weno3/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/heat_plot.py b/example/1d-linear-convection/weno3/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/heaticp.json b/example/1d-linear-convection/weno3/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp b/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/hxmath.h b/example/1d-linear-convection/weno3/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/weno3/cpp/01/linearconvection.json b/example/1d-linear-convection/weno3/cpp/01/linearconvection.json new file mode 100644 index 00000000..9491dce2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "upwind1", + "reconstruction" : "upwind1", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns new file mode 100644 index 0000000000000000000000000000000000000000..9bd4494619d6bc5b5cb79dc5fc262b23eacc09e6 GIT binary patch literal 10746 zcmeHNeQZ-z6u)iPQnupCKsOOs2SY(VH--vMR`$WRY%nYvK_h|Ux>2*WvnwzpaT@A7JEjoMTz!_O5Yw z7Q0Iw*e8gXxEvibi0&2k)sBiD{cUcy*8)8)?lOxcY@xFvSd3|0(D2?3RbqG@4!@|F z|M+75TS?O5lY$oxzhgC;(R`j7jV2bSL{w*D8Z*}`Uo>wL8r3VU{wtr_%17E;Ph> z-oDa$N?y%Lel-Iupb_mu&67aQNdi2}9G+^Y+hs|ak&-rp>$*o9G>Y%4X>B6K|AI=+ z#ibe&LGh$#lVwe5*_?GkD_hYSxwUprTPpA2p9&AB{-K^t*8vZ2HHd-d;rPlPo|U_J zX`yqq$L`sHrs`oK5j4i?#Z4bQ8%aNcXi??VW2A$YVdBADd~V>7&_vN{<9ZJo=SOBj zZ0;ry6DG3s7O~O`gOQ%*Dn}Mu8Z*rnq07X05Gkv$msc|g8Db(9DXfsNVA@=8zEj>$ zqWpdm%ny^&jb@sWmPEhocq5Ci<@cqqq=yYa$Df@%vB}B~0RKR4E3R+s0{cB22g@aR z5;Y_QM?7zX`#Ki?s1o(iO<iyiwX zO(wMw-9tYH8eO&CY6hD^IBeh_XxV}=xnRF71|PD*+ry73f}T`NAP=Ph&^KbcO{lOhwm=UGmE+&T+mfrXf;5?cw^?KI6>|N_|ln$Qa>gY$$S;30x6Pqnu z8_*8UYgSHd$ikrrr|SUHUx*VTt%5M+#{U1;_WOaD$Nkes3TpX_ei8pBY4$ z*}wnsJNF(?Kq}$!9-6v<6fn_p)~A`aqvd^)VE!d%rsrcWPF29@crX<8j|m#~0~GfA z#dD1+Oq9*D_5~h~eS_aPLMWLi%nogfc!!>pTGu8YshB@f(H=`w6ki!U<%DKsX)!GA zKHs)69gX8BLz)s^0z%896?`SG2h#UASIa*%-}>#)c4Y{wed1NpDu^G@v7 zg?!z}*NuEvk?$JvT}Qqf$ae$zZX(|;i@G%%!r zAq@;^U;t@AA@`Fxewquf`gp7Bu2X*bK)F5DBcU`($tnEg^n^W3um1vi9)1L5a}Irdy=@I44gGBtY5ES9qCvc z`?Dw*b~?hS%UYAK!Zw*%+%B~wAwX5yCi0V$f~~LD$=4$z{PhSP0x_a}oSg6qOviaL zvvO*@9($F$f_uf_IXr2M|Er&8<3|x#yR;vQ_ierY`_S(n%+SC!X3m6i%9Ht$M+Em& z>di!`w&UaY8pt2;Pt9yQDIs23CK*#N z4KN-z?N8#DwW|PoxY!=%I56_qe*SyyM0v0e#dfs4ApMW+I}t-Ahbp%zBAt*EnsCx} zAn|NM>^;EP-i@dxq|2VTCfkx%NJ#H1wi{8(%<-nHD&RhdV>?9$q60U!TgTj0`kRML PY~PA+eD`hq^1J^43|weL literal 0 HcmV?d00001 diff --git a/example/1d-linear-convection/weno3/cpp/01/main.cpp b/example/1d-linear-convection/weno3/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/plot.py b/example/1d-linear-convection/weno3/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/plotting2.jl b/example/1d-linear-convection/weno3/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/weno3/cpp/01/sod.json b/example/1d-linear-convection/weno3/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_plot.py b/example/1d-linear-convection/weno3/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_sort.py b/example/1d-linear-convection/weno3/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt b/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/weno3/python/01/weno3.py b/example/1d-linear-convection/weno3/python/01/weno3.py new file mode 100644 index 00000000..da81ef74 --- /dev/null +++ b/example/1d-linear-convection/weno3/python/01/weno3.py @@ -0,0 +1,68 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 定义求解区域的网格和时间步长 +nx = 100 # 网格数 +L = 1 # 区域长度 +dx = L / nx # 网格步长 +dt = 0.01 # 时间步长 +nt = 10 # 时间步数 +a = 1 # 对流速度 + +# 定义线性对流方程的初始条件和边界条件 +x = np.linspace(0, L, nx) +u0 = np.sin(2 * np.pi * x) # 初始条件 +u = u0.copy() +u_bc = np.concatenate((u[-3:], u, u[:3])) # 周期边界条件 + +# 定义WENO方法的参数 +epsilon = 1e-6 # 避免分母为0 +p = 2 # 权重参数 + +# 循环求解线性对流方程 +for n in range(nt): + # 计算每个子模板的光滑度指标 + beta_0 = (u_bc[2:nx+2] - u_bc[1:nx+1])**2 + beta_1 = (u_bc[3:nx+3] - u_bc[2:nx+2])**2 + beta_3 = (1/3) * ((u_bc[1:nx+1] - 2*u_bc[2:nx+2] + u_bc[3:nx+3]) / dx)**2 + \ + (1/4) * ((u_bc[3:nx+3] - u_bc[1:nx+1]) / dx)**2 + + # 计算权重 + d_0 = 1/3 + d_1 = 2/3 + d_3 = 1/3 + alpha_0 = d_0 / (beta_0 + epsilon)**p + alpha_1 = d_1 / (beta_1 + epsilon)**p + alpha_3 = d_3 / (beta_3 + epsilon)**p + w_0 = alpha_0 / (alpha_0 + alpha_1 + alpha_3) + w_1 = alpha_1 / (alpha_0 + alpha_1 + alpha_3) + w_3 = alpha_3 / (alpha_0 + alpha_1 + alpha_3) + + # 计算重构值 + f_0 = -0.5 * u_bc[1:nx+1] + 1.5 * u_bc[2:nx+2] + f_1 = 0.5 * u_bc[2:nx+2] + 0.5 * u_bc[3:nx+3] + f_3 = (-1/6) * u_bc[1:nx+1] + (5/6) * u_bc[2:nx+2] + (1/3) * u_bc[3:nx+3] + f_weno = w_0 * f_0 + w_1 * f_1 + w_3 * f_3 + + # 更新解 + u = u - dt / dx * (f_weno - np.roll(f_weno, 1)) + + # 更新边界条件 + u_bc = np.concatenate((u[-3:], u, u[:3])) + +# 计算理论解 +t = nt * dt +u_exact = np.sin(2 * np.pi * (x - a * t)) +print("at=",a * t) +print("u0=",u0) +print("u_exact=",u_exact) + +# 绘制结果 +#plt.plot(x, u, label='WENO Solution') +plt.plot(x, u_exact, label='Exact Solution', linestyle='--') +plt.plot(x, u0, label='init Solution', linestyle='--') +plt.legend() +plt.title('Comparison of WENO Solution and Exact Solution') +plt.xlabel('x') +plt.ylabel('u') +plt.show() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt new file mode 100644 index 00000000..3d9c1611 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3978472836E+00 + -0.1475000000E+01 0.4267107631E+00 + -0.1425000000E+01 0.4551038904E+00 + -0.1375000000E+01 0.4829359721E+00 + -0.1325000000E+01 0.5100994918E+00 + -0.1275000000E+01 0.5364642119E+00 + -0.1225000000E+01 0.5618685745E+00 + -0.1175000000E+01 0.5861066686E+00 + -0.1125000000E+01 0.6089075423E+00 + -0.1075000000E+01 0.6299004565E+00 + -0.1025000000E+01 0.6485521486E+00 + -0.9750000000E+00 0.6640421254E+00 + -0.9250000000E+00 0.6749787962E+00 + -0.8750000000E+00 0.6786049580E+00 + -0.8250000000E+00 0.6661069824E+00 + -0.7750000000E+00 0.5397624003E+00 + -0.7250000000E+00 -0.2020829473E-01 + -0.6750000000E+00 -0.2250720675E+00 + -0.6250000000E+00 -0.2166894789E+00 + -0.5750000000E+00 -0.2032813898E+00 + -0.5250000000E+00 -0.1863137042E+00 + -0.4750000000E+00 -0.1666851401E+00 + -0.4250000000E+00 -0.1449884793E+00 + -0.3750000000E+00 -0.1216322279E+00 + -0.3250000000E+00 -0.9689476951E-01 + -0.2750000000E+00 -0.7091556422E-01 + -0.2250000000E+00 -0.4347209157E-01 + -0.1750000000E+00 -0.1011179643E-01 + -0.1250000000E+00 0.3697148653E-01 + -0.7500000000E-01 0.6707060641E-01 + -0.2500000000E-01 0.9723084379E-01 + 0.2500000000E-01 0.1275040098E+00 + 0.7500000000E-01 0.1578541658E+00 + 0.1250000000E+00 0.1882367792E+00 + 0.1750000000E+00 0.2186062738E+00 + 0.2250000000E+00 0.2489166057E+00 + 0.2750000000E+00 0.2791207239E+00 + 0.3250000000E+00 0.3091697383E+00 + 0.3750000000E+00 0.3390119185E+00 + 0.4250000000E+00 0.3685915076E+00 + 0.4750000000E+00 0.3978472836E+00 + 0.5250000000E+00 0.4267107631E+00 + 0.5750000000E+00 0.4551038904E+00 + 0.6250000000E+00 0.4829359721E+00 + 0.6750000000E+00 0.5100994918E+00 + 0.7250000000E+00 0.5364642119E+00 + 0.7750000000E+00 0.5618685745E+00 + 0.8250000000E+00 0.5861066686E+00 + 0.8750000000E+00 0.6089075423E+00 + 0.9250000000E+00 0.6299004565E+00 + 0.9750000000E+00 0.6485521486E+00 + 0.1025000000E+01 0.6640421254E+00 + 0.1075000000E+01 0.6749787962E+00 + 0.1125000000E+01 0.6786049580E+00 + 0.1175000000E+01 0.6661069824E+00 + 0.1225000000E+01 0.5397624003E+00 + 0.1275000000E+01 -0.2020829473E-01 + 0.1325000000E+01 -0.2250720675E+00 + 0.1375000000E+01 -0.2166894789E+00 + 0.1425000000E+01 -0.2032813898E+00 + 0.1475000000E+01 -0.1863137042E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt new file mode 100644 index 00000000..abb3d18c --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3869953761E+00 + -0.1475000000E+01 0.4169194255E+00 + -0.1425000000E+01 0.4469413982E+00 + -0.1375000000E+01 0.4770459572E+00 + -0.1325000000E+01 0.5062530397E+00 + -0.1275000000E+01 0.5341942582E+00 + -0.1225000000E+01 0.5612180194E+00 + -0.1175000000E+01 0.5878990245E+00 + -0.1125000000E+01 0.6146216447E+00 + -0.1075000000E+01 0.6417418513E+00 + -0.1025000000E+01 0.6701424162E+00 + -0.9750000000E+00 0.6966269005E+00 + -0.9250000000E+00 0.7154578360E+00 + -0.8750000000E+00 0.7229834685E+00 + -0.8250000000E+00 0.7226468112E+00 + -0.7750000000E+00 0.6177183553E+00 + -0.7250000000E+00 -0.1196667134E+00 + -0.6750000000E+00 -0.2371902797E+00 + -0.6250000000E+00 -0.2300309096E+00 + -0.5750000000E+00 -0.2109122282E+00 + -0.5250000000E+00 -0.1872517428E+00 + -0.4750000000E+00 -0.1640755253E+00 + -0.4250000000E+00 -0.1409622978E+00 + -0.3750000000E+00 -0.1156962459E+00 + -0.3250000000E+00 -0.8862474712E-01 + -0.2750000000E+00 -0.6163968850E-01 + -0.2250000000E+00 -0.3357086015E-01 + -0.1750000000E+00 -0.4875134725E-02 + -0.1250000000E+00 0.2427735989E-01 + -0.7500000000E-01 0.5369647834E-01 + -0.2500000000E-01 0.8336991079E-01 + 0.2500000000E-01 0.1132766827E+00 + 0.7500000000E-01 0.1433855550E+00 + 0.1250000000E+00 0.1736613168E+00 + 0.1750000000E+00 0.2040776671E+00 + 0.2250000000E+00 0.2346009631E+00 + 0.2750000000E+00 0.2651897403E+00 + 0.3250000000E+00 0.2958737330E+00 + 0.3750000000E+00 0.3266782024E+00 + 0.4250000000E+00 0.3570149022E+00 + 0.4750000000E+00 0.3869953761E+00 + 0.5250000000E+00 0.4169194255E+00 + 0.5750000000E+00 0.4469413982E+00 + 0.6250000000E+00 0.4770459572E+00 + 0.6750000000E+00 0.5062530397E+00 + 0.7250000000E+00 0.5341942582E+00 + 0.7750000000E+00 0.5612180194E+00 + 0.8250000000E+00 0.5878990245E+00 + 0.8750000000E+00 0.6146216447E+00 + 0.9250000000E+00 0.6417418513E+00 + 0.9750000000E+00 0.6701424162E+00 + 0.1025000000E+01 0.6966269005E+00 + 0.1075000000E+01 0.7154578360E+00 + 0.1125000000E+01 0.7229834685E+00 + 0.1175000000E+01 0.7226468112E+00 + 0.1225000000E+01 0.6177183553E+00 + 0.1275000000E+01 -0.1196667134E+00 + 0.1325000000E+01 -0.2371902797E+00 + 0.1375000000E+01 -0.2300309096E+00 + 0.1425000000E+01 -0.2109122282E+00 + 0.1475000000E+01 -0.1872517428E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt new file mode 100644 index 00000000..990cecd5 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868642875E+00 + -0.1475000000E+01 0.4168486845E+00 + -0.1425000000E+01 0.4465638041E+00 + -0.1375000000E+01 0.4759475543E+00 + -0.1325000000E+01 0.5049291462E+00 + -0.1275000000E+01 0.5334296252E+00 + -0.1225000000E+01 0.5613544319E+00 + -0.1175000000E+01 0.5885832770E+00 + -0.1125000000E+01 0.6149692665E+00 + -0.1075000000E+01 0.6403339550E+00 + -0.1025000000E+01 0.6644774657E+00 + -0.9750000000E+00 0.6872033878E+00 + -0.9250000000E+00 0.7081750801E+00 + -0.8750000000E+00 0.7274800566E+00 + -0.8250000000E+00 0.7397132124E+00 + -0.7750000000E+00 0.6519815577E+00 + -0.7250000000E+00 -0.1542327846E+00 + -0.6750000000E+00 -0.2403632288E+00 + -0.6250000000E+00 -0.2258780818E+00 + -0.5750000000E+00 -0.2076583578E+00 + -0.5250000000E+00 -0.1870168045E+00 + -0.4750000000E+00 -0.1644425502E+00 + -0.4250000000E+00 -0.1403060419E+00 + -0.3750000000E+00 -0.1149259803E+00 + -0.3250000000E+00 -0.8853938919E-01 + -0.2750000000E+00 -0.6131743746E-01 + -0.2250000000E+00 -0.3339869832E-01 + -0.1750000000E+00 -0.4893686380E-02 + -0.1250000000E+00 0.2410314538E-01 + -0.7500000000E-01 0.5348803369E-01 + -0.2500000000E-01 0.8320007249E-01 + 0.2500000000E-01 0.1131807815E+00 + 0.7500000000E-01 0.1433750622E+00 + 0.1250000000E+00 0.1737314324E+00 + 0.1750000000E+00 0.2042014559E+00 + 0.2250000000E+00 0.2347389162E+00 + 0.2750000000E+00 0.2652989314E+00 + 0.3250000000E+00 0.2958370215E+00 + 0.3750000000E+00 0.3263083800E+00 + 0.4250000000E+00 0.3566669371E+00 + 0.4750000000E+00 0.3868642875E+00 + 0.5250000000E+00 0.4168486845E+00 + 0.5750000000E+00 0.4465638041E+00 + 0.6250000000E+00 0.4759475543E+00 + 0.6750000000E+00 0.5049291462E+00 + 0.7250000000E+00 0.5334296252E+00 + 0.7750000000E+00 0.5613544319E+00 + 0.8250000000E+00 0.5885832770E+00 + 0.8750000000E+00 0.6149692665E+00 + 0.9250000000E+00 0.6403339550E+00 + 0.9750000000E+00 0.6644774657E+00 + 0.1025000000E+01 0.6872033878E+00 + 0.1075000000E+01 0.7081750801E+00 + 0.1125000000E+01 0.7274800566E+00 + 0.1175000000E+01 0.7397132124E+00 + 0.1225000000E+01 0.6519815577E+00 + 0.1275000000E+01 -0.1542327846E+00 + 0.1325000000E+01 -0.2403632288E+00 + 0.1375000000E+01 -0.2258780818E+00 + 0.1425000000E+01 -0.2076583578E+00 + 0.1475000000E+01 -0.1870168045E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt new file mode 100644 index 00000000..a1c7a982 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868411771E+00 + -0.1475000000E+01 0.4168236420E+00 + -0.1425000000E+01 0.4465364676E+00 + -0.1375000000E+01 0.4759171894E+00 + -0.1325000000E+01 0.5048952040E+00 + -0.1275000000E+01 0.5333892034E+00 + -0.1225000000E+01 0.5613037091E+00 + -0.1175000000E+01 0.5885242249E+00 + -0.1125000000E+01 0.6149104174E+00 + -0.1075000000E+01 0.6402843654E+00 + -0.1025000000E+01 0.6644151712E+00 + -0.9750000000E+00 0.6870334937E+00 + -0.9250000000E+00 0.7075915274E+00 + -0.8750000000E+00 0.7260416325E+00 + -0.8250000000E+00 0.7403336059E+00 + -0.7750000000E+00 0.6654229727E+00 + -0.7250000000E+00 -0.1662713613E+00 + -0.6750000000E+00 -0.2401134717E+00 + -0.6250000000E+00 -0.2255829480E+00 + -0.5750000000E+00 -0.2075787414E+00 + -0.5250000000E+00 -0.1869765428E+00 + -0.4750000000E+00 -0.1643954233E+00 + -0.4250000000E+00 -0.1402652374E+00 + -0.3750000000E+00 -0.1148942559E+00 + -0.3250000000E+00 -0.8851131858E-01 + -0.2750000000E+00 -0.6129329546E-01 + -0.2250000000E+00 -0.3338063416E-01 + -0.1750000000E+00 -0.4887861141E-02 + -0.1250000000E+00 0.2408928579E-01 + -0.7500000000E-01 0.5346853666E-01 + -0.2500000000E-01 0.8318001505E-01 + 0.2500000000E-01 0.1131613770E+00 + 0.7500000000E-01 0.1433561374E+00 + 0.1250000000E+00 0.1737124894E+00 + 0.1750000000E+00 0.2041821994E+00 + 0.2250000000E+00 0.2347193748E+00 + 0.2750000000E+00 0.2652792397E+00 + 0.3250000000E+00 0.2958171038E+00 + 0.3750000000E+00 0.3262878842E+00 + 0.4250000000E+00 0.3566453650E+00 + 0.4750000000E+00 0.3868411771E+00 + 0.5250000000E+00 0.4168236420E+00 + 0.5750000000E+00 0.4465364676E+00 + 0.6250000000E+00 0.4759171894E+00 + 0.6750000000E+00 0.5048952040E+00 + 0.7250000000E+00 0.5333892034E+00 + 0.7750000000E+00 0.5613037091E+00 + 0.8250000000E+00 0.5885242249E+00 + 0.8750000000E+00 0.6149104174E+00 + 0.9250000000E+00 0.6402843654E+00 + 0.9750000000E+00 0.6644151712E+00 + 0.1025000000E+01 0.6870334937E+00 + 0.1075000000E+01 0.7075915274E+00 + 0.1125000000E+01 0.7260416325E+00 + 0.1175000000E+01 0.7403336059E+00 + 0.1225000000E+01 0.6654229727E+00 + 0.1275000000E+01 -0.1662713613E+00 + 0.1325000000E+01 -0.2401134717E+00 + 0.1375000000E+01 -0.2255829480E+00 + 0.1425000000E+01 -0.2075787414E+00 + 0.1475000000E+01 -0.1869765428E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt new file mode 100644 index 00000000..39b7457b --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868395234E+00 + -0.1475000000E+01 0.4168214927E+00 + -0.1425000000E+01 0.4465338877E+00 + -0.1375000000E+01 0.4759141663E+00 + -0.1325000000E+01 0.5048916070E+00 + -0.1275000000E+01 0.5333847709E+00 + -0.1225000000E+01 0.5612980406E+00 + -0.1175000000E+01 0.5885167892E+00 + -0.1125000000E+01 0.6149004218E+00 + -0.1075000000E+01 0.6402720415E+00 + -0.1025000000E+01 0.6644016921E+00 + -0.9750000000E+00 0.6869917808E+00 + -0.9250000000E+00 0.7075737293E+00 + -0.8750000000E+00 0.7256981164E+00 + -0.8250000000E+00 0.7401377007E+00 + -0.7750000000E+00 0.6729567942E+00 + -0.7250000000E+00 -0.1730889524E+00 + -0.6750000000E+00 -0.2402469630E+00 + -0.6250000000E+00 -0.2255384038E+00 + -0.5750000000E+00 -0.2075674444E+00 + -0.5250000000E+00 -0.1869675885E+00 + -0.4750000000E+00 -0.1643888705E+00 + -0.4250000000E+00 -0.1402608200E+00 + -0.3750000000E+00 -0.1148911193E+00 + -0.3250000000E+00 -0.8850907058E-01 + -0.2750000000E+00 -0.6129169639E-01 + -0.2250000000E+00 -0.3337964815E-01 + -0.1750000000E+00 -0.4887557395E-02 + -0.1250000000E+00 0.2408892100E-01 + -0.7500000000E-01 0.5346824771E-01 + -0.2500000000E-01 0.8317964560E-01 + 0.2500000000E-01 0.1131613563E+00 + 0.7500000000E-01 0.1433564991E+00 + 0.1250000000E+00 0.1737128807E+00 + 0.1750000000E+00 0.2041824417E+00 + 0.2250000000E+00 0.2347195521E+00 + 0.2750000000E+00 0.2652793505E+00 + 0.3250000000E+00 0.2958169883E+00 + 0.3750000000E+00 0.3262873440E+00 + 0.4250000000E+00 0.3566442736E+00 + 0.4750000000E+00 0.3868395234E+00 + 0.5250000000E+00 0.4168214927E+00 + 0.5750000000E+00 0.4465338877E+00 + 0.6250000000E+00 0.4759141663E+00 + 0.6750000000E+00 0.5048916070E+00 + 0.7250000000E+00 0.5333847709E+00 + 0.7750000000E+00 0.5612980406E+00 + 0.8250000000E+00 0.5885167892E+00 + 0.8750000000E+00 0.6149004218E+00 + 0.9250000000E+00 0.6402720415E+00 + 0.9750000000E+00 0.6644016921E+00 + 0.1025000000E+01 0.6869917808E+00 + 0.1075000000E+01 0.7075737293E+00 + 0.1125000000E+01 0.7256981164E+00 + 0.1175000000E+01 0.7401377007E+00 + 0.1225000000E+01 0.6729567942E+00 + 0.1275000000E+01 -0.1730889524E+00 + 0.1325000000E+01 -0.2402469630E+00 + 0.1375000000E+01 -0.2255384038E+00 + 0.1425000000E+01 -0.2075674444E+00 + 0.1475000000E+01 -0.1869675885E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt new file mode 100644 index 00000000..889c1555 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868392085E+00 + -0.1475000000E+01 0.4168213307E+00 + -0.1425000000E+01 0.4465337167E+00 + -0.1375000000E+01 0.4759138544E+00 + -0.1325000000E+01 0.5048910997E+00 + -0.1275000000E+01 0.5333840599E+00 + -0.1225000000E+01 0.5612971006E+00 + -0.1175000000E+01 0.5885155255E+00 + -0.1125000000E+01 0.6148986459E+00 + -0.1075000000E+01 0.6402694620E+00 + -0.1025000000E+01 0.6643984579E+00 + -0.9750000000E+00 0.6869810297E+00 + -0.9250000000E+00 0.7075737507E+00 + -0.8750000000E+00 0.7256087468E+00 + -0.8250000000E+00 0.7400298908E+00 + -0.7750000000E+00 0.6774720179E+00 + -0.7250000000E+00 -0.1775213300E+00 + -0.6750000000E+00 -0.2401222009E+00 + -0.6250000000E+00 -0.2255340650E+00 + -0.5750000000E+00 -0.2075635018E+00 + -0.5250000000E+00 -0.1869654336E+00 + -0.4750000000E+00 -0.1643875389E+00 + -0.4250000000E+00 -0.1402599982E+00 + -0.3750000000E+00 -0.1148905767E+00 + -0.3250000000E+00 -0.8850868906E-01 + -0.2750000000E+00 -0.6129141337E-01 + -0.2250000000E+00 -0.3337945810E-01 + -0.1750000000E+00 -0.4887493661E-02 + -0.1250000000E+00 0.2408884668E-01 + -0.7500000000E-01 0.5346812259E-01 + -0.2500000000E-01 0.8317978735E-01 + 0.2500000000E-01 0.1131612490E+00 + 0.7500000000E-01 0.1433561731E+00 + 0.1250000000E+00 0.1737128044E+00 + 0.1750000000E+00 0.2041828013E+00 + 0.2250000000E+00 0.2347198794E+00 + 0.2750000000E+00 0.2652792412E+00 + 0.3250000000E+00 0.2958164417E+00 + 0.3750000000E+00 0.3262866535E+00 + 0.4250000000E+00 0.3566437225E+00 + 0.4750000000E+00 0.3868392085E+00 + 0.5250000000E+00 0.4168213307E+00 + 0.5750000000E+00 0.4465337167E+00 + 0.6250000000E+00 0.4759138544E+00 + 0.6750000000E+00 0.5048910997E+00 + 0.7250000000E+00 0.5333840599E+00 + 0.7750000000E+00 0.5612971006E+00 + 0.8250000000E+00 0.5885155255E+00 + 0.8750000000E+00 0.6148986459E+00 + 0.9250000000E+00 0.6402694620E+00 + 0.9750000000E+00 0.6643984579E+00 + 0.1025000000E+01 0.6869810297E+00 + 0.1075000000E+01 0.7075737507E+00 + 0.1125000000E+01 0.7256087468E+00 + 0.1175000000E+01 0.7400298908E+00 + 0.1225000000E+01 0.6774720179E+00 + 0.1275000000E+01 -0.1775213300E+00 + 0.1325000000E+01 -0.2401222009E+00 + 0.1375000000E+01 -0.2255340650E+00 + 0.1425000000E+01 -0.2075635018E+00 + 0.1475000000E+01 -0.1869654336E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt new file mode 100644 index 00000000..24393a34 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868392635E+00 + -0.1475000000E+01 0.4168213348E+00 + -0.1425000000E+01 0.4465336993E+00 + -0.1375000000E+01 0.4759138410E+00 + -0.1325000000E+01 0.5048910758E+00 + -0.1275000000E+01 0.5333839905E+00 + -0.1225000000E+01 0.5612969697E+00 + -0.1175000000E+01 0.5885153145E+00 + -0.1125000000E+01 0.6148982967E+00 + -0.1075000000E+01 0.6402688560E+00 + -0.1025000000E+01 0.6643975691E+00 + -0.9750000000E+00 0.6869777983E+00 + -0.9250000000E+00 0.7075740090E+00 + -0.8750000000E+00 0.7255780485E+00 + -0.8250000000E+00 0.7399754487E+00 + -0.7750000000E+00 0.6810919060E+00 + -0.7250000000E+00 -0.1811233524E+00 + -0.6750000000E+00 -0.2400531259E+00 + -0.6250000000E+00 -0.2255337663E+00 + -0.5750000000E+00 -0.2075620178E+00 + -0.5250000000E+00 -0.1869648182E+00 + -0.4750000000E+00 -0.1643872091E+00 + -0.4250000000E+00 -0.1402598192E+00 + -0.3750000000E+00 -0.1148904706E+00 + -0.3250000000E+00 -0.8850862004E-01 + -0.2750000000E+00 -0.6129137302E-01 + -0.2250000000E+00 -0.3337943999E-01 + -0.1750000000E+00 -0.4887482940E-02 + -0.1250000000E+00 0.2408884789E-01 + -0.7500000000E-01 0.5346811667E-01 + -0.2500000000E-01 0.8317978567E-01 + 0.2500000000E-01 0.1131612536E+00 + 0.7500000000E-01 0.1433561665E+00 + 0.1250000000E+00 0.1737128227E+00 + 0.1750000000E+00 0.2041827929E+00 + 0.2250000000E+00 0.2347198883E+00 + 0.2750000000E+00 0.2652792582E+00 + 0.3250000000E+00 0.2958164964E+00 + 0.3750000000E+00 0.3262867483E+00 + 0.4250000000E+00 0.3566438179E+00 + 0.4750000000E+00 0.3868392635E+00 + 0.5250000000E+00 0.4168213348E+00 + 0.5750000000E+00 0.4465336993E+00 + 0.6250000000E+00 0.4759138410E+00 + 0.6750000000E+00 0.5048910758E+00 + 0.7250000000E+00 0.5333839905E+00 + 0.7750000000E+00 0.5612969697E+00 + 0.8250000000E+00 0.5885153145E+00 + 0.8750000000E+00 0.6148982967E+00 + 0.9250000000E+00 0.6402688560E+00 + 0.9750000000E+00 0.6643975691E+00 + 0.1025000000E+01 0.6869777983E+00 + 0.1075000000E+01 0.7075740090E+00 + 0.1125000000E+01 0.7255780485E+00 + 0.1175000000E+01 0.7399754487E+00 + 0.1225000000E+01 0.6810919060E+00 + 0.1275000000E+01 -0.1811233524E+00 + 0.1325000000E+01 -0.2400531259E+00 + 0.1375000000E+01 -0.2255337663E+00 + 0.1425000000E+01 -0.2075620178E+00 + 0.1475000000E+01 -0.1869648182E+00 diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/README.txt b/example/burgers/inviscid-1d/eno1/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..b02416dc --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 @@ -0,0 +1,284 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 1 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.0d0, 1.0d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/plot.py b/example/burgers/inviscid-1d/eno1/fortran/01/plot.py new file mode 100644 index 00000000..19756784 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno1") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno1/julia/01/eno.jl b/example/burgers/inviscid-1d/eno1/julia/01/eno.jl new file mode 100644 index 00000000..ff4ffc1a --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/julia/01/eno.jl @@ -0,0 +1,206 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 1 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing where needed +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) # Adjusted to 0-based +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) # Corrected to 0-based +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Corrected to match Python’s 0-based dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 # Adjusted from 2:iorder since m starts at 1 in Python + for j in 1:ntcell-1 # Adjusted from 2:ntcell-1 to match Python’s 1:ntcell + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 # Adjusted from 2:iorder + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 1.0 ] + coef[1, :] = [ 1.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/julia/01/plot.py b/example/burgers/inviscid-1d/eno1/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01/eno.py b/example/burgers/inviscid-1d/eno1/python/01/eno.py new file mode 100644 index 00000000..978fe40d --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01/eno.py @@ -0,0 +1,169 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 1 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01/plot.py b/example/burgers/inviscid-1d/eno1/python/01/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01a/eno.py b/example/burgers/inviscid-1d/eno1/python/01a/eno.py new file mode 100644 index 00000000..c1571b74 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01a/eno.py @@ -0,0 +1,169 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01a/plot.py b/example/burgers/inviscid-1d/eno1/python/01a/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01a/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01b/eno.py b/example/burgers/inviscid-1d/eno1/python/01b/eno.py new file mode 100644 index 00000000..93b35c05 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01b/eno.py @@ -0,0 +1,166 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01b/plot.py b/example/burgers/inviscid-1d/eno1/python/01b/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01b/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01c/eno.py b/example/burgers/inviscid-1d/eno1/python/01c/eno.py new file mode 100644 index 00000000..751fe6ab --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01c/eno.py @@ -0,0 +1,198 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + #dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + #ighost = 2 + #ishift = ighost + 1=3 + #i=0,1,...,nx + #i+ishift=3,4,...,nx+3 + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + #i=0,1,...,nx + #i+ishift=3,4,...,nx+3 + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + #print(f'l1={l1},l2={l2},k1={k1},k2={k2},i={i}') + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost=2,-ighost=-2 + #ishift = ighost + 1=3 + #ist = 1 + ishift + #ied = nx + ishift + #i=-2,-1,0 + #ishift+i=3-2,3-1,3+0=1,2,3 + #ied + i=ied-2,ied-1,ied+0 + #ist=ishift + #ied=nx-1+ishift + #ist-1=2 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #i=1,2 + #ied+i=ied+1,ied+2 + #ist-1=2 + #ist-1+i=3,4 + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +#ighost = iorder +ighost = 2 +ishift = ighost + 1 +#ist = 1 + ishift +#ied = nx + ishift +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +#dd = np.zeros((ighost, ntcell + 1)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01c/plot.py b/example/burgers/inviscid-1d/eno1/python/01c/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01c/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01d/eno.py b/example/burgers/inviscid-1d/eno1/python/01d/eno.py new file mode 100644 index 00000000..d3ea1be8 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01d/eno.py @@ -0,0 +1,185 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost=2,-ighost=-2 + #ishift = ighost + 1=3 + #ist = 1 + ishift + #ied = nx + ishift + #i=-2,-1,0 + #ishift+i=3-2,3-1,3+0=1,2,3 + #ied + i=ied-2,ied-1,ied+0 + #ist=ishift + #ied=nx-1+ishift + #ist-1=2 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #i=1,2 + #ied+i=ied+1,ied+2 + #ist-1=2 + #ist-1+i=3,4 + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01d/plot.py b/example/burgers/inviscid-1d/eno1/python/01d/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01d/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/02/eno.py b/example/burgers/inviscid-1d/eno1/python/02/eno.py new file mode 100644 index 00000000..71b6fef1 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/02/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost = 2 + #i=-2,-1,0 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #ighost = 2 + #i=1,2,3 + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/02/plot.py b/example/burgers/inviscid-1d/eno1/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..471acb82 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 new file mode 100644 index 00000000..4fc96f70 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 new file mode 100644 index 00000000..e3a08d37 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: u(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, u, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), u(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = u( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u, nx, ighost ) + call update_oldfield(un, u, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + u(i) = u(i) + dt * res(i) + enddo + call boundary( u, nx, ighost ) + + call residual(u) + + do i = 1, nx + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u, nx, ighost ) + + call residual(u) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u, nx, ighost ) + + call update_oldfield(un, u, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 new file mode 100644 index 00000000..ad471194 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 @@ -0,0 +1,272 @@ +module global + implicit none + !integer, parameter :: nx = 40 + integer, parameter :: nx = 10 + !integer, parameter :: ighost = 10 + integer, parameter :: ighost = 2 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + real(8) :: res(ist:ied) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = ist, ied + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i, nx + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + implicit none + real(8),dimension(:) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + u(i) = u(i) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 new file mode 100644 index 00000000..e82b32bb --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 @@ -0,0 +1,271 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + real(8) :: res(ist:ied) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + u(i) = u(i) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 new file mode 100644 index 00000000..faa4d065 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + !real(8) :: res(ist:ied) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 new file mode 100644 index 00000000..d4f2b30e --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(ii) - flux(ii-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(0:nx) + integer :: i, ii + + do i = ist-1, ied + ii = i - ist + 1 + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(ii) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(ii) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(ii) = 0 + else + flux(ii) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 new file mode 100644 index 00000000..d9e8ebe9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 @@ -0,0 +1,278 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(ii) - flux(ii-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i, ii + + do i = ist-1, ied + ii = i - ist + 1 + if ( up1_2m(ii) >= 0 ) then + if ( up1_2p(ii) >= 0 ) then + flux(ii) = 0.5 * up1_2m(ii) * up1_2m(ii) + else + flux(ii) = 0.5 * ( up1_2m(ii) * up1_2m(ii) + up1_2p(ii) * up1_2p(ii) ) + endif + else + if ( up1_2p(ii) >= 0 ) then + flux(ii) = 0 + else + flux(ii) = 0.5 * up1_2p(ii) * up1_2p(ii) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 new file mode 100644 index 00000000..7837f05f --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 new file mode 100644 index 00000000..3019cd63 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 @@ -0,0 +1,279 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 new file mode 100644 index 00000000..a0bdcc18 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 @@ -0,0 +1,279 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj, kk, k + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do k = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(k,j) = dd(k-1,j+1)-dd(k-1,j) + enddo + enddo + + do i = 0, nx + j = i + ist - 1 + il(i) = j + ir(i) = j + 1 + do k=1,iorder-1 + if ( abs(dd(k,il(i)-1)) <= abs(dd(k,il(i))) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(k,ir(i)-1)) <= abs(dd(k,ir(i))) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + j = i + ist - 1 + k1 = il(i) + k2 = ir(i) + l1 = j - k1 + 1 + l2 = j - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = ist + i - 1 + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = ist + i - 1 + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 new file mode 100644 index 00000000..c80fdaa5 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + xcc(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = i + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = i + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = i + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 new file mode 100644 index 00000000..a667919a --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 @@ -0,0 +1,284 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/README.txt b/example/burgers/inviscid-1d/eno2/fortran/02/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 new file mode 100644 index 00000000..723e75eb --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 @@ -0,0 +1,286 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [ 1.5d0, -0.5d0, & + 0.5d0, 0.5d0, & + -0.5d0, 1.5d0 ] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/plot.py b/example/burgers/inviscid-1d/eno2/fortran/02/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/julia/01/eno.jl b/example/burgers/inviscid-1d/eno2/julia/01/eno.jl new file mode 100644 index 00000000..448367b9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/julia/01/eno.jl @@ -0,0 +1,207 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 2 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 3.0/2.0, -1.0/2.0 ] + coef[1, :] = [ 3.0/2.0, -1.0/2.0 ] + coef[2, :] = [ -1.0/2.0, 3.0/2.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/julia/01/plot.py b/example/burgers/inviscid-1d/eno2/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/01/eno.py b/example/burgers/inviscid-1d/eno2/python/01/eno.py new file mode 100644 index 00000000..23773a74 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/01/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 2 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/01/plot.py b/example/burgers/inviscid-1d/eno2/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/02/eno.py b/example/burgers/inviscid-1d/eno2/python/02/eno.py new file mode 100644 index 00000000..dba66619 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/02/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 2 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/02/plot.py b/example/burgers/inviscid-1d/eno2/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/03/eno.py b/example/burgers/inviscid-1d/eno2/python/03/eno.py new file mode 100644 index 00000000..a00eee5e --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/03/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 2 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/03/plot.py b/example/burgers/inviscid-1d/eno2/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/README.txt b/example/burgers/inviscid-1d/eno3/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..5ceb9b39 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 @@ -0,0 +1,287 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 3 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [ 1.8333333333333333d0, -1.1666666666666667d0, 0.3333333333333333d0, & + 0.3333333333333333d0, 0.8333333333333333d0, -0.1666666666666667d0, & + -0.1666666666666667d0, 0.8333333333333333d0, 0.3333333333333333d0, & + 0.3333333333333333d0, -1.1666666666666667d0, 1.8333333333333333d0 ] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/plot.py b/example/burgers/inviscid-1d/eno3/fortran/01/plot.py new file mode 100644 index 00000000..6bf2c013 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno3") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/julia/01/eno.jl b/example/burgers/inviscid-1d/eno3/julia/01/eno.jl new file mode 100644 index 00000000..76f0287e --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/julia/01/eno.jl @@ -0,0 +1,208 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 3 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1, :] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2, :] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3, :] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/julia/01/plot.py b/example/burgers/inviscid-1d/eno3/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/01/eno.py b/example/burgers/inviscid-1d/eno3/python/01/eno.py new file mode 100644 index 00000000..2e40a3e2 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/01/eno.py @@ -0,0 +1,172 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 3 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/01/plot.py b/example/burgers/inviscid-1d/eno3/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/02/eno.py b/example/burgers/inviscid-1d/eno3/python/02/eno.py new file mode 100644 index 00000000..a52aadec --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/02/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 3 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/02/plot.py b/example/burgers/inviscid-1d/eno3/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/03/eno.py b/example/burgers/inviscid-1d/eno3/python/03/eno.py new file mode 100644 index 00000000..429bb23c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/03/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 3 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/03/plot.py b/example/burgers/inviscid-1d/eno3/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/README.txt b/example/burgers/inviscid-1d/eno4/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..d535b2e4 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 @@ -0,0 +1,299 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 4 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 25.0/12.0 + coef(0, 1) = -23.0/12.0 + coef(0, 2) = 13.0/12.0 + coef(0, 3) = -1.0/4.0 + + coef(1, 0) = 1.0/4.0 + coef(1, 1) = 13.0/12.0 + coef(1, 2) = -5.0/12.0 + coef(1, 3) = 1.0/12.0 + + coef(2, 0) = -1.0/12.0 + coef(2, 1) = 7.0/12.0 + coef(2, 2) = 7.0/12.0 + coef(2, 3) = -1.0/12.0 + + coef(3, 0) = 1.0/12.0 + coef(3, 1) = -5.0/12.0 + coef(3, 2) = 13.0/12.0 + coef(3, 3) = 1.0/4.0 + + coef(4, 0) = -1.0/4.0 + coef(4, 1) = 13.0/12.0 + coef(4, 2) = -23.0/12.0 + coef(4, 3) = 25.0/12.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/plot.py b/example/burgers/inviscid-1d/eno4/fortran/01/plot.py new file mode 100644 index 00000000..775b3197 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno4") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/julia/01/eno.jl b/example/burgers/inviscid-1d/eno4/julia/01/eno.jl new file mode 100644 index 00000000..732efdbb --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/julia/01/eno.jl @@ -0,0 +1,209 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 4 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1, :] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2, :] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3, :] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4, :] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/julia/01/plot.py b/example/burgers/inviscid-1d/eno4/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/01/eno.py b/example/burgers/inviscid-1d/eno4/python/01/eno.py new file mode 100644 index 00000000..55ed295a --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/01/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 4 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/01/plot.py b/example/burgers/inviscid-1d/eno4/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/02/eno.py b/example/burgers/inviscid-1d/eno4/python/02/eno.py new file mode 100644 index 00000000..05d93bac --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/02/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 4 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/02/plot.py b/example/burgers/inviscid-1d/eno4/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/03/eno.py b/example/burgers/inviscid-1d/eno4/python/03/eno.py new file mode 100644 index 00000000..9b7565c7 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/03/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 4 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/03/plot.py b/example/burgers/inviscid-1d/eno4/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/README.txt b/example/burgers/inviscid-1d/eno5/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..54c0a730 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 @@ -0,0 +1,310 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 5 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 137.0/60.0 + coef(0, 1) = -163.0/60.0 + coef(0, 2) = 137.0/60.0 + coef(0, 3) = -21.0/20.0 + coef(0, 4) = 1.0/5.0 + + coef(1, 0) = 1.0/5.0 + coef(1, 1) = 77.0/60.0 + coef(1, 2) = -43.0/60.0 + coef(1, 3) = 17.0/60.0 + coef(1, 4) = -1.0/20.0 + + coef(2, 0) = -1.0/20.0 + coef(2, 1) = 9.0/20.0 + coef(2, 2) = 47.0/60.0 + coef(2, 3) = -13.0/60.0 + coef(2, 4) = 1.0/30.0 + + coef(3, 0) = 1.0/30.0 + coef(3, 1) = -13.0/60.0 + coef(3, 2) = 47.0/60.0 + coef(3, 3) = 9.0/20.0 + coef(3, 4) = -1.0/20.0 + + coef(4, 0) = -1.0/20.0 + coef(4, 1) = 17.0/60.0 + coef(4, 2) = -43.0/60.0 + coef(4, 3) = 77.0/60.0 + coef(4, 4) = 1.0/5.0 + + coef(5, 0) = 1.0/5.0 + coef(5, 1) = -21.0/20.0 + coef(5, 2) = 137.0/60.0 + coef(5, 3) = -163.0/60.0 + coef(5, 4) = 137.0/60.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/plot.py b/example/burgers/inviscid-1d/eno5/fortran/01/plot.py new file mode 100644 index 00000000..87eef54f --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno5") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/julia/01/eno.jl b/example/burgers/inviscid-1d/eno5/julia/01/eno.jl new file mode 100644 index 00000000..74516595 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/julia/01/eno.jl @@ -0,0 +1,210 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 5 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1, :] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2, :] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3, :] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4, :] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5, :] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/julia/01/plot.py b/example/burgers/inviscid-1d/eno5/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/01/eno.py b/example/burgers/inviscid-1d/eno5/python/01/eno.py new file mode 100644 index 00000000..863aaea0 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/01/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 5 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/01/plot.py b/example/burgers/inviscid-1d/eno5/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/02/eno.py b/example/burgers/inviscid-1d/eno5/python/02/eno.py new file mode 100644 index 00000000..badae66e --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/02/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 5 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/02/plot.py b/example/burgers/inviscid-1d/eno5/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/03/eno.py b/example/burgers/inviscid-1d/eno5/python/03/eno.py new file mode 100644 index 00000000..ee7fc9f1 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/03/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 5 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/03/plot.py b/example/burgers/inviscid-1d/eno5/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/README.txt b/example/burgers/inviscid-1d/eno6/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..d262981b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 @@ -0,0 +1,323 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 6 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 49.0/20.0 + coef(0, 1) = -71.0/20.0 + coef(0, 2) = 79.0/20.0 + coef(0, 3) = -163.0/60.0 + coef(0, 4) = 31.0/30.0 + coef(0, 5) = -1.0/6.0 + + coef(1, 0) = 1.0/6.0 + coef(1, 1) = 29.0/20.0 + coef(1, 2) = -21.0/20.0 + coef(1, 3) = 37.0/60.0 + coef(1, 4) = -13.0/60.0 + coef(1, 5) = 1.0/30.0 + + coef(2, 0) = -1.0/30.0 + coef(2, 1) = 11.0/30.0 + coef(2, 2) = 19.0/20.0 + coef(2, 3) = -23.0/60.0 + coef(2, 4) = 7.0/60.0 + coef(2, 5) = -1.0/60.0 + + coef(3, 0) = 1.0/60.0 + coef(3, 1) = -2.0/15.0 + coef(3, 2) = 37.0/60.0 + coef(3, 3) = 37.0/60.0 + coef(3, 4) = -2.0/15.0 + coef(3, 5) = 1.0/60.0 + + coef(4, 0) = -1.0/60.0 + coef(4, 1) = 7.0/60.0 + coef(4, 2) = -23.0/60.0 + coef(4, 3) = 19.0/20.0 + coef(4, 4) = 11.0/30.0 + coef(4, 5) = -1.0/30.0 + + coef(5, 0) = 1.0/30.0 + coef(5, 1) = -13.0/60.0 + coef(5, 2) = 37.0/60.0 + coef(5, 3) = -21.0/20.0 + coef(5, 4) = 29.0/20.0 + coef(5, 5) = 1.0/6.0 + + coef(6, 0) = -1.0/6.0 + coef(6, 1) = 31.0/30.0 + coef(6, 2) = -163.0/60.0 + coef(6, 3) = 79.0/20.0 + coef(6, 4) = -71.0/20.0 + coef(6, 5) = 49.0/20.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/plot.py b/example/burgers/inviscid-1d/eno6/fortran/01/plot.py new file mode 100644 index 00000000..ca0edf79 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno6") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/julia/01/eno.jl b/example/burgers/inviscid-1d/eno6/julia/01/eno.jl new file mode 100644 index 00000000..922a07d8 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/julia/01/eno.jl @@ -0,0 +1,211 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 6 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1, :] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2, :] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3, :] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4, :] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5, :] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6, :] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/julia/01/plot.py b/example/burgers/inviscid-1d/eno6/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/01/eno.py b/example/burgers/inviscid-1d/eno6/python/01/eno.py new file mode 100644 index 00000000..19e34aeb --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/01/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 6 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/01/plot.py b/example/burgers/inviscid-1d/eno6/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/02/eno.py b/example/burgers/inviscid-1d/eno6/python/02/eno.py new file mode 100644 index 00000000..f9908e96 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/02/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 6 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/02/plot.py b/example/burgers/inviscid-1d/eno6/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/03/eno.py b/example/burgers/inviscid-1d/eno6/python/03/eno.py new file mode 100644 index 00000000..0a3b3446 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/03/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 6 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/03/plot.py b/example/burgers/inviscid-1d/eno6/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/README.txt b/example/burgers/inviscid-1d/eno7/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..5dab972d --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 @@ -0,0 +1,338 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 7 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 363.0/140.0 + coef(0, 1) = -617.0/140.0 + coef(0, 2) = 853.0/140.0 + coef(0, 3) = -2341.0/420.0 + coef(0, 4) = 667.0/210.0 + coef(0, 5) = -43.0/42.0 + coef(0, 6) = 1.0/7.0 + + coef(1, 0) = 1.0/7.0 + coef(1, 1) = 223.0/140.0 + coef(1, 2) = -197.0/140.0 + coef(1, 3) = 153.0/140.0 + coef(1, 4) = -241.0/420.0 + coef(1, 5) = 37.0/210.0 + coef(1, 6) = -1.0/42.0 + + coef(2, 0) = -1.0/42.0 + coef(2, 1) = 13.0/42.0 + coef(2, 2) = 153.0/140.0 + coef(2, 3) = -241.0/420.0 + coef(2, 4) = 109.0/420.0 + coef(2, 5) = -31.0/420.0 + coef(2, 6) = 1.0/105.0 + + coef(3, 0) = 1.0/105.0 + coef(3, 1) = -19.0/210.0 + coef(3, 2) = 107.0/210.0 + coef(3, 3) = 319.0/420.0 + coef(3, 4) = -101.0/420.0 + coef(3, 5) = 5.0/84.0 + coef(3, 6) = -1.0/140.0 + + coef(4, 0) = -1.0/140.0 + coef(4, 1) = 5.0/84.0 + coef(4, 2) = -101.0/420.0 + coef(4, 3) = 319.0/420.0 + coef(4, 4) = 107.0/210.0 + coef(4, 5) = -19.0/210.0 + coef(4, 6) = 1.0/105.0 + + coef(5, 0) = 1.0/105.0 + coef(5, 1) = -31.0/420.0 + coef(5, 2) = 109.0/420.0 + coef(5, 3) = -241.0/420.0 + coef(5, 4) = 153.0/140.0 + coef(5, 5) = 13.0/42.0 + coef(5, 6) = -1.0/42.0 + + coef(6, 0) = -1.0/42.0 + coef(6, 1) = 37.0/210.0 + coef(6, 2) = -241.0/420.0 + coef(6, 3) = 153.0/140.0 + coef(6, 4) = -197.0/140.0 + coef(6, 5) = 223.0/140.0 + coef(6, 6) = 1.0/7.0 + + coef(7, 0) = 1.0/7.0 + coef(7, 1) = -43.0/42.0 + coef(7, 2) = 667.0/210.0 + coef(7, 3) = -2341.0/420.0 + coef(7, 4) = 853.0/140.0 + coef(7, 5) = -617.0/140.0 + coef(7, 6) = 363.0/140.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/plot.py b/example/burgers/inviscid-1d/eno7/fortran/01/plot.py new file mode 100644 index 00000000..87c8ba86 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno7") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/julia/01/eno.jl b/example/burgers/inviscid-1d/eno7/julia/01/eno.jl new file mode 100644 index 00000000..c91d3fec --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/julia/01/eno.jl @@ -0,0 +1,212 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 7 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1, :] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2, :] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3, :] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4, :] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5, :] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6, :] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7, :] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/julia/01/plot.py b/example/burgers/inviscid-1d/eno7/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/01/eno.py b/example/burgers/inviscid-1d/eno7/python/01/eno.py new file mode 100644 index 00000000..4ad651fc --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/01/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 7 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/01/plot.py b/example/burgers/inviscid-1d/eno7/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/02/eno.py b/example/burgers/inviscid-1d/eno7/python/02/eno.py new file mode 100644 index 00000000..054efb88 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/02/eno.py @@ -0,0 +1,177 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 7 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/02/plot.py b/example/burgers/inviscid-1d/eno7/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/03/eno.py b/example/burgers/inviscid-1d/eno7/python/03/eno.py new file mode 100644 index 00000000..8eb0ef4e --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/03/eno.py @@ -0,0 +1,177 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 7 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/03/plot.py b/example/burgers/inviscid-1d/eno7/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/theory/python/01/testprj.py b/example/burgers/theory/python/01/testprj.py new file mode 100644 index 00000000..035a5d81 --- /dev/null +++ b/example/burgers/theory/python/01/testprj.py @@ -0,0 +1,20 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 参数设置 +nu = 0.1 # 粘性系数 +x = np.linspace(-1, 1, 400) # x 范围从 -1 到 1 +t = 0.1 # 时间 t + +# 计算解析解 +u = 2 * np.pi * nu * np.tan(np.pi * x) + +# 绘图 +plt.figure(figsize=(10, 6)) +plt.plot(x, u, label=f't = {t}', linewidth=2) +plt.title('解析解 u(x, t) = 2 * pi * nu * tan(pi * x)', fontsize=14) +plt.xlabel('x', fontsize=12) +plt.ylabel('u(x, t)', fontsize=12) +plt.legend(fontsize=12) +plt.grid(True) +plt.show() \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/CMakeLists.txt b/example/eno/enoburgers/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/README.txt b/example/eno/enoburgers/fortran/01/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/enoburgers.f90 b/example/eno/enoburgers/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..0cd18f3d --- /dev/null +++ b/example/eno/enoburgers/fortran/01/enoburgers.f90 @@ -0,0 +1,291 @@ +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(0:iorder-1,0:iorder-1) +! real(8) :: res(1:nx) +! real(8) :: dx +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, m +! integer :: k1, k2, l1, l2 +! integer :: nx, iorder, ighost +! +!! Choose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j) = u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j) = dd(i-1,j+1) - dd(i-1,j) +! enddo +! enddo +! +! do j = 0, nx +! il(j) = j +! do i = 1, iorder - 1 +! if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j) = il(j) - 1 +! endif +! enddo +! enddo +! +! do j = 0, nx +! ir(j) = j + 1 +! do i = 1, iorder - 1 +! if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j) = ir(j) - 1 +! endif +! enddo +! enddo +! +!! Reconstruction u(j+1/2) +! do j = 0, nx +! k1 = il(j) +! k2 = ir(j) +! l1 = j - k1 +! l2 = j - k2 +! up1_2m(j) = 0 +! up1_2p(j) = 0 +! do m = 0, iorder - 1 +! up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) +! up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) +! enddo +! enddo +! +! do i = 1, nx +! res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx +! enddo +! +! end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & + ,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + !real(8) :: coef(0:iorder-1, 0:iorder-1) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + !dx = 1.0 / nx + !dt = dx * 0.5 + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + !coef = reshape([1.5,-0.5,0.5,0.5,-0.5,1.5], [iorder+1, iorder], order = [1, 2]) + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt b/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/README.txt b/example/eno/enoburgers/fortran/01_debug/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 b/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 new file mode 100644 index 00000000..57c2b5f1 --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 @@ -0,0 +1,289 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: res(1:nx) + real(8) :: dx + integer :: il(0:nx), ir(0:nx) + integer :: i, j, m + integer :: k1, k2, l1, l2 + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + do i = 1, iorder - 1 + if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j) = il(j) - 1 + endif + enddo + enddo + + do j = 0, nx + ir(j) = j + 1 + do i = 1, iorder - 1 + if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j) = ir(j) - 1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k1 = il(j) + k2 = ir(j) + l1 = j - k1 + l2 = j - k2 + up1_2m(j) = 0 + up1_2p(j) = 0 + do m = 0, iorder - 1 + up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) + up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) + enddo + enddo + + do i = 1, nx + res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx + enddo + + end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & +! ,iorder,ighost) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(-1:iorder-1,0:iorder-1) +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, k1, k2, l1, l2, m, nx +! integer :: iorder, ighost +! +! ! chose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j)=u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j)=dd(i-1,j+1)-dd(i-1,j) +! enddo +! enddo +! do j=0,nx +! il(j)=j +! ir(j)=j+1 +! do i=1,iorder-1 +! if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j)=il(j)-1 +! endif +! if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j)=ir(j)-1 +! endif +! enddo +! enddo +! ! reconstruction u(j+1_2) +! do j=0,nx +! k1=il(j) +! k2=ir(j) +! l1=j-k1 +! l2=j-k2 +! up1_2m(j)=0 +! up1_2p(j)=0 +! do m=0,iorder-1 +! up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) +! up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) +! enddo +! enddo +!end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + !dx = 1.0 / nx + !dt = dx * 0.5 + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/CMakeLists.txt b/example/eno/enoburgers/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/README.txt b/example/eno/enoburgers/fortran/01a/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/enoburgers.f90 b/example/eno/enoburgers/fortran/01a/enoburgers.f90 new file mode 100644 index 00000000..608f5c2b --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/enoburgers.f90 @@ -0,0 +1,336 @@ +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(0:iorder-1,0:iorder-1) +! real(8) :: res(1:nx) +! real(8) :: dx +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, m +! integer :: k1, k2, l1, l2 +! integer :: nx, iorder, ighost +! +!! Choose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j) = u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j) = dd(i-1,j+1) - dd(i-1,j) +! enddo +! enddo +! +! do j = 0, nx +! il(j) = j +! do i = 1, iorder - 1 +! if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j) = il(j) - 1 +! endif +! enddo +! enddo +! +! do j = 0, nx +! ir(j) = j + 1 +! do i = 1, iorder - 1 +! if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j) = ir(j) - 1 +! endif +! enddo +! enddo +! +!! Reconstruction u(j+1/2) +! do j = 0, nx +! k1 = il(j) +! k2 = ir(j) +! l1 = j - k1 +! l2 = j - k2 +! up1_2m(j) = 0 +! up1_2p(j) = 0 +! do m = 0, iorder - 1 +! up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) +! up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) +! enddo +! enddo +! +! do i = 1, nx +! res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx +! enddo +! +! end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & +! ,iorder,ighost) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(-1:iorder-1,0:iorder-1) +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, k1, k2, l1, l2, m, nx +! integer :: iorder, ighost +! +! ! chose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j)=u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j)=dd(i-1,j+1)-dd(i-1,j) +! enddo +! enddo +! do j=0,nx +! il(j)=j +! ir(j)=j+1 +! do i=1,iorder-1 +! if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j)=il(j)-1 +! endif +! if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j)=ir(j)-1 +! endif +! enddo +! enddo +! ! reconstruction u(j+1_2) +! do j=0,nx +! k1=il(j) +! k2=ir(j) +! l1=j-k1 +! l2=j-k2 +! up1_2m(j)=0 +! up1_2p(j)=0 +! do m=0,iorder-1 +! up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) +! up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) +! enddo +! enddo +!end subroutine reconstruction + + +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + real(8) :: res(1:nx) + real(8) :: dx + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/CMakeLists.txt b/example/eno/enoburgers/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/README.txt b/example/eno/enoburgers/fortran/01b/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/enoburgers.f90 b/example/eno/enoburgers/fortran/01b/enoburgers.f90 new file mode 100644 index 00000000..bb727327 --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/enoburgers.f90 @@ -0,0 +1,230 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + real(8) :: res(1:nx) + real(8) :: dx + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo + + + do i = 1, nx + res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine rhs(up1_2m,up1_2p,nx,dx,res) + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx + integer :: nx, i + + call getflux(up1_2m,up1_2p,flux,nx) + + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo +end subroutine rhs + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + !u1(i) = pu(i) + dt * ress + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + !u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + !su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + open(1,file='temp21.plt',status='unknown') + do i=-ighost,nx+ighost + write(1,101) x(i),pu(i) + enddo + close(1) + open(2,file='solution.plt',status='unknown') + do i=1,nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end program main \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/CMakeLists.txt b/example/eno/enoburgers/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/README.txt b/example/eno/enoburgers/fortran/01c/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/enoburgers.f90 b/example/eno/enoburgers/fortran/01c/enoburgers.f90 new file mode 100644 index 00000000..4d842aa3 --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/enoburgers.f90 @@ -0,0 +1,218 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + + !chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + + !reconstruction u(j+1_2) + do j = 0, nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo + +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine rhs(up1_2m,up1_2p,nx,dx,res) + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx + integer :: nx, i + + call getflux(up1_2m,up1_2p,flux,nx) + + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo +end subroutine rhs + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + do i = 1, nx + !ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + t1 = 1.0/3 + t2 = 2.0/3 + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + open(1,file='temp.plt',status='unknown') + do i=-ighost,nx+ighost + write(1,101) x(i),pu(i) + enddo + close(1) + open(2,file='solution.plt',status='unknown') + do i=1,nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/CMakeLists.txt b/example/eno/enolinear/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/README.txt b/example/eno/enolinear/fortran/01/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/enolinear.f90 b/example/eno/enolinear/fortran/01/enolinear.f90 new file mode 100644 index 00000000..9e81111e --- /dev/null +++ b/example/eno/enolinear/fortran/01/enolinear.f90 @@ -0,0 +1,184 @@ + subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit double precision (a-h,o-z) + double precision u(-ighost:nx+ighost),up1_2(0:nx) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j)=j + do i=1,iorder-1 + if(abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j)))) then + ir(j)=ir(j)-1 + endif + enddo + enddo +! Reconstruction u(j+1/2) + do j=0,nx + k=ir(j) + l=j-k + up1_2(j)=0 + do m=0,iorder-1 + up1_2(j)=up1_2(j)+u(k+m)*coef(l,m) + enddo + enddo + end + +! Main program + program main + implicit double precision (a-h,o-z) + parameter (nx=40,pi=3.14159265358979323846,ighost=10,iorder=2) + double precision pu(-ighost:nx+ighost),su(-ighost:nx+ighost) + double precision u1(-ighost:nx+ighost),u2(-ighost:nx+ighost) + double precision u0(1:nx),up1_2(0:nx),x(-ighost:nx+ighost) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + tt=5.0/3.0 + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! 3rd-order coefficients +! data ((coef(i,j),j=0,2),i=0,2) & +! & /0.3333333333333333D0, 0.8333333333333333D0, +! & -0.1666666666666667D0,-0.1666666666666667D0, +! & 0.8333333333333333D0, 0.3333333333333333D0, +! & 0.3333333333333333D0,-1.1666666666666667D0, +! & 1.8333333333333333D0/ +! 4th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /0.25, 1.083333,-0.416667, 0.083333, +! & -0.083333, 0.583333, 0.583333,-0.083333, +! & 0.083333,-0.416667, 1.083333, 0.25, +! & -0.25, 1.083333,-1.916667, 2.083333/ +! 5th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /2.0D-1, 1.283333333333333D0,-7.166666666666667D-1, +! & 2.833333333333333333D-1,-5.0D-2, +! & -5.0D-2, 4.5D-1, 7.8333333333333333D-1, +! & -2.166666666666667D-1, 3.3333333333333333D-2, +! & 3.333333333333333333D-2,-2.166666666666667D-1, +! & 7.83333333333333333D-1,0.45D0,-5.0D-2, +! & -5.0D-2, 2.8333333333333333D-1,-7.166666666666667D-1, +! & 1.283333333333333333D0, 2.0D-1, +! & 2.0D-1,-1.05D0,2.2833333333333333333D0, +! & -2.716666666666667D0, 2.283333333333333333D0/ +! 6th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /0.166667, 1.45, -1.05, 0.616667,-0.216667, 0.033333, +! & -0.033333, 0.366667, 0.95, -0.383333, 0.116667,-0.016667, +! & 0.016667,-0.133333, 0.616667, 0.616667,-0.133333, 0.016667, +! & -0.016667, 0.116667,-0.383333, 0.95, 0.366667,-0.033333, +! & 0.033333,-0.216667, 0.616667,-1.05, 1.45, 0.166667, +! & -0.166667, 1.033333,-2.716667, 3.95, -3.55, 2.45 / +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo +! Initial mean value 1 +! Initial mean value 2 + do i=1,nx +! pu(i)=0.5*((x(i)+dx/2)*(x(i)+dx/2)-(x(i)-dx/2)*(x(i)-dx/2))/dx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + & /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + end \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/CMakeLists.txt b/example/eno/enolinear/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/README.txt b/example/eno/enolinear/fortran/01a/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01a/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/enolinear.f90 b/example/eno/enolinear/fortran/01a/enolinear.f90 new file mode 100644 index 00000000..55ea1b8e --- /dev/null +++ b/example/eno/enolinear/fortran/01a/enolinear.f90 @@ -0,0 +1,163 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit double precision (a-h,o-z) + double precision u(-ighost:nx+ighost),up1_2(0:nx) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j)=j + do i=1,iorder-1 + if(abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j)))) then + ir(j)=ir(j)-1 + endif + enddo + enddo +! Reconstruction u(j+1/2) + do j=0,nx + k=ir(j) + l=j-k + up1_2(j)=0 + do m=0,iorder-1 + up1_2(j)=up1_2(j)+u(k+m)*coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit double precision (a-h,o-z) + parameter (nx=40,pi=3.14159265358979323846,ighost=10,iorder=2) + double precision pu(-ighost:nx+ighost),su(-ighost:nx+ighost) + double precision u1(-ighost:nx+ighost),u2(-ighost:nx+ighost) + double precision u0(1:nx),up1_2(0:nx),x(-ighost:nx+ighost) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + tt=5.0/3.0 + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 +! Initial mean value 2 + do i=1,nx +! pu(i)=0.5*((x(i)+dx/2)*(x(i)+dx/2)-(x(i)-dx/2)*(x(i)-dx/2))/dx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + & /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/CMakeLists.txt b/example/eno/enolinear/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/README.txt b/example/eno/enolinear/fortran/01b/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01b/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/enolinear.f90 b/example/eno/enolinear/fortran/01b/enolinear.f90 new file mode 100644 index 00000000..2e968f66 --- /dev/null +++ b/example/eno/enolinear/fortran/01b/enolinear.f90 @@ -0,0 +1,170 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i=1,nx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/CMakeLists.txt b/example/eno/enolinear/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/README.txt b/example/eno/enolinear/fortran/01c/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01c/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/enolinear.f90 b/example/eno/enolinear/fortran/01c/enolinear.f90 new file mode 100644 index 00000000..ea5591e3 --- /dev/null +++ b/example/eno/enolinear/fortran/01c/enolinear.f90 @@ -0,0 +1,169 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(1,file='\temp2.plt',status='unknown') + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i=1,nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + do i = 0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i= nx + 1, nx + ighost + pu(i)=pu(i-nx) + enddo + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx + !if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error + abs( u0(i) - pu(i) ) + it=it+1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/CMakeLists.txt b/example/eno/enolinear/fortran/01d/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01d/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/README.txt b/example/eno/enolinear/fortran/01d/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01d/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/enolinear.f90 b/example/eno/enolinear/fortran/01d/enolinear.f90 new file mode 100644 index 00000000..d78adcf3 --- /dev/null +++ b/example/eno/enolinear/fortran/01d/enolinear.f90 @@ -0,0 +1,194 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(1,file='\temp2.plt',status='unknown') + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + + count = 0 ! ʼ + + do i = - ighost, nx + ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if ( count == 5 ) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + !do i = 0, - ighost, - 1 + ! pu(i)=pu(i+nx) + !enddo + ! + !do i= nx + 1, nx + ighost + ! pu(i)=pu(i-nx) + !enddo + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t .lt. supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + + call boundary( u1, nx, ighost ) + !do i=0,-ighost,-1 + ! u1(i)=u1(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! u1(i)=u1(i-nx) + !enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + + call boundary( u2, nx, ighost ) + !do i=0,-ighost,-1 + ! u2(i)=u2(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! u2(i)=u2(i-nx) + !enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + + call boundary( su, nx, ighost ) + !do i=0,-ighost,-1 + ! su(i)=su(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! su(i)=su(i-nx) + !enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx + !if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error + abs( u0(i) - pu(i) ) + it=it+1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/CMakeLists.txt b/example/eno/enolinear/fortran/01e/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01e/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/README.txt b/example/eno/enolinear/fortran/01e/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01e/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/enolinear.f90 b/example/eno/enolinear/fortran/01e/enolinear.f90 new file mode 100644 index 00000000..b2e730f7 --- /dev/null +++ b/example/eno/enolinear/fortran/01e/enolinear.f90 @@ -0,0 +1,159 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + !u1(i)=pu(i)-dt*temp/dx + u1(i) = pu(i) - dt * temp/dx + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + temp=up1_2(i)-up1_2(i-1) + !u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) - 1.0/4.0 * dt * temp/dx + + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + temp = up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + !su(i) = t1 * pu(i) + t2 * ( u2(i) - dt * temp / dx ) + su(i) = t1 * pu(i) + t2 * u2(i) - t2 * dt * temp / dx + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/CMakeLists.txt b/example/eno/enolinear/fortran/01f/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01f/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/README.txt b/example/eno/enolinear/fortran/01f/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01f/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/enolinear.f90 b/example/eno/enolinear/fortran/01f/enolinear.f90 new file mode 100644 index 00000000..eb04a10a --- /dev/null +++ b/example/eno/enolinear/fortran/01f/enolinear.f90 @@ -0,0 +1,158 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m = 0, iorder - 1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + real(8) :: ress + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + + do i = 1, nx + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/CMakeLists.txt b/example/eno/enolinear/fortran/01g/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01g/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/README.txt b/example/eno/enolinear/fortran/01g/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01g/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/enolinear.f90 b/example/eno/enolinear/fortran/01g/enolinear.f90 new file mode 100644 index 00000000..92f790da --- /dev/null +++ b/example/eno/enolinear/fortran/01g/enolinear.f90 @@ -0,0 +1,161 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + real(8) :: res(1:nx) + real(8) :: dx + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m = 0, iorder - 1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + + do i = 1, nx + res(i) = - ( up1_2(i) - up1_2(i-1) ) / dx + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + dx = 1.0 / nx + dt = dx * 0.5 + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + + do i = 1, nx + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + do i = 1, nx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/figure/1d/03/testprj.py b/example/figure/1d/03/testprj.py new file mode 100644 index 00000000..ac9d8e95 --- /dev/null +++ b/example/figure/1d/03/testprj.py @@ -0,0 +1,32 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义当前计算点i和扩展范围r、s +i = 0 # 当前计算点 +r = 3 # 左侧扩展范围 +s = 3 # 右侧扩展范围 + +# 生成网格点索引 +x_indices = np.arange(i - r, i + s + 1) + +# 生成对应的值(这里用随机值表示,实际应用中可以替换为具体值) +u_values = np.random.rand(len(x_indices)) + +# 绘制网格点和对应的值 +plt.figure(figsize=(10, 2)) +plt.plot(x_indices, u_values, 'o-', label='Grid Points and Values') +plt.xlabel('Grid Index') +plt.ylabel('Values') +plt.title('Grid Points and Corresponding Values') +plt.grid(True) +plt.legend() + +# 标注每个网格点 +for idx, value in zip(x_indices, u_values): + plt.text(idx, value, f'*', fontsize=12, ha='center', va='bottom') + +# 标注当前计算点 +plt.plot(i, u_values[i - (i - r)], 'ro', label='Current Point (i)') +plt.text(i, u_values[i - (i - r)], f'({i}, {u_values[i - (i - r)]:.2f})', fontsize=12, ha='center', va='bottom') + +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03a/testprj.py b/example/figure/1d/03a/testprj.py new file mode 100644 index 00000000..142cf0e2 --- /dev/null +++ b/example/figure/1d/03a/testprj.py @@ -0,0 +1,46 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义网格点 +i = 0 # 当前计算点 +r = 2 # 左侧扩展范围 +s = 2 # 右侧扩展范围 + +# 创建图形和子图 +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4), sharey=True) + +# 左侧重建 +x_left = np.arange(i - r, i + s + 1) +ax1.plot(x_left, np.zeros_like(x_left) + 1, 'o-', color='gray', markersize=8) +ax1.plot([i, i], [0, 1], 'k--') # 绘制垂直线 +ax1.plot([i + 1, i + 1], [0, 1], 'k--') # 绘制垂直线 +ax1.text(i + 0.5, 1.05, r'$u_{i+\frac{1}{2},L}^L$', fontsize=12, ha='center') +ax1.set_title('(a) Left-side reconstruction') +ax1.set_xticks(x_left) +ax1.set_xticklabels([f'{i-2}', f'{i-1}', f'{i}', f'{i+1}', f'{i+2}']) +ax1.set_xlim([i - r - 1, i + s + 2]) +ax1.set_ylim([0, 1.5]) +ax1.grid(False) + +# 右侧重建 +x_right = np.arange(i - 1, i + 4) +print("x_right=",x_right) +ax2.plot(x_right, np.zeros_like(x_right) + 1, 'o-', color='gray', markersize=8) +ax2.plot([i, i], [0, 1], 'k--') # 绘制垂直线 +ax2.plot([i + 2, i + 2], [0, 1], 'k--') # 绘制垂直线 +ax2.text(i + 1.5, 1.05, r'$u_{i+\frac{1}{2},R}^R$', fontsize=12, ha='center') +ax2.set_title('(b) Right-side reconstruction') +ax2.set_xticks(x_right) +ax2.set_xticklabels([f'{i-1}', f'{i}', f'{i+1}', f'{i+2}', f'{i+3}']) +ax2.set_xlim([i - 2, i + 3 + 1]) +ax2.set_ylim([0, 1.5]) +ax2.grid(False) + +# 绘制边界点 +for ax in [ax1, ax2]: + ax.plot([i + s + 1, i + s + 1], [0, 1], 'ko') # 绘制边界点 + ax.plot([i + s + 2, i + s + 2], [0, 1], 'ro') # 绘制边界点 + ax.plot([i + s + 3, i + s + 3], [0, 1], 'ro') # 绘制边界点 + +plt.tight_layout() +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03b/testprj.py b/example/figure/1d/03b/testprj.py new file mode 100644 index 00000000..6b95492f --- /dev/null +++ b/example/figure/1d/03b/testprj.py @@ -0,0 +1,83 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +# 绘制 (a) Left-side reconstruction +plt.subplot(1, 2, 1) # 1行2列的第一个子图 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5, 6]) # 对应 i = -2 到 N+3 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=10) # 红点 + +# 标记特定点 (i=1 和其他点) +plt.text(-2, 0.1, '$i=-2$', fontsize=12, ha='center') +plt.text(-1, 0.1, '$i=-1$', fontsize=12, ha='center') +plt.text(0, 0.1, '$i=0$', fontsize=12, ha='center') +plt.text(1, 0.1, '$i=1$', fontsize=12, ha='center') +plt.text(2, 0.1, '$i=2$', fontsize=12, ha='center') +plt.text(3, 0.1, '$i=3$', fontsize=12, ha='center') +plt.text(4, 0.1, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, 0.1, '$i=N+2$', fontsize=12, ha='center') +plt.text(6, 0.1, '$i=N+3$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (i-2 到 i+2, 覆盖 i+1) +template_left = plt.Rectangle((0.5, -0.5), 4, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_left) +plt.text(2.5, 0.3, '$u_{i+1}^L$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(a) Left-side reconstruction', fontsize=14) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 绘制 (b) Right-side reconstruction +plt.subplot(1, 2, 2) # 1行2列的第二个子图 + +# 绘制网格点 (红点) +plt.plot(x_points, y_points, 'ro', markersize=10) # 红点 + +# 标记特定点 (i=1 和其他点) +plt.text(-2, 0.1, '$i=-2$', fontsize=12, ha='center') +plt.text(-1, 0.1, '$i=-1$', fontsize=12, ha='center') +plt.text(0, 0.1, '$i=0$', fontsize=12, ha='center') +plt.text(1, 0.1, '$i=1$', fontsize=12, ha='center') +plt.text(2, 0.1, '$i=2$', fontsize=12, ha='center') +plt.text(3, 0.1, '$i=3$', fontsize=12, ha='center') +plt.text(4, 0.1, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, 0.1, '$i=N+2$', fontsize=12, ha='center') +plt.text(6, 0.1, '$i=N+3$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (i-1 到 i+3, 覆盖 i+1) +template_right = plt.Rectangle((0.5, -0.5), 5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_right) +plt.text(2.5, 0.3, '$u_{i+1}^R$', fontsize=12, ha='center') + +# 绘制黑点 (i=1) +plt.plot(1, 0, 'ko', markersize=10) # 黑点在 i=1 + +# 设置标题和轴 +plt.title('(b) Right-side reconstruction', fontsize=14) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 调整布局 +plt.tight_layout() + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03c/testprj.py b/example/figure/1d/03c/testprj.py new file mode 100644 index 00000000..feff1396 --- /dev/null +++ b/example/figure/1d/03c/testprj.py @@ -0,0 +1,68 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形样式 +plt.rcParams['font.size'] = 12 + +# 绘制 (a) Left-side reconstruction +plt.figure(figsize=(8, 2)) # 调整图形大小以匹配图片宽度 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5, 6]) # 对应 i = -2 到 N+3 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 标记特定点 (i 值) +for i, x in enumerate(x_points): + plt.text(x, 0.1, f'$i={x}$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (从 i-1 到 i+2, 覆盖 i+1) +template_left = plt.Rectangle((-0.5, -0.5), 3.5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_left) +plt.text(1, 0.3, '$u_{i+1}^L$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(a) Left-side reconstruction', fontsize=14, pad=10) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('left_side_reconstruction.png', bbox_inches='tight', dpi=300) +plt.show() + +# 绘制 (b) Right-side reconstruction +plt.figure(figsize=(8, 2)) # 调整图形大小以匹配图片宽度 + +# 绘制网格点 (红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 标记特定点 (i 值) +for i, x in enumerate(x_points): + plt.text(x, 0.1, f'$i={x}$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (从 i-1 到 i+2, 覆盖 i+1) +template_right = plt.Rectangle((-0.5, -0.5), 3.5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_right) +plt.text(1, 0.3, '$u_{i+1}^R$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(b) Right-side reconstruction', fontsize=14, pad=10) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('right_side_reconstruction.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03d/testprj.py b/example/figure/1d/03d/testprj.py new file mode 100644 index 00000000..0dfeea5a --- /dev/null +++ b/example/figure/1d/03d/testprj.py @@ -0,0 +1,30 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(8, 1)) # 调整图形大小以匹配图片高度和宽度 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5]) # 对应 i = -2 到 5 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制黑点 (在 x=-1 和 x=3) +plt.plot([-1, 3], [0, 0], 'ko', markersize=8) # 黑点 + +# 绘制 x=0 和 x=2 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=2, color='k', linestyle='--', alpha=0.5) + +# 绘制紫色矩形模板 (从 x=-1 到 x=2) +template = plt.Rectangle((-1, -0.5), 3, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template) + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('reconstruction_template.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03e/testprj.py b/example/figure/1d/03e/testprj.py new file mode 100644 index 00000000..c7dcbcdc --- /dev/null +++ b/example/figure/1d/03e/testprj.py @@ -0,0 +1,34 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(8, 1)) # 调整图形大小以匹配图片高度和宽度 + +# 绘制网格点和连接线 (红点和实线) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5]) # 对应 i = -2 到 5 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制红点和连接线 +plt.plot(x_points, y_points, 'r-', linewidth=1) # 红色的实线连接所有点 +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点覆盖在实线上 + +# 绘制黑点 (在 x=-1 和 x=3) 及其连接线 +black_points = np.array([-1, 3]) +plt.plot(black_points, np.zeros_like(black_points), 'k-', linewidth=1) # 黑色的实线连接黑点 +plt.plot(black_points, np.zeros_like(black_points), 'ko', markersize=8) # 黑点覆盖在实线上 + +# 绘制 x=0 和 x=2 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=2, color='k', linestyle='--', alpha=0.5) + +# 绘制紫色矩形模板 (从 x=-1 到 x=2) +template = plt.Rectangle((-1, -0.5), 3, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template) + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('reconstruction_template_with_lines.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03f/testprj.py b/example/figure/1d/03f/testprj.py new file mode 100644 index 00000000..4c302dd7 --- /dev/null +++ b/example/figure/1d/03f/testprj.py @@ -0,0 +1,44 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (默认红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘的红点 (i=-5, 5) 再次覆盖,确保颜色正确 +plt.plot([-5, 5], [0, 0], 'ro', markersize=8) # 确保边缘点为红点 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_lines.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03g/testprj.py b/example/figure/1d/03g/testprj.py new file mode 100644 index 00000000..bfde2db8 --- /dev/null +++ b/example/figure/1d/03g/testprj.py @@ -0,0 +1,48 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (默认红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘的红点 (i=-5, 5) 再次覆盖,确保颜色正确 +plt.plot([-5, 5], [0, 0], 'ro', markersize=8) # 确保边缘点为红点 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_labels.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03h/testprj.py b/example/figure/1d/03h/testprj.py new file mode 100644 index 00000000..398dc9aa --- /dev/null +++ b/example/figure/1d/03h/testprj.py @@ -0,0 +1,50 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制中间的红点 (i=-3, -2, -1, 0, 1, 2, 3) +middle_points_red = x_points[2:9] # 对应 i=-3, -2, -1, 0, 1, 2, 3 +plt.plot(middle_points_red, np.zeros_like(middle_points_red), 'ro', markersize=8) # 红点 + +# 绘制边缘的黑点 (i=-5, -4, 4, 5) +edge_points_black = np.array([-5, -4, 4, 5]) +plt.plot(edge_points_black, np.zeros_like(edge_points_black), 'ko', markersize=8) # 黑点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points_line = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points_line, np.zeros_like(middle_points_line), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_edge_black.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03i/testprj.py b/example/figure/1d/03i/testprj.py new file mode 100644 index 00000000..19fd98be --- /dev/null +++ b/example/figure/1d/03i/testprj.py @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (内部红色,边缘黑色) +plt.scatter(x_points, y_points, s=100, facecolor='red', edgecolor='black', linewidth=1) # 点大小 s=100 对应 markersize=8 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_red_inside_black_edge.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03j/testprj.py b/example/figure/1d/03j/testprj.py new file mode 100644 index 00000000..e6033427 --- /dev/null +++ b/example/figure/1d/03j/testprj.py @@ -0,0 +1,49 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([x_points[:3], x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_middle_black_edge_black.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03k/testprj.py b/example/figure/1d/03k/testprj.py new file mode 100644 index 00000000..4cd0ff50 --- /dev/null +++ b/example/figure/1d/03k/testprj.py @@ -0,0 +1,53 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([x_points[:3], x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 添加右侧点 (4, 5) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(4, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位,使用 LaTeX 格式 +plt.text(5, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_edge_labels.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03l/testprj.py b/example/figure/1d/03l/testprj.py new file mode 100644 index 00000000..7fe6b351 --- /dev/null +++ b/example/figure/1d/03l/testprj.py @@ -0,0 +1,66 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义原始 11 个点的坐标 (从 i=-5 到 i=5) +original_x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(original_x_points) # 所有点在 y=0 线上 + +# 计算新的点坐标:仅左边的第 3 个点和第 4 个点 (i=-3, -2) 之间的距离变为原距离的两倍 +# 原距离为 1 (从 -3 到 -2),新距离为 2 +# 仅右边的第 3 个点和第 4 个点 (i=3, 2) 之间的距离变为原距离的两倍 +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +# 解释: +# - 左边:i=-5, -4 保持不变 (-5, -4) +# - 左边的第 3 个点 i=-3 保持在 -3 +# - 左边的第 4 个点 i=-2 移动到 -1 (距离从 -3 到 -1 为 2) +# - i=-1, 0, 1 保持不变 (-1, 0, 1) +# - 右边的第 3 个点 i=3 保持在 3 +# - 右边的第 4 个点 i=2 移动到 1 (距离从 3 到 1 为 2) +# - 右边:i=4, 5 保持不变 (4, 5) + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -1, -1, 0, 1, 1) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-1, -1, 0, 1, 1 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -1, -1, 0, 1, 1) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-4 到 i=-3,新位置 -4 到 -3) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3,新位置 4 到 3) +right_edge_points = new_x_points[8:10] # 对应新位置 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 添加右侧点 (4, 5) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(4, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位,使用 LaTeX 格式 +plt.text(5, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_adjusted_third_fourth_distance.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03m/testprj.py b/example/figure/1d/03m/testprj.py new file mode 100644 index 00000000..e4f2a2d0 --- /dev/null +++ b/example/figure/1d/03m/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点对应 new_x_points[:3] 和 new_x_points[8:] (i=-6, -5, -4, 4, 5, 6) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-6, -5, -4, 4, 5, 6 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-5 到 i=-4,新位置 -5 到 -4) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-5, -4 +# 绘制一半实线 (从 i=-5 到中间),一半虚线 (从中间到 i=-4) +x_half = np.linspace(-5, -4.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-4.5, -4, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=5 到 i=4,新位置 5 到 4) +right_edge_points = new_x_points[8:10] # 对应新位置 i=5, 4 +# 绘制一半实线 (从 i=5 到中间),一半虚线 (从中间到 i=4) +x_half_right = np.linspace(5, 4.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(4.5, 4, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-6, -5) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-6, -0.5, '-2', fontsize=12, ha='center') # 在 i=-6 下方 0.5 单位 +plt.text(-5, -0.5, '-1', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 + +# 添加右侧点 (5, 6) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=6 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_new_positions.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03n/testprj.py b/example/figure/1d/03n/testprj.py new file mode 100644 index 00000000..4fabfebc --- /dev/null +++ b/example/figure/1d/03n/testprj.py @@ -0,0 +1,60 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点对应 new_x_points[:3] 和 new_x_points[8:] (i=-6, -5, -4, 4, 5, 6) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-6, -5, -4, 4, 5, 6 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-5 到 i=-4,新位置 -5 到 -4) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-5, -4 +# 绘制一半实线 (从 i=-5 到中间),一半虚线 (从中间到 i=-4) +x_half = np.linspace(-5, -4.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-4.5, -4, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=5 到 i=4,新位置 5 到 4) +right_edge_points = new_x_points[8:10] # 对应新位置 i=5, 4 +# 绘制一半实线 (从 i=5 到中间),一半虚线 (从中间到 i=4) +x_half_right = np.linspace(5, 4.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(4.5, 4, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-6, -5) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_new_positions.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03o/testprj.py b/example/figure/1d/03o/testprj.py new file mode 100644 index 00000000..88132226 --- /dev/null +++ b/example/figure/1d/03o/testprj.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点需手动指定,排除左侧 i=-4 和右侧 i=4 +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) # 对应 i=-6, -5, -4, 4, 5, 6,但 i=-4 和 i=4 单独处理 +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 (内部黑色,边缘黑色) +special_black_points = np.array([-4, 4]) # 对应新位置 i=-4, 4 +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 去掉左侧第二点和第三点的连线 (i=-5 到 i=-4),以及右侧第二点和第三点的连线 (i=5 到 i=4) +# 原代码中的混合线已移除,不再绘制: +# - 左边 (i=-5 到 i=-4) +# - 右边 (i=5 到 i=4) + +# 添加所有点的标签,与点保持一定距离,高度一致 +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') # 在 i=-6 下方 0.5 单位 +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') # 在 i=-2 下方 0.5 单位 +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') # 在 i=-1 下方 0.5 单位 +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') # 在 i=0 下方 0.5 单位 +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') # 在 i=1 下方 0.5 单位 +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') # 在 i=2 下方 0.5 单位 +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位 +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位 +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=6 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03p/testprj.py b/example/figure/1d/03p/testprj.py new file mode 100644 index 00000000..fc2bc4b3 --- /dev/null +++ b/example/figure/1d/03p/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.linspace(-4, -2, 4) # 分割为三个等分 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.linspace(2, 4, 4) # 分割为三个等分 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03q/testprj.py b/example/figure/1d/03q/testprj.py new file mode 100644 index 00000000..28a2f6df --- /dev/null +++ b/example/figure/1d/03q/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03r/testprj.py b/example/figure/1d/03r/testprj.py new file mode 100644 index 00000000..64e179da --- /dev/null +++ b/example/figure/1d/03r/testprj.py @@ -0,0 +1,79 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +x = -2.2 +y = -0.1 +width = 4.4 +height = 0.2 + +# 创建一个矩形对象 +#rect = patches.Rectangle((x, y), width, height, linewidth=1, edgecolor='none', facecolor=rectangle_color, zorder=0) + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges_with_rectangle.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03s/testprj.py b/example/figure/1d/03s/testprj.py new file mode 100644 index 00000000..ec92c788 --- /dev/null +++ b/example/figure/1d/03s/testprj.py @@ -0,0 +1,85 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +x = -2.2 +y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges_with_rectangle.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03t/testprj.py b/example/figure/1d/03t/testprj.py new file mode 100644 index 00000000..ebb6f484 --- /dev/null +++ b/example/figure/1d/03t/testprj.py @@ -0,0 +1,90 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:9] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +#x = -2.2 +#y = -0.1 +x = -1.2 +y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Right-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +#plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03u/cfd.png b/example/figure/1d/03u/cfd.png new file mode 100644 index 0000000000000000000000000000000000000000..c985f2cb6b9acb0de4cc74af8545049db433d5a7 GIT binary patch literal 32092 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 literal 0 HcmV?d00001 diff --git a/example/figure/1d/03u/testprj.py b/example/figure/1d/03u/testprj.py new file mode 100644 index 00000000..cf28f21c --- /dev/null +++ b/example/figure/1d/03u/testprj.py @@ -0,0 +1,93 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +#new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +#x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04/testprj.py b/example/figure/1d/04/testprj.py new file mode 100644 index 00000000..dacad291 --- /dev/null +++ b/example/figure/1d/04/testprj.py @@ -0,0 +1,105 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +#x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +#plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +#plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +#plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 +plot_mixed_line(-4,-2) + +# 添加右起第三点和第四点之间的分段连线(2到4) +#x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +#x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +#plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +#plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +#plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 +plot_mixed_line(2,4) + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04a/testprj.py b/example/figure/1d/04a/testprj.py new file mode 100644 index 00000000..8f8e0711 --- /dev/null +++ b/example/figure/1d/04a/testprj.py @@ -0,0 +1,101 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 2.5)) + +y0=0 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) +plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +#middle_points = x_points[3:8] +middle_points = x_points[3:9] +plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +plot_mixed_line(-4,-2) + +# 添加右起第三点和第四点之间的分段连线(2到4) +plot_mixed_line(2,4) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +#ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') +plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, y0++0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, y0++0.3, '$x=L$', fontsize=12, ha='center') + +plt.text(0, y0+-1.5, '(a) Left-side reconstruction', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04b/testprj.py b/example/figure/1d/04b/testprj.py new file mode 100644 index 00000000..b487524a --- /dev/null +++ b/example/figure/1d/04b/testprj.py @@ -0,0 +1,115 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +def plot_cfd_line( x_points, y0 ): + # 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) + edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) + plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + + # 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 + special_black_points = np.array([-4, 4]) + plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) + #middle_points = x_points[3:8] + middle_points = x_points[3:9] + plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点的黑实线连接 + plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + + # 添加左起第三点和第四点之间的分段连线(-4到-2) + plot_mixed_line(-4,-2) + + # 添加右起第三点和第四点之间的分段连线(2到4) + plot_mixed_line(2,4) + + return + +def plot_rect(x, y, width, height, rectangle_color): + rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + + # 将矩形添加到坐标轴上 + ax = plt.gca() + ax.add_patch(rect) + return + +def plot_label(y0, xv, lr, txt_name): + # 添加标签和其他设置(保持不变) + plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') + plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') + plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') + plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') + plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') + plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') + plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') + plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') + #plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') + plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') + plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') + plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + + #plt.text(xv+0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') + lrname = r'$u_{i+\frac{1}{2}}^' + lr + r'$' + plt.text(xv-0.3, y0+0.5, lrname, fontsize=12, ha='center') + plt.text(-4, y0+0.3, '$x=0$', fontsize=12, ha='center') + plt.text(+4, y0+0.3, '$x=L$', fontsize=12, ha='center') + + plt.text(0, y0-1.5, txt_name, fontsize=12, ha='center') + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 2.5)) + +y0=0 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) + +plot_cfd_line( x_points, y0 ) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [y0-0.5, y0+0.5], 'k--') # 绘制垂直线 + + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = y0-0.1 +#x = -1.2 +#y = y0-0.1 +width = 4.4 +height = 0.2 + +lr = 'L' +txt_name = '(a) Left-side reconstruction' + +plot_rect(x,y,width,height,rectangle_color) +plot_label(y0,xv,lr,txt_name) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04c/cfd.png b/example/figure/1d/04c/cfd.png new file mode 100644 index 0000000000000000000000000000000000000000..d464467d8911b1c90a3af87f0f5ca2117edffd76 GIT binary patch literal 63137 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

|ttMtyrhRtJ+qcI?MgogB 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 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + #mystr = strn + ss + f'{abs(i)}' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + #mystr = '0' + else: + mystr = r'$'+ strn + r'$' + #mystr = strn + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + r'}{2}}' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = -1 + 2 * ishift + i2 = i1 - 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 0+ishift + i2 = i1-1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +x_ghost_l = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost, dtype=np.float64) +x_ghost_r = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01g/testprj.py b/example/figure/1d/eno/01g/testprj.py new file mode 100644 index 00000000..570d6ee2 --- /dev/null +++ b/example/figure/1d/eno/01g/testprj.py @@ -0,0 +1,313 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + #mystr = strn + ss + f'{abs(i)}' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + #mystr = '0' + else: + mystr = r'$'+ strn + r'$' + #mystr = strn + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + r'}{2}}' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = -1 + 2 * ishift + i2 = i1 - 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 0+ishift + i2 = i1-1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +x_ghost_l = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost, dtype=np.float64) +x_ghost_r = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01h/testprj.py b/example/figure/1d/eno/01h/testprj.py new file mode 100644 index 00000000..5f703ef0 --- /dev/null +++ b/example/figure/1d/eno/01h/testprj.py @@ -0,0 +1,310 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + stri = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01i/testprj.py b/example/figure/1d/eno/01i/testprj.py new file mode 100644 index 00000000..ca246420 --- /dev/null +++ b/example/figure/1d/eno/01i/testprj.py @@ -0,0 +1,307 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('N', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('N',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01i0/testprj.py b/example/figure/1d/eno/01i0/testprj.py new file mode 100644 index 00000000..52b8dc29 --- /dev/null +++ b/example/figure/1d/eno/01i0/testprj.py @@ -0,0 +1,307 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('N', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('N',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j/testprj.py b/example/figure/1d/eno/01j/testprj.py new file mode 100644 index 00000000..f96daea4 --- /dev/null +++ b/example/figure/1d/eno/01j/testprj.py @@ -0,0 +1,314 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + str1 = genstrNp('ist',i1) + str2 = genstrNp('ist',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1) + str2 = genstrNp('ied',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j0/testprj.py b/example/figure/1d/eno/01j0/testprj.py new file mode 100644 index 00000000..0193b895 --- /dev/null +++ b/example/figure/1d/eno/01j0/testprj.py @@ -0,0 +1,318 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + iii = ighost + 1 + ist = (1 + ishift) + iii + + #str1 = genstrNp(f'ist={ist}',i1) + str1 = genstrNp('ist',i1) + str2 = genstrNp('ist',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1) + str2 = genstrNp('ied',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j1/testprj.py b/example/figure/1d/eno/01j1/testprj.py new file mode 100644 index 00000000..ae1f2bb3 --- /dev/null +++ b/example/figure/1d/eno/01j1/testprj.py @@ -0,0 +1,315 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift + ast ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + str1 = genstrNp('ist',i1+ast) + str2 = genstrNp('ist',i2+ast) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1+ast) + str2 = genstrNp('ied',i2+ast) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * (igc+ast) + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii+ast) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +ast = 1 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02/testprj.py b/example/figure/1d/eno/02/testprj.py new file mode 100644 index 00000000..c818c076 --- /dev/null +++ b/example/figure/1d/eno/02/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + im1 = ii - 2 + ip = ii + 1 + ip1 = ii + 2 + + for i in range(0, nxc): + if i > 0 and i < im1: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip1 and i < nx-1: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-r-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-r+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[6], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[7], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[8], yb, r'$x_{i+s-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[9], yb, r'$x_{i+s+\frac{1}{2}}$', fontsize=12, ha='center') + + plt.text(xcc[0], ybc, r'$i-r$', fontsize=12, ha='center') + plt.text(xcc[1], ybc, r'$\cdots\cdots$', fontsize=12, ha='center') + plt.text(xcc[-2], ybc, r'$\cdots\cdots$', fontsize=12, ha='center') + plt.text(xcc[-1], ybc, r'$i+s$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02a/testprj.py b/example/figure/1d/eno/02a/testprj.py new file mode 100644 index 00000000..1a40cb5e --- /dev/null +++ b/example/figure/1d/eno/02a/testprj.py @@ -0,0 +1,150 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=2 +s=0 +plot_label(x, xcc, yref, r, s) + + +yref = -0.2 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=1 +s=1 +plot_label(x, xcc, yref, r, s) + + +yref = -0.4 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=0 +s=2 +plot_label(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02b/testprj.py b/example/figure/1d/eno/02b/testprj.py new file mode 100644 index 00000000..4f42af07 --- /dev/null +++ b/example/figure/1d/eno/02b/testprj.py @@ -0,0 +1,159 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02c/testprj.py b/example/figure/1d/eno/02c/testprj.py new file mode 100644 index 00000000..76fcc7a4 --- /dev/null +++ b/example/figure/1d/eno/02c/testprj.py @@ -0,0 +1,188 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + print("ncell=",ncell) + print("idc=",idc) + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02d/testprj.py b/example/figure/1d/eno/02d/testprj.py new file mode 100644 index 00000000..a01ded55 --- /dev/null +++ b/example/figure/1d/eno/02d/testprj.py @@ -0,0 +1,204 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02e/cfd.png b/example/figure/1d/eno/02e/cfd.png new file mode 100644 index 0000000000000000000000000000000000000000..926d6cd4435e4af3153e85a76d729d030b670ec3 GIT binary patch literal 35387 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 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +yref = 0.0 +r=rv[0] +s=sv[0] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +yref = -0.2 +r=rv[1] +s=sv[1] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=rv[2] +s=sv[2] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02f/testprj.py b/example/figure/1d/eno/02f/testprj.py new file mode 100644 index 00000000..9b958f8e --- /dev/null +++ b/example/figure/1d/eno/02f/testprj.py @@ -0,0 +1,209 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02g/cfd.png b/example/figure/1d/eno/02g/cfd.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9f01cac62f737ebd33aa22ed36efc51c9fcec7 GIT binary patch literal 47257 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 literal 0 HcmV?d00001 diff --git a/example/figure/1d/eno/02g/testprj.py b/example/figure/1d/eno/02g/testprj.py new file mode 100644 index 00000000..108286a7 --- /dev/null +++ b/example/figure/1d/eno/02g/testprj.py @@ -0,0 +1,207 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.5* dyt + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02h/cfd.png b/example/figure/1d/eno/02h/cfd.png new file mode 100644 index 0000000000000000000000000000000000000000..aaea00d6400089f4ee3ed4385b43b47043a60a6f GIT binary patch literal 37308 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 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.5* dyt + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +#k=3 +k=2 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02i/testprj.py b/example/figure/1d/eno/02i/testprj.py new file mode 100644 index 00000000..9407c2ea --- /dev/null +++ b/example/figure/1d/eno/02i/testprj.py @@ -0,0 +1,221 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.8* dyt + k=r+s+1 + namelist = [] + for m in range(k - 1, -1, -1): + j = 1 + 2 * m + str = r'$x_{i-\frac{' + f'{j}' + r'}{2}}$' + namelist.append(str) + for m in range(0, k): + j = 1 + 2 * m + str = r'$x_{i+\frac{' + f'{j}' + r'}{2}}$' + namelist.append(str) + print(f'{namelist=}') + print(f'{len(namelist)=}') + print(f'{r=},{s=}') + + for i in range(len(namelist)): + print(f'namelist[{i}]={namelist[i]}') + + nx = xcc.size + ii = nx // 2 + + print(f'{ii=},{nx=}') + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + print(f'{idc=}') + print(f'{idv=}') + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i]-1 ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 8 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +#k=3 +k=4 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/latex/01/README.txt b/example/figure/1d/eno/latex/01/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/01/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/01/plot.tex b/example/figure/1d/eno/latex/01/plot.tex new file mode 100644 index 00000000..ff9a33d9 --- /dev/null +++ b/example/figure/1d/eno/latex/01/plot.tex @@ -0,0 +1,41 @@ +\documentclass{article} +\usepackage{amsmath} +\begin{document} + +\section*{Results for different values of $k$ and $r$} + +\subsection*{$k=1$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{0} \bar{v}_{i} +\end{array} +\end{equation} + +\subsection*{$k=2$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{01} \bar{v}_{i} + c_{00} \bar{v}_{i+1}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\subsection*{$k=3$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{20} \bar{v}_{i-2} + c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 2 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{11} \bar{v}_{i-1} + c_{10} \bar{v}_{i} + c_{01} \bar{v}_{i+1}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{02} \bar{v}_{i} + c_{01} \bar{v}_{i+1} + c_{00} \bar{v}_{i+2}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\subsection*{$k=4$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{30} \bar{v}_{i-3} + c_{20} \bar{v}_{i-2} + c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 3 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{21} \bar{v}_{i-2} + c_{11} \bar{v}_{i-1} + c_{10} \bar{v}_{i} + c_{01} \bar{v}_{i+1}, \quad \text{if } r = 2 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{12} \bar{v}_{i-1} + c_{11} \bar{v}_{i} + c_{10} \bar{v}_{i+1} + c_{02} \bar{v}_{i+2}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{03} \bar{v}_{i} + c_{02} \bar{v}_{i+1} + c_{01} \bar{v}_{i+2} + c_{00} \bar{v}_{i+3}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02/README.txt b/example/figure/1d/eno/latex/02/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02/plot.tex b/example/figure/1d/eno/latex/02/plot.tex new file mode 100644 index 00000000..4566e2ca --- /dev/null +++ b/example/figure/1d/eno/latex/02/plot.tex @@ -0,0 +1,78 @@ +\documentclass{ctexart} +\usepackage{amsmath} +\begin{document} + +\section{三阶精度边界值近似推导} + +\subsection{问题描述} +已知单元格中心为 \(x_{i-1}, x_i, x_{i+1}\),对应的平均值为 \(\bar{u}_{i-1}, \bar{u}_i, \bar{u}_{i+1}\)。目标是用线性组合: +\[ +u_{i+1/2} \approx a \bar{u}_{i-1} + b \bar{u}_i + c \bar{u}_{i+1} +\] +逼近右边界 \(x_{i+1/2}\) 处的值,并证明此近似具有三阶精度。 + +\subsection{推导过程} + +\subsubsection{泰勒展开单元格平均值} +假设解 \(u(x)\) 充分光滑,以 \(x_i\) 为中心进行泰勒展开,单元格平均值的定义式为: +\[ +\bar{u}_j = \frac{1}{\Delta x} \int_{x_j - \Delta x/2}^{x_j + \Delta x/2} u(x) dx +\] +对每个单元格进行展开(保留到三次项): + +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \int_{x_{i-1} - \Delta x/2}^{x_{i-1} + \Delta x/2} \left[ u_i - u'_i \Delta x + \frac{u''_i}{2} (\Delta x)^2 - \frac{u'''_i}{6} (\Delta x)^3 + \dots \right] dx \notag \\ +&= u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4), \\ +\bar{u}_i &= \frac{1}{\Delta x} \int_{x_i - \Delta x/2}^{x_i + \Delta x/2} \left[ u_i + u'_i (x - x_i) + \frac{u''_i}{2} (x - x_i)^2 + \dots \right] dx \notag \\ +&= u_i + \frac{1}{24} u''_i (\Delta x)^2 + \mathcal{O}(\Delta x^4), \\ +\bar{u}_{i+1} &= \frac{1}{\Delta x} \int_{x_{i+1} - \Delta x/2}^{x_{i+1} + \Delta x/2} \left[ u_i + u'_i \Delta x + \frac{u''_i}{2} (\Delta x)^2 + \frac{u'''_i}{6} (\Delta x)^3 + \dots \right] dx \notag \\ +&= u_i + u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 + \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\end{align} + +\subsubsection{边界值的泰勒展开} +将 \(u_{i+1/2}\) 在 \(x_i\) 处展开: +\begin{equation} +u_{i+1/2} = u_i + \frac{1}{2} u'_i \Delta x + \frac{1}{8} u''_i (\Delta x)^2 + \frac{1}{48} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\end{equation} + +\subsubsection{匹配系数} +将线性组合 \(a \bar{u}_{i-1} + b \bar{u}_i + c \bar{u}_{i+1}\) 代入泰勒展开式,要求其与 \(u_{i+1/2}\) 的展开一致。比较各阶项的系数: + +\begin{align} +\text{常数项:} & \quad a + b + c = 1, \\ +\text{一阶项:} & \quad (-a + c) \Delta x = \frac{1}{2} \Delta x \ \Rightarrow \ -a + c = \frac{1}{2}, \\ +\text{二阶项:} & \quad \frac{13a + b + 13c}{24} (\Delta x)^2 = \frac{1}{8} (\Delta x)^2 \ \Rightarrow \ 13a + b + 13c = 3, \\ +\text{三阶项:} & \quad \frac{-5a + 5c}{24} (\Delta x)^3 = \frac{1}{48} (\Delta x)^3 \ \Rightarrow \ -5a + 5c = \frac{1}{2}. +\end{align} + +联立方程组: +\[ +\begin{cases} +a + b + c = 1, \\ +-a + c = \frac{1}{2}, \\ +13a + b + 13c = 3, \\ +-5a + 5c = \frac{1}{2}. +\end{cases} +\] +解得唯一解: +\[ +a = -\frac{1}{6}, \quad b = \frac{5}{6}, \quad c = \frac{1}{3}. +\] + +\subsubsection{误差分析} +将系数代入线性组合,计算误差: +\[ +\text{误差} = \left(-\frac{1}{6} \bar{u}_{i-1} + \frac{5}{6} \bar{u}_i + \frac{1}{3} \bar{u}_{i+1}\right) - u_{i+1/2}. +\] +展开后误差项为: +\[ +\left(\frac{-5a + 5c}{24} - \frac{1}{48}\right) u'''_i (\Delta x)^3 = \left(\frac{5}{36} - \frac{1}{48}\right) u'''_i (\Delta x)^3 = \mathcal{O}(\Delta x^3). +\] +因此,近似具有三阶精度。 + +\subsection{结论} +最终重构公式为: +\[ +u_{i+1/2} = -\frac{1}{6} \bar{u}_{i-1} + \frac{5}{6} \bar{u}_i + \frac{1}{3} \bar{u}_{i+1} + \mathcal{O}(\Delta x^3). +\] +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02a/README.txt b/example/figure/1d/eno/latex/02a/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02a/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02a/plot.tex b/example/figure/1d/eno/latex/02a/plot.tex new file mode 100644 index 00000000..5ac3f1c1 --- /dev/null +++ b/example/figure/1d/eno/latex/02a/plot.tex @@ -0,0 +1,76 @@ +\documentclass{article} +\usepackage{amsmath} +\begin{document} + +\section{Derivation of Cell Average Expansion for $\bar{u}_{i-1}$} + +\subsection{Definition of Cell Average} +The cell average for cell $i-1$ is defined as: +\[ +\bar{u}_{i-1} = \frac{1}{\Delta x} \int_{x_{i-1}-\Delta x/2}^{x_{i-1}+\Delta x/2} u(x) dx. +\] +Given $x_{i-1} = x_i - \Delta x$, the integration interval becomes: +\[ +x \in \left[ x_i - \frac{3\Delta x}{2}, x_i - \frac{\Delta x}{2} \right]. +\] + +\subsection{Taylor Expansion about $x_i$} +Expand $u(x)$ around $x_i$ up to third-order terms: +\[ +u(x) = u_i + u'_i (x - x_i) + \frac{u''_i}{2} (x - x_i)^2 + \frac{u'''_i}{6} (x - x_i)^3 + \mathcal{O}(\Delta x^4). +\] + +\subsection{Variable Substitution} +Let $y = x - x_i$, then the integration limits become: +\[ +y \in \left[ -\frac{3\Delta x}{2}, -\frac{\Delta x}{2} \right]. +\] +The cell average transforms to: +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \int_{-3\Delta x/2}^{-\Delta x/2} \left[ u_i + u'_i y + \frac{u''_i}{2} y^2 + \frac{u'''_i}{6} y^3 \right] dy \notag \\ +&\quad + \mathcal{O}(\Delta x^4). +\end{align} + +\subsection{Term-by-Term Integration} +\subsubsection{Constant Term} +\[ +\int_{-3\Delta x/2}^{-\Delta x/2} u_i dy = u_i \left[ y \right]_{-3\Delta x/2}^{-\Delta x/2} = u_i \Delta x. +\] + +\subsubsection{First-Order Term} +\[ +u'_i \int_{-3\Delta x/2}^{-\Delta x/2} y dy = u'_i \left[ \frac{y^2}{2} \right]_{-3\Delta x/2}^{-\Delta x/2} = -u'_i \Delta x^2. +\] + +\subsubsection{Second-Order Term} +\[ +\frac{u''_i}{2} \int_{-3\Delta x/2}^{-\Delta x/2} y^2 dy = \frac{u''_i}{2} \left( \frac{13}{12}\Delta x^3 \right) = \frac{13}{24} u''_i \Delta x^3. +\] + +\subsubsection{Third-Order Term} +\[ +\frac{u'''_i}{6} \int_{-3\Delta x/2}^{-\Delta x/2} y^3 dy = \frac{u'''_i}{6} \left( -\frac{5}{4}\Delta x^4 \right) = -\frac{5}{24} u'''_i \Delta x^4. +\] + +\subsection{Combine Results} +Assemble all integrated terms and divide by $\Delta x$: +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \bigg[ u_i \Delta x - u'_i \Delta x^2 + \frac{13}{24} u''_i \Delta x^3 \notag \\ +&\quad - \frac{5}{24} u'''_i \Delta x^4 \bigg] + \mathcal{O}(\Delta x^4) \\ +&= u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 \notag \\ +&\quad + \mathcal{O}(\Delta x^4). +\end{align} + +\subsection{Coefficient Verification} +Key integration results that determine coefficients: +\begin{align} +\int_{-3\Delta x/2}^{-\Delta x/2} y^2 dy &= \frac{( -\Delta x/2 )^3 - ( -3\Delta x/2 )^3}{3} = \frac{13\Delta x^3}{12}, \\ +\int_{-3\Delta x/2}^{-\Delta x/2} y^3 dy &= \frac{( -\Delta x/2 )^4 - ( -3\Delta x/2 )^4}{4} = -\frac{5\Delta x^4}{4}. +\end{align} + +\subsection{Final Result} +The complete Taylor expansion of the cell average is: +\[ +\bar{u}_{i-1} = u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\] +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02b/README.txt b/example/figure/1d/eno/latex/02b/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02b/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02b/plot.tex b/example/figure/1d/eno/latex/02b/plot.tex new file mode 100644 index 00000000..445a42c1 --- /dev/null +++ b/example/figure/1d/eno/latex/02b/plot.tex @@ -0,0 +1,56 @@ +\documentclass{ctexart} +\usepackage{amsmath} % 数学公式 +\usepackage{geometry} % 调整页面布局 +\usepackage{amsfonts} % 数学字体 + +% 设置页面边距 +\geometry{a4paper, left=2cm, right=2cm, top=2cm, bottom=2cm} + +\title{ENO插值系数 $c_{rj}$ 的推导} +\author{} +\date{} + +\begin{document} +\maketitle + +\section{推导过程} + +\subsection{模板选择与多项式构造} +ENO方法通过自适应选择模板构造插值多项式。对于模板偏移量 $r$,选取节点: +\[ +\left\{x_{i-r+q-\frac{1}{2}}\right\}_{q=0}^k +\] +构造 $k$ 阶多项式 $P_r(x)$,使其满足: +\begin{equation} +P_r\left(x_{i-r+m-\frac{1}{2}}\right) = u_{i-r+m}, \quad m = 0,1,\dots,k +\end{equation} + +\subsection{拉格朗日插值基函数} +基函数 $L_m(x)$ 定义为: +\begin{equation} +L_m(x) = \prod_{\substack{l=0 \\ l \neq m}}^{k} \frac{x - x_{i-r+l-\frac{1}{2}}}{x_{i-r+m-\frac{1}{2}} - x_{i-r+l-\frac{1}{2}}} +\end{equation} + +\subsection{界面处插值计算} +在界面 $x_{i+\frac{1}{2}}$ 处的多项式值为: +\begin{align} +P_r\left(x_{i+\frac{1}{2}}\right) &= \sum_{m=0}^{k} u_{i-r+m} L_m\left(x_{i+\frac{1}{2}}\right) \\ +&= \sum_{m=0}^{k} u_{i-r+m} \left[ \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{\prod_{\substack{q=0 \\ q \neq m,l}}^{k} \left(x_{i+\frac{1}{2}} - x_{i-r+q-\frac{1}{2}}\right)}{\prod_{\substack{l=0 \\ l \neq m}}^{k} \left(x_{i-r+m-\frac{1}{2}} - x_{i-r+l-\frac{1}{2}}\right)} \right] +\end{align} + +\subsection{系数组合与加权} +通过以下步骤得到最终系数: +\begin{enumerate} + \item 外层求和范围 $m = j+1$ 到 $k$ + \item 分子排除 $q=m$ 和 $q=l$ 的项 + \item 分母为基函数的标准分母 + \item 乘以网格间距 $\Delta x_{i-r+j}$ +\end{enumerate} + +\section{最终结果} +ENO插值系数 $c_{rj}$ 的表达式为: +\begin{equation} +c_{rj} = \sum_{m=j+1}^{k} \left( \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{\prod_{\substack{q=0 \\ q \neq m,l}}^{k} \left( x_{i+\frac{1}{2}} - x_{i - r + q - \frac{1}{2}} \right)}{\prod_{\substack{l=0 \\ l \neq m}}^{k} \left( x_{i - r + m - \frac{1}{2}} - x_{i - r + l - \frac{1}{2}} \right)} \right) \Delta x_{i - r + j}. +\end{equation} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02c/README.txt b/example/figure/1d/eno/latex/02c/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02c/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02c/plot.tex b/example/figure/1d/eno/latex/02c/plot.tex new file mode 100644 index 00000000..1cf0c374 --- /dev/null +++ b/example/figure/1d/eno/latex/02c/plot.tex @@ -0,0 +1,115 @@ +\documentclass{ctexart} +\usepackage{amsmath, amssymb, geometry} +\usepackage{enumitem} +\geometry{a4paper, margin=2cm} + +\title{ENO插值系数$c_{rj}$的推导思考过程} +\author{} +\date{} + +\begin{document} +\maketitle + +\section{初步分析} +\begin{itemize}[leftmargin=*] + \item \textbf{公式结构观察}: + \[ + c_{rj} = \sum_{m=j+1}^{k} \left( \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{ + \prod_{\substack{q=0 \\ q \neq m,l}}^{k} (x_{i+1/2} - x_{i-r+q-1/2}) + }{ + \prod_{\substack{l=0 \\ l \neq m}}^{k} (x_{i-r+m-1/2} - x_{i-r+l-1/2}) + } \right) \Delta x_{i-r+j} + \] + 包含双重求和与排除性乘积,暗示与拉格朗日插值相关。 + + \item \textbf{关键疑问标记}: + \begin{itemize} + \item 分子中的$\prod_{q\neq m,l}$是否对应双重排除的基函数? + \item 分母是否为标准拉格朗日分母$\prod_{l\neq m}(x_m - x_l)$? + \item 外层求和$m=j+1$到$k$的物理意义为何? + \end{itemize} +\end{itemize} + +\section{数学工具关联} +\subsection{拉格朗日插值再审视} +标准基函数形式: +\[ +L_m(x) = \prod_{\substack{l=0 \\ l \neq m}}^{k} \frac{x - x_l}{x_m - x_l} +\] +对比发现分子部分存在差异,需解释$q \neq m,l$的双重排除。 + +\subsection{导数近似可能性} +考虑基函数导数形式: +\[ +L'_m(x) = \sum_{l \neq m} \frac{1}{x_m-x_l} \prod_{\substack{q=0 \\ q \neq m,l}}^{k} \frac{x-x_q}{x_m-x_q} +\] +发现与原式分子结构相似,但分母处理不同。 + +\section{具体案例验证} +\subsection{k=1特殊情况} +节点集合$\{x_{i-r-1/2}, x_{i-r+1/2}\}$,计算$c_{r0}$: +\[ +c_{r0} = \frac{\prod_{\substack{q=0 \\ q \neq 1,0}}^{1} (\cdot)}{\prod_{l\neq1} (\cdot)} \Delta x_{i-r} = \frac{1}{\Delta x_{i-r}} \Delta x_{i-r} = 1 +\] +结果提示可能对应一阶迎风格式。 + +\subsection{k=2情况推演} +需计算三节点情况下的双重求和: +\[ +\begin{aligned} +c_{r0} &= \sum_{m=1}^2 \Bigg( \sum_{\substack{l=0 \\ l \neq m}}^2 \frac{ + \prod_{\substack{q=0 \\ q \neq m,l}}^2 (x_{i+1/2}-x_{i-r+q-1/2}) +}{ + \prod_{\substack{l=0 \\ l \neq m}}^2 (x_{i-r+m-1/2}-x_{i-r+l-1/2}) +} \Bigg) \Delta x_{i-r} +\end{aligned} +\] +展开后呈现二阶精度特征。 + +\section{推导路径分析} +\begin{enumerate}[label=路径\arabic*:] + \item \textbf{牛顿-柯特斯积分}:假设系数来自非均匀网格积分公式 + \[ + \int_{x_j}^{x_{j+1}} P(x)dx = \sum c_{rj} \Delta x_{i-r+j} + \] + 但分子结构不匹配典型积分公式 + + \item \textbf{通量重构理论}:考虑有限体积法中界面通量计算 + \[ + \hat{f}_{i+1/2} = \sum c_{rj} f_{i-r+j} + \] + 需验证是否对应守恒形式 + + \item \textbf{误差控制机制}:ENO的核心思想体现 + \begin{itemize} + \item 分子中的双重排除可能对应光滑性检测 + \item 外层求和$m=j+1$反映模板扩展策略 + \end{itemize} +\end{enumerate} + +\section{关键突破点} +\begin{itemize} + \item 发现分子可重组为: + \[ + \prod_{q\neq m} (x_{i+1/2}-x_q) \bigg/ (x_{i+1/2}-x_l) + \] + \item 分母可分解为: + \[ + (x_m-x_l) \prod_{\substack{l'\neq m \\ l'\neq l}} (x_m-x_{l'}) + \] + \item 结合后得到: + \[ + \frac{\prod_{q\neq m} (x_{i+1/2}-x_q)}{\prod_{l'\neq m} (x_m-x_{l'})} \sum_{l\neq m} \frac{1}{x_{i+1/2}-x_l} + \] + 最终指向分段多项式的光滑性度量 +\end{itemize} + +\section{结论性推导} +通过将ENO的模板选择过程形式化,最终验证系数公式满足: +\begin{itemize} + \item 保持$k$阶精度:泰勒展开匹配至$O(\Delta x^k)$ + \item 本质无振荡:分子结构自动抑制高频分量 + \item 网格适应性:显式包含$\Delta x_{i-r+j}$项 +\end{itemize} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02d/README.txt b/example/figure/1d/eno/latex/02d/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02d/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02d/plot.tex b/example/figure/1d/eno/latex/02d/plot.tex new file mode 100644 index 00000000..a24958b6 --- /dev/null +++ b/example/figure/1d/eno/latex/02d/plot.tex @@ -0,0 +1,38 @@ +\documentclass{ctexart} +\usepackage{amsmath} + +\begin{document} + +\section*{牛顿-柯特斯积分公式} + +牛顿-柯特斯积分公式是数值积分方法中的一种,它通过多项式逼近被积函数,然后对多项式进行积分以近似原函数的积分。这种方法是由牛顿和柯特斯共同提出的,因此得名。 + +\subsection*{专业解释} + +牛顿- 柯特斯积分公式基于多项式插值理论,其基本思想是:在积分区间 $[a, b]$ 上选取 $n+1$ 个点 $x_0, x_1, \ldots, x_n$,构造一个 $n$ 次插值多项式 $P_n(x)$ 来逼近被积函数 $f(x)$。然后对 $P_n(x)$ 进行积分,得到原函数积分的近似值。 + +牛顿- 柯特斯公式的一般形式为: +\begin{equation} +\int_{a}^{b} f(x) dx \approx \sum_{j=0}^{n} w_j f(x_j) +\end{equation} +其中,$w_j$ 是权重系数,$f(x_j)$ 是函数在节点 $x_j$ 处的值。 + +\subsection*{简单例子} + +\begin{enumerate} + \item 梯形法则:当 $n=1$ 时,牛顿-柯特斯公式退化为梯形法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{b-a}{2} [f(a) + f(b)] + \end{equation} + + \item 辛普森一三法则:当 $n=2$ 时,牛顿-柯特斯公式为辛普森一三法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{b-a}{6} [f(a) + 4f\left(\frac{a+b}{2}\right) + f(b)] + \end{equation} + \item 辛普森三八法则:当 $n=4$ 时,牛顿-柯特斯公式为辛普森三八法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{3(b-a)}{8} [f(a) + 3f\left(\frac{3a+b}{4}\right) + 3f\left(\frac{a+b}{2}\right) + f(b)] + \end{equation} +\end{enumerate} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02e/README.txt b/example/figure/1d/eno/latex/02e/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02e/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02e/plot.tex b/example/figure/1d/eno/latex/02e/plot.tex new file mode 100644 index 00000000..2b29609a --- /dev/null +++ b/example/figure/1d/eno/latex/02e/plot.tex @@ -0,0 +1,47 @@ +\documentclass{ctexart} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{hyperref} + +\begin{document} + +\section{一维标量方程的 ENO 和 weighted ENO 格式} + +\subsection{积分平均型格式或者有限体积型格式} + +将原方程在区间 $I_i$ 上积分,并整理得 +\begin{equation} +\frac{d}{dt} \int_{x_{i-\frac{1}{2}}}^{x_{i+\frac{1}{2}}} u(x,t) dx + f\left(u\left(x_{i+\frac{1}{2}}, t\right)\right) - f\left(u\left(x_{i-\frac{1}{2}}, t\right)\right) = 0. +\end{equation} +\label{eq:eno1} + +定义函数 $u(x,t)$ 的单元平均值 +\begin{equation} +\bar{u}_i(t) = \frac{1}{\Delta x_i} \int_{x_{i-\frac{1}{2}}}^{x_{i+\frac{1}{2}}} u(x,t) dx, +\end{equation} +\label{eq:eno2} + +则有 +\begin{equation} +\frac{d}{dt} \bar{u}_i + \frac{1}{\Delta x_i} \left[f\left(u\left(x_{i+\frac{1}{2}, t\right)\right) - f\left(u\left(x_{i-\frac{1}{2}, t}\right)\right)\right] = 0, +\end{equation} +\label{eq:eno3} + +这里由于只有单元平均值已知,所以需要构造函数在单元边界点(半网格节点)上的值 $u_{i-1/2}, i=0,1,\cdots,N$。此时有限体积格式可写为 +\begin{equation} +\frac{d}{dt} \bar{u}_i + \frac{1}{\Delta x_i} \left[f\left(u_{i+\frac{1}{2}}\right) - f\left(u_{i-\frac{1}{2}}\right)\right] = 0. +\end{equation} +\label{eq:eno4} + +假定周期边界条件,即假定在计算区域外的数值解是可以得到的(这也适合于具有紧致支集的问题)。对于一致网格剖分 $\Delta x_i = \Delta x$,我们可以如下构造单元节点上的函数值: + +\begin{enumerate} + \item 确定一个模板。 + \item 构造一个多项式,设为 $p(x)$,使其满足 + \begin{equation} + \frac{1}{\Delta x_j} \int_{x_{j-\frac{1}{2}}}^{x_{j+\frac{1}{2}}} p(x) dx = \bar{u}_j, \quad j = i-1, i, i+1 + \end{equation} + 在所选择的模板上成立。上述模板下多项式 $p(x)$ 是惟一确定的不超过二次 +\end{enumerate} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02etest/README.txt b/example/figure/1d/eno/latex/02etest/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02etest/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02etest/plot.tex b/example/figure/1d/eno/latex/02etest/plot.tex new file mode 100644 index 00000000..ce1dc1b1 --- /dev/null +++ b/example/figure/1d/eno/latex/02etest/plot.tex @@ -0,0 +1,12 @@ +\documentclass{ctexart} +\usepackage{amsmath} + +\begin{document} + +\begin{align} +E &= mc^2 \tag{\label{eq:Einstein}} \\ % 手动编号 +a &= b \tag{\label{eq:myeq}} \\ + &= c +\end{align} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02f/README.txt b/example/figure/1d/eno/latex/02f/README.txt new file mode 100644 index 00000000..0808f5c5 --- /dev/null +++ b/example/figure/1d/eno/latex/02f/README.txt @@ -0,0 +1,3 @@ +pdflatex plot.tex +d:\github\OneFLOW\example\figure\1d\eno\latex\02f\build\ +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02f/plot.tex b/example/figure/1d/eno/latex/02f/plot.tex new file mode 100644 index 00000000..2e8d688c --- /dev/null +++ b/example/figure/1d/eno/latex/02f/plot.tex @@ -0,0 +1,29 @@ +\documentclass{article} +\usepackage{amsmath} +\usepackage[UTF8]{ctex} % For Chinese support + +\begin{document} + +\section{8.1} + +\begin{equation} +w_t + (f(w))_x = 0, \quad x \in (a, b), \quad t > 0 +\label{eq:8.1} +\end{equation} + +\begin{equation} +w(x, 0) = w^0(x), \quad x \in [a, b] +\label{eq:8.2} +\end{equation} + +\begin{equation} +a = x_{\frac{1}{2}} < x_{\frac{3}{2}} < \cdots < x_{N-\frac{1}{2}} = b +\label{eq:8.3} +\end{equation} + +其中计算点为 \( x_i = \frac{x_{i-1/2} + x_{i+1/2}}{2} \),步长为 \( \Delta x_i \)。 +\( \Delta x = \max \Delta x_i \),表示最大网格步长。 + +加权ENO方法是一种高阶、非振荡的数值方法,适用于求解偏微分方程。 + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/README.txt b/example/figure/1d/eno/latex/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/arrow/01/testprj.py b/example/figure/arrow/01/testprj.py new file mode 100644 index 00000000..7a8f8a7e --- /dev/null +++ b/example/figure/arrow/01/testprj.py @@ -0,0 +1,29 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +# 创建一个新的图形 +fig, ax = plt.subplots() + +# 添加一条竖向线段 +line = ax.plot([0, 0], [0, 1], color='blue')[0] + +# 在线段末端添加箭头 +arrow = patches.FancyArrowPatch( + (0, 1), # 箭头起点坐标 + (0, 0), # 箭头终点坐标 + arrowstyle='->', # 箭头样式 + mutation_scale=20 # 箭头大小 +) + +# 将箭头添加到图形中 +ax.add_patch(arrow) + +# 设置坐标轴的范围 +ax.set_xlim(-0.1, 0.1) +ax.set_ylim(-0.1, 1.1) + +# 隐藏坐标轴 +ax.axis('off') + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/arrow/01a/testprj.py b/example/figure/arrow/01a/testprj.py new file mode 100644 index 00000000..84f6a5b9 --- /dev/null +++ b/example/figure/arrow/01a/testprj.py @@ -0,0 +1,32 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义函数值 +x = np.array([0, 1, 2, 3]) +y = np.array([1, 4, 9, 16]) + +# 绘制原始点 +plt.scatter(x, y, color='blue', label='Data Points') + +# 绘制0阶差商 +for i in range(len(x)): + plt.plot([x[i], x[i]], [y[i], y[i]], 'k--') # 绘制水平线 + +# 绘制1阶差商 +for i in range(len(x) - 1): + plt.plot([x[i], x[i+1]], [y[i], y[i+1]], 'r--') # 绘制斜线 + +# 绘制2阶差商 +for i in range(len(x) - 2): + plt.plot([x[i], x[i+2]], [y[i], y[i+2]], 'g--') # 绘制更长的斜线 + +# 添加图例 +plt.legend(['Data Points', '0th Order Differences', '1st Order Differences', '2nd Order Differences']) + +# 添加标题和标签 +plt.title('Difference Quotient Visualization') +plt.xlabel('x') +plt.ylabel('f(x)') + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/integral/latex/01/README.txt b/example/figure/integral/latex/01/README.txt new file mode 100644 index 00000000..bcbf055d --- /dev/null +++ b/example/figure/integral/latex/01/README.txt @@ -0,0 +1 @@ +pdflatex plot.tex \ No newline at end of file diff --git a/example/figure/integral/latex/01/plot.tex b/example/figure/integral/latex/01/plot.tex new file mode 100644 index 00000000..b7ec8fa7 --- /dev/null +++ b/example/figure/integral/latex/01/plot.tex @@ -0,0 +1,42 @@ +\documentclass{standalone} +\usepackage{tikz} +\usepackage{pgfplots} +\pgfplotsset{compat=newest} + +\begin{document} +\begin{tikzpicture} +\begin{axis}[ + axis lines = middle, + xlabel = \(z\), + ylabel = {\(f(x^{2})\)}, + ymin=-1.5, ymax=1.5, + xmin=-0.1, xmax=1.1, + width=10cm, + height=6cm, + grid=both, + grid style={line width=.1pt, draw=gray!10}, + major grid style={line width=.2pt,draw=gray!50}, + minor tick num=5, + enlargelimits={abs=0.5}, + samples=100, + domain=0:1, + legend pos=north west, +] + +% 绘制函数曲线 +\addplot [domain=0:1, samples=100, color=blue, thick] {sin(2*pi*x)}; +\addlegendentry{\(f(x) = \sin(2\pi x)\)} + +% 绘制网格点 +\foreach \x in {0, 0.1, ..., 1} { + \addplot[mark=*, mark size=3, color=red] coordinates {(\x, {sin(2*pi*\x)})}; +} + +% 绘制积分区域 +\foreach \x in {0, 0.1, ..., 0.9} { + \addplot [fill=gray!30, draw=none, domain=\x:{\x+0.1}] {sin(2*pi*x)} \closedcycle; +} + +\end{axis} +\end{tikzpicture} +\end{document} \ No newline at end of file diff --git a/example/figure/integral/python/01/testprj.py b/example/figure/integral/python/01/testprj.py new file mode 100644 index 00000000..1c0f93db --- /dev/null +++ b/example/figure/integral/python/01/testprj.py @@ -0,0 +1,33 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 定义积分区间和函数 +a = 0 +b = 1 +n = 10 # 网格点数量 +x = np.linspace(a, b, n+1) +f = lambda x: np.sin(2 * np.pi * x) # 定义函数 f(x) = sin(2πx) + +# 计算函数值 +y = f(x) + +# 绘制函数曲线 +plt.figure(figsize=(8, 4)) +plt.plot(x, y, label='f(x) = sin(2πx)', color='blue', linewidth=2) + +# 绘制网格点 +plt.scatter(x, y, color='red', zorder=5) + +# 绘制积分区域 +for i in range(n): + plt.fill_between([x[i], x[i+1]], [0, 0], [y[i], y[i+1]], color='gray', alpha=0.3) + +# 添加标题和标签 +plt.title('One-Dimensional Line Integral', fontsize=14) +plt.xlabel('x', fontsize=12) +plt.ylabel('f(x)', fontsize=12) +plt.legend(fontsize=12) +plt.grid(True) + +# 显示图表 +plt.show() \ No newline at end of file diff --git a/example/figure/latex/01/README.txt b/example/figure/latex/01/README.txt new file mode 100644 index 00000000..bcbf055d --- /dev/null +++ b/example/figure/latex/01/README.txt @@ -0,0 +1 @@ +pdflatex plot.tex \ No newline at end of file diff --git a/example/figure/latex/01/plot.tex b/example/figure/latex/01/plot.tex new file mode 100644 index 00000000..7d080f19 --- /dev/null +++ b/example/figure/latex/01/plot.tex @@ -0,0 +1,70 @@ +\documentclass{article} +\usepackage{tikz} +\usepackage{geometry} +\geometry{a4paper, margin=1cm} + +\begin{document} + +% 左侧重构 (Left-side reconstruction) +\begin{tikzpicture} + % 设置坐标和样式 + \tikzset{ + dot/.style={circle, fill=red, inner sep=2pt}, + template/.style={rectangle, fill=purple, fill opacity=0.3, draw=none}, + } + + % 绘制网格点 (红点) 并命名节点 + \foreach \x in {-2,-1,0,1,2,3,4,5,6} { + \node[dot] (p\x) at (\x,0) {}; + \node[above=2pt] at (\x,0) {\(i=\x\)}; + } + + % 绘制虚线 (x=0 和 x=L) + \draw[dashed, gray] (0,-0.5) -- (0,0.5); + \draw[dashed, gray] (6,-0.5) -- (6,0.5); + \node[below=2pt] at (0,0) {\(x=0\)}; + \node[below=2pt] at (6,0) {\(x=L\)}; + + % 绘制紫色模板 (从 i-1 到 i+2, 覆盖 i+1) + \node[template, minimum width=3.5cm, minimum height=1cm] at (1,0) {}; + \node at (1,0.3) {\(u_{i+1}^L\)}; + + % 设置标题 + \node[above=10pt] at (current bounding box.north) {(a) Left-side reconstruction}; + + % 隐藏坐标轴 + \path[use as bounding box] (-2.5,-0.7) rectangle (6.5,0.7); +\end{tikzpicture} + +% 右侧重构 (Right-side reconstruction) +\begin{tikzpicture} + % 设置坐标和样式 + \tikzset{ + dot/.style={circle, fill=red, inner sep=2pt}, + template/.style={rectangle, fill=purple, fill opacity=0.3, draw=none}, + } + + % 绘制网格点 (红点) 并命名节点 + \foreach \x in {-2,-1,0,1,2,3,4,5,6} { + \node[dot] (p\x) at (\x,0) {}; + \node[above=2pt] at (\x,0) {\(i=\x\)}; + } + + % 绘制虚线 (x=0 和 x=L) + \draw[dashed, gray] (0,-0.5) -- (0,0.5); + \draw[dashed, gray] (6,-0.5) -- (6,0.5); + \node[below=2pt] at (0,0) {\(x=0\)}; + \node[below=2pt] at (6,0) {\(x=L\)}; + + % 绘制紫色模板 (从 i-1 到 i+2, 覆盖 i+1) + \node[template, minimum width=3.5cm, minimum height=1cm] at (1,0) {}; + \node at (1,0.3) {\(u_{i+1}^R\)}; + + % 设置标题 + \node[above=10pt] at (current bounding box.north) {(b) Right-side reconstruction}; + + % 隐藏坐标轴 + \path[use as bounding box] (-2.5,-0.7) rectangle (6.5,0.7); +\end{tikzpicture} + +\end{document} \ No newline at end of file diff --git a/example/grid/1d/01/Mesh/CMakeLists.txt b/example/grid/1d/01/Mesh/CMakeLists.txt new file mode 100644 index 00000000..dc0c69f3 --- /dev/null +++ b/example/grid/1d/01/Mesh/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.31) + +project(Mesh VERSION 1.0) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(Qt6 REQUIRED COMPONENTS Widgets) + +list ( APPEND PRJ_LIBRARIES Qt6::Widgets ) +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +set( PROJECT_SOURCES + main.cpp + grid.h grid.cpp + mainwindow.h mainwindow.cpp mainwindow.ui + meshdialog.h meshdialog.cpp meshdialog.ui +) + +set( PRJ_SOURCES ) +foreach(source ${PROJECT_SOURCES}) + #list( APPEND PRJ_SOURCES "codes/${source}" ) + list( APPEND PRJ_SOURCES "${source}" ) +endforeach() + +foreach(source ${PRJ_SOURCES}) + #message( STATUS "source=${source}" ) +endforeach() + +add_executable( ${PROJECT_NAME} + #images/res.qrc +) + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PRJ_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/grid/1d/01/Mesh/CMakeLists.txt.user b/example/grid/1d/01/Mesh/CMakeLists.txt.user new file mode 100644 index 00000000..ed7af13d --- /dev/null +++ b/example/grid/1d/01/Mesh/CMakeLists.txt.user @@ -0,0 +1,462 @@ + + + + + + EnvironmentId + {762d27bf-d7ff-4b95-a1d2-6c0057e05a84} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + true + false + 2 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop Qt 6.8.1 MSVC2022 64bit + Desktop Qt 6.8.1 MSVC2022 64bit + qt.qt6.681.win64_msvc2022_64_kit + 0 + 0 + 0 + + Debug + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + 0 + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + Release + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Release + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-RelWithDebInfo + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release with Debug Information + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + 0 + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Profile + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Profile + CMakeProjectManager.CMakeBuildConfiguration + + + MinSizeRel + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-MinSizeRel + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Minimum Size Release + CMakeProjectManager.CMakeBuildConfiguration + + 5 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + + + + + + + + false + + true + ApplicationManagerPlugin.Deploy.CMakePackageStep + + + install-package --acknowledge + true + Install Application Manager package + ApplicationManagerPlugin.Deploy.InstallPackageStep + + + + + + + + 2 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ApplicationManagerPlugin.Deploy.Configuration + + 2 + + true + true + 0 + true + + 2 + + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 + Mesh + CMakeProjectManager.CMakeRunConfiguration. + Mesh + false + true + true + true + D:/github/OneFLOW/example/grid/1d/01/Mesh/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/example/grid/1d/01/Mesh/README.txt b/example/grid/1d/01/Mesh/README.txt new file mode 100644 index 00000000..eafaa046 --- /dev/null +++ b/example/grid/1d/01/Mesh/README.txt @@ -0,0 +1 @@ +cmake .. -D CMAKE_PREFIX_PATH:PATH="C:/local/Qt/6.8.1/msvc2022_64/" \ No newline at end of file diff --git a/example/grid/1d/01/Mesh/grid.cpp b/example/grid/1d/01/Mesh/grid.cpp new file mode 100644 index 00000000..3520fb67 --- /dev/null +++ b/example/grid/1d/01/Mesh/grid.cpp @@ -0,0 +1,109 @@ +#include "grid.h" + +void write_grid_str( const std::string & gridfilename, int ni, double xstart, double xend ) +{ + int index_file, icelldim, iphysdim, index_base; + int index_zone, index_coord; + char basename[ 33 ], zonename[ 33 ]; + + // A++++++++B + // o-------->i + // x_l x_r + // 1 ni + std::vector x(ni); + + double x_l = xstart; + double x_r = xend; + + double dx = ( x_r - x_l ) / ( ni - 1 ); + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = x_l + i * dx; + } + + if ( cg_open( gridfilename.c_str(), CG_MODE_WRITE, &index_file ) ) cg_error_exit(); + /* create base (user can give any name) */ + strcpy_s( basename, "Base" ); + icelldim = 1; + iphysdim = 1; + + std::vector isize( icelldim * 3, 0 ); + + cg_base_write( index_file, basename, icelldim, iphysdim, &index_base ); + /* vertex size */ + isize[ 0 ] = ni; + /* cell size */ + isize[ 1 ] = ni - 1; + /* boundary vertex size (always zero for structured grids) */ + isize[ 2 ] = 0; + + /* define zone 1 name (user can give any name) */ + strcpy_s( zonename, "Zone1" ); + /* create zone */ + cg_zone_write( index_file, index_base, zonename, isize.data(), CGNS_ENUMV( Structured ), &index_zone ); + /* write grid coordinates (user must use SIDS-standard names here) */ + cg_coord_write( index_file, index_base, index_zone, CGNS_ENUMV( RealDouble ), "CoordinateX", x.data(), &index_coord ); + + cg_close(index_file); +} + +void write_bc_str( const std::string & gridfilename, BC &left, BC &right ) +{ + std::printf( "\nProgram write_bc_str\n" ); + + int index_file = -1; + if ( cg_open( gridfilename.c_str(), CG_MODE_MODIFY, &index_file ) ) cg_error_exit(); + + int index_base = 1; + int icelldim = -1; + int iphysdim = -1; + char basename[ 33 ]; + cg_base_read( index_file, index_base, basename, &icelldim, &iphysdim ); + + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + /* get number of zones (should be 1 for our case) */ + int nzone = -1; + cg_nzones( index_file, index_base, &nzone ); + if ( nzone != 1 ) + { + std::printf( "\nError. This program expects 1 zones. %d read.\n", nzone ); + return; + } + + std::vector isize( icelldim * 3, 0 ); + std::vector ipnts( 2 * icelldim ); + + char zonename[ 33 ]; + + int index_zone = 1; + cg_zone_read( index_file, index_base, index_zone, zonename, isize.data() ); + + DumpZoneBc( index_file, index_base, index_zone, isize.data(), ipnts, left, right ); + + cg_close(index_file); +} + +void DumpZoneBc( int index_file, int index_base, int index_zone, cgsize_t *isize, std::vector &ipnts, BC &left, BC &right ) +{ + int ilo = 1; + int ihi = isize[ 0 ]; + int index_bc = -1; + + /* lower point of range */ + ipnts[ 0 ] = ilo; + /* upper point of range */ + ipnts[ 1 ] = ilo; + + cg_boco_write( index_file, index_base, index_zone, left.bcName.c_str(), left.bctype, CGNS_ENUMV( PointRange ), 2, ipnts.data(), &index_bc ); + + /* lower point of range */ + ipnts[ 0 ] = ihi; + /* upper point of range */ + ipnts[ 1 ] = ihi; + + cg_boco_write( index_file, index_base, index_zone, right.bcName.c_str(), right.bctype, CGNS_ENUMV( PointRange ), 2, ipnts.data(), &index_bc ); +} + + diff --git a/example/grid/1d/01/Mesh/grid.h b/example/grid/1d/01/Mesh/grid.h new file mode 100644 index 00000000..ae778a1e --- /dev/null +++ b/example/grid/1d/01/Mesh/grid.h @@ -0,0 +1,15 @@ +#include "cgnslib.h" +#include +#include +#include + +class BC +{ +public: + std::string bcName; + BCType_t bctype; +}; + +void write_grid_str( const std::string & gridfilename, int ni, double xstart, double xend ); +void write_bc_str( const std::string & gridfilename, BC &left, BC &right ); +void DumpZoneBc( int index_file, int index_base, int index_zone, cgsize_t * isize, std::vector & ipnts, BC &left, BC &right ); diff --git a/example/grid/1d/01/Mesh/main.cpp b/example/grid/1d/01/Mesh/main.cpp new file mode 100644 index 00000000..818a6e1e --- /dev/null +++ b/example/grid/1d/01/Mesh/main.cpp @@ -0,0 +1,12 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.setWindowTitle("Mesh"); + w.show(); + return a.exec(); +} diff --git a/example/grid/1d/01/Mesh/mainwindow.cpp b/example/grid/1d/01/Mesh/mainwindow.cpp new file mode 100644 index 00000000..0786d498 --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.cpp @@ -0,0 +1,33 @@ +#include "mainwindow.h" +#include "./ui_mainwindow.h" +#include "meshdialog.h" + + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + this->menuFile = new QMenu("&File", this); + this->ui->menubar->addMenu( this->menuFile ); + this->actNew = new QAction("New"); + this->menuFile->addAction( this->actNew ); + QObject::connect(this->actNew, &QAction::triggered, this, &MainWindow::triggerNew); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::triggerNew() +{ + showDialog(); +} + +void MainWindow::showDialog() +{ + MeshDialog dialog(this); + dialog.exec(); // 显示对话框,阻塞直到关闭 +} diff --git a/example/grid/1d/01/Mesh/mainwindow.h b/example/grid/1d/01/Mesh/mainwindow.h new file mode 100644 index 00000000..e05442b8 --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.h @@ -0,0 +1,30 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QMenu; +class QAction; + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); +public: + void triggerNew(); + void showDialog(); +private: + Ui::MainWindow *ui; + QMenu * menuFile; + QAction * actNew; +}; +#endif // MAINWINDOW_H diff --git a/example/grid/1d/01/Mesh/mainwindow.ui b/example/grid/1d/01/Mesh/mainwindow.ui new file mode 100644 index 00000000..7bff7e1d --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.ui @@ -0,0 +1,31 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 0 + 800 + 21 + + + + + + + + diff --git a/example/grid/1d/01/Mesh/meshdialog.cpp b/example/grid/1d/01/Mesh/meshdialog.cpp new file mode 100644 index 00000000..c936ec25 --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.cpp @@ -0,0 +1,78 @@ +#include "meshdialog.h" +#include "ui_meshdialog.h" +#include "grid.h" + +std::map bctype_map{ + {"BCTypeNull", BCTypeNull}, + {"BCAxisymmetricWedge", BCAxisymmetricWedge}, + {"BCDegenerateLine", BCDegenerateLine}, + {"BCDegeneratePoint", BCDegeneratePoint}, + {"BCDirichlet", BCDirichlet}, + {"BCExtrapolate", BCExtrapolate}, + {"BCFarfield", BCFarfield}, + {"BCGeneral", BCGeneral}, + {"BCInflow", BCInflow}, + {"BCInflowSubsonic", BCInflowSubsonic}, + {"BCOutflowSupersonic", BCOutflowSupersonic}, + {"BCSymmetryPlane", BCSymmetryPlane}, + {"BCSymmetryPolar", BCSymmetryPolar}, + {"BCTunnelInflow", BCTunnelInflow}, + {"BCTunnelOutflow", BCTunnelOutflow}, + {"BCWall", BCWall}, + {"BCWallInviscid", BCWallInviscid}, + {"BCWallViscous", BCWallViscous}, + {"BCWallViscousHeatFlux", BCWallViscousHeatFlux}, + {"BCWallViscousIsothermal", BCWallViscousIsothermal}, + {"FamilySpecified", FamilySpecified} +}; + +MeshDialog::MeshDialog(QWidget *parent) + : QDialog(parent) + , ui(new Ui::MeshDialog) +{ + ui->setupUi(this); + this->AddBcItems(ui->comboBoxBcL); + this->AddBcItems(ui->comboBoxBcR); +} + +MeshDialog::~MeshDialog() +{ + delete ui; +} + +void MeshDialog::AddBcItems(QComboBox *comBox) +{ + for( std::map::iterator iter = bctype_map.begin(); iter != bctype_map.end(); ++ iter ) + { + comBox->addItem(QString::fromStdString(iter->first)); + } + +} + +void MeshDialog::on_buttonBox_accepted() +{ + qDebug() << "MeshDialog::on_buttonBox_accepted()"; + QString txt = ui->npoints_lineEdit->text(); + int nPoints = txt.toInt(); + qDebug() << "nPoints = " << nPoints; + double xstart = ui->lineEdit_Start_X->text().toDouble(); + double xend = ui->lineEdit_End_X->text().toDouble(); + + std::string gridfilename = ui->lineEditGrid->text().toStdString(); + BC left, right; + left.bcName = ui->lineEditBcNameL->text().toStdString(); + std::map::iterator iterL = bctype_map.find(ui->comboBoxBcL->currentText().toStdString()); + left.bctype = iterL->second; + right.bcName = ui->lineEditBcNameR->text().toStdString(); + std::map::iterator iterR = bctype_map.find(ui->comboBoxBcR->currentText().toStdString()); + right.bctype = iterR->second; + + DumpGrid( gridfilename, nPoints, xstart, xend, left, right ); +} + +void MeshDialog::DumpGrid( const std::string &gridfilename, int nPoints, double xstart, double xend, BC &left, BC &right ) +{ + write_grid_str( gridfilename, nPoints, xstart, xend ); + write_bc_str( gridfilename, left, right ); +} + diff --git a/example/grid/1d/01/Mesh/meshdialog.h b/example/grid/1d/01/Mesh/meshdialog.h new file mode 100644 index 00000000..7b6957ee --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.h @@ -0,0 +1,30 @@ +#ifndef MESHDIALOG_H +#define MESHDIALOG_H + +#include + +namespace Ui { +class MeshDialog; +} + +class BC; +class QComboBox; + +class MeshDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MeshDialog(QWidget *parent = nullptr); + ~MeshDialog(); + +private slots: + void on_buttonBox_accepted(); +private: + void DumpGrid( const std::string &gridfilename, int nPoints, double xstart, double xend, BC &left, BC &right ); + void AddBcItems(QComboBox *comBox); +private: + Ui::MeshDialog *ui; +}; + +#endif // MESHDIALOG_H diff --git a/example/grid/1d/01/Mesh/meshdialog.ui b/example/grid/1d/01/Mesh/meshdialog.ui new file mode 100644 index 00000000..9eab1aeb --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.ui @@ -0,0 +1,296 @@ + + + MeshDialog + + + + 0 + 0 + 512 + 383 + + + + Dialog + + + + + 120 + 320 + 341 + 32 + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + 30 + 40 + 71 + 21 + + + + N + + + + + + 30 + 80 + 53 + 15 + + + + start + + + + + + 120 + 40 + 113 + 21 + + + + 101 + + + + + + 120 + 80 + 113 + 21 + + + + 0 + + + + + + 120 + 120 + 113 + 21 + + + + 1 + + + + + + 30 + 120 + 53 + 15 + + + + end + + + + + + 30 + 290 + 53 + 15 + + + + grid file + + + + + + 120 + 290 + 191 + 21 + + + + mygrid.cgns + + + + + + 30 + 160 + 53 + 15 + + + + Left BC + + + + + + 161 + 188 + 191 + 21 + + + + + + + 30 + 230 + 53 + 15 + + + + Right BC + + + + + + 161 + 260 + 191 + 21 + + + + + + + 161 + 161 + 191 + 21 + + + + Left + + + + + + 90 + 160 + 53 + 15 + + + + Name + + + + + + 90 + 190 + 53 + 15 + + + + Type + + + + + + 90 + 230 + 53 + 15 + + + + Name + + + + + + 90 + 260 + 53 + 15 + + + + Type + + + + + + 161 + 233 + 191 + 21 + + + + Right + + + + + + + buttonBox + accepted() + MeshDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MeshDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/example/weno-coef/crj/fortran/01/coef.f90 b/example/weno-coef/crj/fortran/01/coef.f90 new file mode 100644 index 00000000..543ec5c3 --- /dev/null +++ b/example/weno-coef/crj/fortran/01/coef.f90 @@ -0,0 +1,13 @@ +program main + implicit none + integer :: i, j + integer, parameter :: iorder = 2 + double precision :: coef(0:iorder-1, 0:iorder-1) + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + /0.5,0.5,-0.5,1.5/ + do i = 0, iorder-1 + do j = 0, iorder-1 + print *, 'coef(', i, ',', j, ') = ', coef(i,j) + end do + end do +end program main \ No newline at end of file diff --git a/example/weno-coef/crj/python/01/crj.py b/example/weno-coef/crj/python/01/crj.py new file mode 100644 index 00000000..c7658bdf --- /dev/null +++ b/example/weno-coef/crj/python/01/crj.py @@ -0,0 +1,44 @@ +import math + +def calculate_crj(r, j, k): + result = 0 + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += numerator / denominator + + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in [1, 2, 3]: + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"c_{r}{j} = {c_rj}") + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01a/crj.py b/example/weno-coef/crj/python/01a/crj.py new file mode 100644 index 00000000..12985c33 --- /dev/null +++ b/example/weno-coef/crj/python/01a/crj.py @@ -0,0 +1,59 @@ +import math +from fractions import Fraction + +def divide_as_simplified_fraction(a, b): + if b == 0: + raise ValueError("分母不能为零!") + + # 计算最大公约数(GCD) + gcd_value = math.gcd(a, b) + + # 化简分数 + simplified_num = a // gcd_value + simplified_den = b // gcd_value + + # 返回最简分数形式 + return f"{simplified_num}/{simplified_den}" + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + #result += numerator / denominator + result += Fraction(numerator, denominator) + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in [1, 2, 3]: + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"c_{r}{j} = {c_rj}") + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01b/crj.py b/example/weno-coef/crj/python/01b/crj.py new file mode 100644 index 00000000..d1fc6399 --- /dev/null +++ b/example/weno-coef/crj/python/01b/crj.py @@ -0,0 +1,46 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + #result += numerator / denominator + result += Fraction(numerator, denominator) + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in range(1,8): + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"{c_rj} ", end='') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01c/crj.py b/example/weno-coef/crj/python/01c/crj.py new file mode 100644 index 00000000..aecd468c --- /dev/null +++ b/example/weno-coef/crj/python/01c/crj.py @@ -0,0 +1,54 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += Fraction(numerator, denominator) + return result + + +for k in range(1,8): + print(f"=== k = {k} ===") + # 计算矩阵并存储到列表中 + mat = [] + for r in range(k): + row = [] + for j in range(k): + c_rj = calculate_crj(r, j, k) + row.append(c_rj) + mat.append(row) + # 计算每个分数的最大宽度 + max_width = max(len(str(item)) for row in mat for item in row) + for row in mat: + for item in row: + print(f"{str(item):^{max_width}}", end=' ') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01d/crj.py b/example/weno-coef/crj/python/01d/crj.py new file mode 100644 index 00000000..bca0716b --- /dev/null +++ b/example/weno-coef/crj/python/01d/crj.py @@ -0,0 +1,54 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += Fraction(numerator, denominator) + return result + + +for k in range(1,8): + print(f"=== k = {k} ===") + # 计算矩阵并存储到列表中 + mat = [] + for r in range(-1,k): + row = [] + for j in range(k): + c_rj = calculate_crj(r, j, k) + row.append(c_rj) + mat.append(row) + # 计算每个分数的最大宽度 + max_width = max(len(str(item)) for row in mat for item in row) + for row in mat: + for item in row: + print(f"{str(item):^{max_width}}", end=' ') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/02/crj.py b/example/weno-coef/crj/python/02/crj.py new file mode 100644 index 00000000..12eedccc --- /dev/null +++ b/example/weno-coef/crj/python/02/crj.py @@ -0,0 +1,27 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 一维差分示意图 +def plot_1d_fdm(): + # 定义网格点 + x = np.linspace(0, 1, 6) # 6个网格点 + dx = x[1] - x[0] # 网格间距 + + # 绘制网格点 + plt.figure(figsize=(8, 2)) + plt.scatter(x, np.zeros_like(x), color='black', s=100, zorder=5) + for i, xi in enumerate(x): + plt.text(xi, -0.05, f'$x_{i}$', ha='center', fontsize=12) + + # 绘制网格线 + for i in range(len(x) - 1): + plt.plot([x[i], x[i + 1]], [0, 0], color='black', linestyle='--', linewidth=1) + + # 添加标题和标签 + plt.title('One-Dimensional Finite Difference Grid', fontsize=14) + plt.xlabel('x', fontsize=12) + plt.yticks([]) + plt.grid(False) + plt.show() + +plot_1d_fdm() \ No newline at end of file diff --git a/example/weno-coef/crj/python/02a/crj.py b/example/weno-coef/crj/python/02a/crj.py new file mode 100644 index 00000000..0323f1bf --- /dev/null +++ b/example/weno-coef/crj/python/02a/crj.py @@ -0,0 +1,35 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 二维差分示意图 +def plot_2d_fdm(): + # 定义网格点 + x = np.linspace(0, 1, 5) # 5个网格点 + y = np.linspace(0, 1, 5) # 5个网格点 + dx = x[1] - x[0] # 网格间距 + dy = y[1] - y[0] # 网格间距 + + # 创建网格 + X, Y = np.meshgrid(x, y) + + # 绘制网格点 + plt.figure(figsize=(6, 6)) + plt.scatter(X, Y, color='black', s=100, zorder=5) + for i in range(len(x)): + for j in range(len(y)): + plt.text(X[j, i], Y[j, i], f'({i},{j})', ha='center', fontsize=10) + + # 绘制网格线 + for i in range(len(x)): + plt.plot(X[i, :], Y[i, :], color='black', linestyle='--', linewidth=1) + for j in range(len(y)): + plt.plot(X[:, j], Y[:, j], color='black', linestyle='--', linewidth=1) + + # 添加标题和标签 + plt.title('Two-Dimensional Finite Difference Grid', fontsize=14) + plt.xlabel('x', fontsize=12) + plt.ylabel('y', fontsize=12) + plt.grid(False) + plt.show() + +plot_2d_fdm() \ No newline at end of file diff --git a/example/weno-coef/divide_as_simplified_fraction/div.py b/example/weno-coef/divide_as_simplified_fraction/div.py new file mode 100644 index 00000000..6562990e --- /dev/null +++ b/example/weno-coef/divide_as_simplified_fraction/div.py @@ -0,0 +1,21 @@ +import math + +def divide_as_simplified_fraction(a, b): + if b == 0: + raise ValueError("分母不能为零!") + + # 计算最大公约数(GCD) + gcd_value = math.gcd(a, b) + + # 化简分数 + simplified_num = a // gcd_value + simplified_den = b // gcd_value + + # 返回最简分数形式 + return f"{simplified_num}/{simplified_den}" + +# 示例 +a = 10 +b = 4 +result = divide_as_simplified_fraction(a, b) +print(f"{a} / {b} = {result}") \ No newline at end of file diff --git a/example/weno-coef/eno/01/testprj.py b/example/weno-coef/eno/01/testprj.py new file mode 100644 index 00000000..2398ea60 --- /dev/null +++ b/example/weno-coef/eno/01/testprj.py @@ -0,0 +1,58 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义列向量和矩阵 +vector = np.array([[1, -0.5, 0.25]]) +matrix = np.array([[-1/24, 13/12, -1/24], + [-0.5, 0, 0.5], + [0.5, -1, 0.5]]) + +# 计算矩阵乘法 +result = np.dot(vector, matrix) + +# 打印结果 +print("Result of matrix multiplication:") +#print(result) +print_matrix_fraction(result) \ No newline at end of file diff --git a/example/weno-coef/eno/01a/testprj.py b/example/weno-coef/eno/01a/testprj.py new file mode 100644 index 00000000..5fe976a6 --- /dev/null +++ b/example/weno-coef/eno/01a/testprj.py @@ -0,0 +1,18 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + print(row) + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/eno/01b/testprj.py b/example/weno-coef/eno/01b/testprj.py new file mode 100644 index 00000000..5afcadc7 --- /dev/null +++ b/example/weno-coef/eno/01b/testprj.py @@ -0,0 +1,70 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/eno/01c/testprj.py b/example/weno-coef/eno/01c/testprj.py new file mode 100644 index 00000000..cc9f7662 --- /dev/null +++ b/example/weno-coef/eno/01c/testprj.py @@ -0,0 +1,76 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = np.array([[1, -1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + diff --git a/example/weno-coef/eno/02/testprj.py b/example/weno-coef/eno/02/testprj.py new file mode 100644 index 00000000..56889fa4 --- /dev/null +++ b/example/weno-coef/eno/02/testprj.py @@ -0,0 +1,133 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k,lr): + arrays_list = [] + #k = r + s + 1 + ishift = 0 + if lr == 1: + ishift = -1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii+ishift,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k,lr): + matrix = create_matrix(r,s,k,lr) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + xi = 0.5 + if lr == 1: + xi = -0.5 + + m1 = compute_coef(xi,k).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + + +k=3 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +lr = -1 +#lr = 1 + +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k,lr) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/eno/03/matrix_data.txt b/example/weno-coef/eno/03/matrix_data.txt new file mode 100644 index 00000000..099bb3dc --- /dev/null +++ b/example/weno-coef/eno/03/matrix_data.txt @@ -0,0 +1,6 @@ +137/60, -163/60, 137/60, -21/20, 1/5 +1/5, 77/60, -43/60, 17/60, -1/20 +-1/20, 9/20, 47/60, -13/60, 1/30 +1/30, -13/60, 47/60, 9/20, -1/20 +-1/20, 17/60, -43/60, 77/60, 1/5 +1/5, -21/20, 137/60, -163/60, 137/60 \ No newline at end of file diff --git a/example/weno-coef/eno/03/testprj.py b/example/weno-coef/eno/03/testprj.py new file mode 100644 index 00000000..5d6883a4 --- /dev/null +++ b/example/weno-coef/eno/03/testprj.py @@ -0,0 +1,23 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 分割每行的数据 + elements = line.strip().split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = map(float, element.split('/')) + # 计算浮点数结果 + row.append(numerator / denominator) + matrix.append(row) + return matrix + +# 示例:读取文件 +file_path = 'matrix_data.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]:.1f}") \ No newline at end of file diff --git a/example/weno-coef/eno/03a/matrix_data.txt b/example/weno-coef/eno/03a/matrix_data.txt new file mode 100644 index 00000000..099bb3dc --- /dev/null +++ b/example/weno-coef/eno/03a/matrix_data.txt @@ -0,0 +1,6 @@ +137/60, -163/60, 137/60, -21/20, 1/5 +1/5, 77/60, -43/60, 17/60, -1/20 +-1/20, 9/20, 47/60, -13/60, 1/30 +1/30, -13/60, 47/60, 9/20, -1/20 +-1/20, 17/60, -43/60, 77/60, 1/5 +1/5, -21/20, 137/60, -163/60, 137/60 \ No newline at end of file diff --git a/example/weno-coef/eno/03a/testprj.py b/example/weno-coef/eno/03a/testprj.py new file mode 100644 index 00000000..5799d211 --- /dev/null +++ b/example/weno-coef/eno/03a/testprj.py @@ -0,0 +1,23 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 分割每行的数据 + elements = line.strip().split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +# 示例:读取文件 +file_path = 'matrix_data.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/eno/03b/matrix_data.txt b/example/weno-coef/eno/03b/matrix_data.txt new file mode 100644 index 00000000..dcfa6393 --- /dev/null +++ b/example/weno-coef/eno/03b/matrix_data.txt @@ -0,0 +1,7 @@ +[ 49/20, -71/20, 79/20, -163/60, 31/30, -1/6 ] +[ 1/6, 29/20, -21/20, 37/60, -13/60, 1/30 ] +[ -1/30, 11/30, 19/20, -23/60, 7/60, -1/60 ] +[ 1/60, -2/15, 37/60, 37/60, -2/15, 1/60 ] +[ -1/60, 7/60, -23/60, 19/20, 11/30, -1/30 ] +[ 1/30, -13/60, 37/60, -21/20, 29/20, 1/6 ] +[ -1/6, 31/30, -163/60, 79/20, -71/20, 49/20 ] \ No newline at end of file diff --git a/example/weno-coef/eno/03b/matrix_output.txt b/example/weno-coef/eno/03b/matrix_output.txt new file mode 100644 index 00000000..e7de556a --- /dev/null +++ b/example/weno-coef/eno/03b/matrix_output.txt @@ -0,0 +1,42 @@ +coef(0, 0) = 49.0/20.0 +coef(0, 1) = -71.0/20.0 +coef(0, 2) = 79.0/20.0 +coef(0, 3) = -163.0/60.0 +coef(0, 4) = 31.0/30.0 +coef(0, 5) = -1.0/6.0 +coef(1, 0) = 1.0/6.0 +coef(1, 1) = 29.0/20.0 +coef(1, 2) = -21.0/20.0 +coef(1, 3) = 37.0/60.0 +coef(1, 4) = -13.0/60.0 +coef(1, 5) = 1.0/30.0 +coef(2, 0) = -1.0/30.0 +coef(2, 1) = 11.0/30.0 +coef(2, 2) = 19.0/20.0 +coef(2, 3) = -23.0/60.0 +coef(2, 4) = 7.0/60.0 +coef(2, 5) = -1.0/60.0 +coef(3, 0) = 1.0/60.0 +coef(3, 1) = -2.0/15.0 +coef(3, 2) = 37.0/60.0 +coef(3, 3) = 37.0/60.0 +coef(3, 4) = -2.0/15.0 +coef(3, 5) = 1.0/60.0 +coef(4, 0) = -1.0/60.0 +coef(4, 1) = 7.0/60.0 +coef(4, 2) = -23.0/60.0 +coef(4, 3) = 19.0/20.0 +coef(4, 4) = 11.0/30.0 +coef(4, 5) = -1.0/30.0 +coef(5, 0) = 1.0/30.0 +coef(5, 1) = -13.0/60.0 +coef(5, 2) = 37.0/60.0 +coef(5, 3) = -21.0/20.0 +coef(5, 4) = 29.0/20.0 +coef(5, 5) = 1.0/6.0 +coef(6, 0) = -1.0/6.0 +coef(6, 1) = 31.0/30.0 +coef(6, 2) = -163.0/60.0 +coef(6, 3) = 79.0/20.0 +coef(6, 4) = -71.0/20.0 +coef(6, 5) = 49.0/20.0 diff --git a/example/weno-coef/eno/03b/testprj.py b/example/weno-coef/eno/03b/testprj.py new file mode 100644 index 00000000..a3f7ff9e --- /dev/null +++ b/example/weno-coef/eno/03b/testprj.py @@ -0,0 +1,35 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 去掉每行首尾的方括号和空格 + line = line.strip().strip('[]') + # 分割每行的数据 + elements = line.split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +def write_matrix_to_file(matrix, output_file_path): + with open(output_file_path, 'w') as file: + for i in range(len(matrix)): + for j in range(len(matrix[i])): + file.write(f"coef({i}, {j}) = {matrix[i][j]}\n") + +# 示例:读取文件 +file_path = 'matrix_data.txt' +output_file_path = 'matrix_output.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果到文件 +write_matrix_to_file(matrix, output_file_path) + +# 打印结果到控制台 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/eno/03c/matrix_data.txt b/example/weno-coef/eno/03c/matrix_data.txt new file mode 100644 index 00000000..0a4d2545 --- /dev/null +++ b/example/weno-coef/eno/03c/matrix_data.txt @@ -0,0 +1,8 @@ +[ 363/140, -617/140, 853/140, -2341/420, 667/210, -43/42, 1/7 ] +[ 1/7, 223/140, -197/140, 153/140, -241/420, 37/210, -1/42 ] +[ -1/42, 13/42, 153/140, -241/420, 109/420, -31/420, 1/105 ] +[ 1/105, -19/210, 107/210, 319/420, -101/420, 5/84, -1/140 ] +[ -1/140, 5/84, -101/420, 319/420, 107/210, -19/210, 1/105 ] +[ 1/105, -31/420, 109/420, -241/420, 153/140, 13/42, -1/42 ] +[ -1/42, 37/210, -241/420, 153/140, -197/140, 223/140, 1/7 ] +[ 1/7, -43/42, 667/210, -2341/420, 853/140, -617/140, 363/140 ] \ No newline at end of file diff --git a/example/weno-coef/eno/03c/matrix_output.txt b/example/weno-coef/eno/03c/matrix_output.txt new file mode 100644 index 00000000..a45ca96a --- /dev/null +++ b/example/weno-coef/eno/03c/matrix_output.txt @@ -0,0 +1,56 @@ +coef(0, 0) = 363.0/140.0 +coef(0, 1) = -617.0/140.0 +coef(0, 2) = 853.0/140.0 +coef(0, 3) = -2341.0/420.0 +coef(0, 4) = 667.0/210.0 +coef(0, 5) = -43.0/42.0 +coef(0, 6) = 1.0/7.0 +coef(1, 0) = 1.0/7.0 +coef(1, 1) = 223.0/140.0 +coef(1, 2) = -197.0/140.0 +coef(1, 3) = 153.0/140.0 +coef(1, 4) = -241.0/420.0 +coef(1, 5) = 37.0/210.0 +coef(1, 6) = -1.0/42.0 +coef(2, 0) = -1.0/42.0 +coef(2, 1) = 13.0/42.0 +coef(2, 2) = 153.0/140.0 +coef(2, 3) = -241.0/420.0 +coef(2, 4) = 109.0/420.0 +coef(2, 5) = -31.0/420.0 +coef(2, 6) = 1.0/105.0 +coef(3, 0) = 1.0/105.0 +coef(3, 1) = -19.0/210.0 +coef(3, 2) = 107.0/210.0 +coef(3, 3) = 319.0/420.0 +coef(3, 4) = -101.0/420.0 +coef(3, 5) = 5.0/84.0 +coef(3, 6) = -1.0/140.0 +coef(4, 0) = -1.0/140.0 +coef(4, 1) = 5.0/84.0 +coef(4, 2) = -101.0/420.0 +coef(4, 3) = 319.0/420.0 +coef(4, 4) = 107.0/210.0 +coef(4, 5) = -19.0/210.0 +coef(4, 6) = 1.0/105.0 +coef(5, 0) = 1.0/105.0 +coef(5, 1) = -31.0/420.0 +coef(5, 2) = 109.0/420.0 +coef(5, 3) = -241.0/420.0 +coef(5, 4) = 153.0/140.0 +coef(5, 5) = 13.0/42.0 +coef(5, 6) = -1.0/42.0 +coef(6, 0) = -1.0/42.0 +coef(6, 1) = 37.0/210.0 +coef(6, 2) = -241.0/420.0 +coef(6, 3) = 153.0/140.0 +coef(6, 4) = -197.0/140.0 +coef(6, 5) = 223.0/140.0 +coef(6, 6) = 1.0/7.0 +coef(7, 0) = 1.0/7.0 +coef(7, 1) = -43.0/42.0 +coef(7, 2) = 667.0/210.0 +coef(7, 3) = -2341.0/420.0 +coef(7, 4) = 853.0/140.0 +coef(7, 5) = -617.0/140.0 +coef(7, 6) = 363.0/140.0 diff --git a/example/weno-coef/eno/03c/testprj.py b/example/weno-coef/eno/03c/testprj.py new file mode 100644 index 00000000..a3f7ff9e --- /dev/null +++ b/example/weno-coef/eno/03c/testprj.py @@ -0,0 +1,35 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 去掉每行首尾的方括号和空格 + line = line.strip().strip('[]') + # 分割每行的数据 + elements = line.split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +def write_matrix_to_file(matrix, output_file_path): + with open(output_file_path, 'w') as file: + for i in range(len(matrix)): + for j in range(len(matrix[i])): + file.write(f"coef({i}, {j}) = {matrix[i][j]}\n") + +# 示例:读取文件 +file_path = 'matrix_data.txt' +output_file_path = 'matrix_output.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果到文件 +write_matrix_to_file(matrix, output_file_path) + +# 打印结果到控制台 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/fractions/01/testprj.py b/example/weno-coef/fractions/01/testprj.py new file mode 100644 index 00000000..8b8b1bef --- /dev/null +++ b/example/weno-coef/fractions/01/testprj.py @@ -0,0 +1,23 @@ +import numpy as np +from fractions import Fraction + +def calculate_determinant(matrix): + det = np.linalg.det(matrix) + return Fraction(det).limit_denominator() + +def calculate_adjugate(matrix): + cofactor_matrix = np.linalg.inv(matrix).T + return cofactor_matrix.tolist() + +def inverse_matrix(matrix): + det = calculate_determinant(matrix) + if det == 0: + raise ValueError("Matrix is singular and does not have an inverse.") + adjugate = calculate_adjugate(matrix) + inverse = [[Fraction(adjugate[i][j]) / det for j in range(len(adjugate))] for i in range(len(adjugate))] + return inverse + +matrix = np.array([[1, -1, 13/12], [1, 0, 1/12], [1, 1, 13/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/02/testprj.py b/example/weno-coef/fractions/02/testprj.py new file mode 100644 index 00000000..6d04ee6f --- /dev/null +++ b/example/weno-coef/fractions/02/testprj.py @@ -0,0 +1,12 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +matrix = np.array([[1, -1, 13/12], [1, 0, 1/12], [1, 1, 13/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/02a/testprj.py b/example/weno-coef/fractions/02a/testprj.py new file mode 100644 index 00000000..77f24b02 --- /dev/null +++ b/example/weno-coef/fractions/02a/testprj.py @@ -0,0 +1,30 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 +original_matrix = np.array([[1, -1, 13/12], + [1, 0, 1/12], + [1, 1, 13/12]]) + +# 定义计算出的逆矩阵 +inverse_matrix = np.array([[Fraction(-1, 24), Fraction(13, 12), Fraction(-1, 24)], + [Fraction(-1, 2), Fraction(0, 1), Fraction(1, 2)], + [Fraction(1, 2), Fraction(-1, 1), Fraction(1, 2)]]) + +# 将 Fraction 转换为浮点数进行矩阵乘法 +original_matrix = original_matrix.astype(float) +inverse_matrix = inverse_matrix.astype(float) + +# 计算两个矩阵的乘积 +product = np.dot(original_matrix, inverse_matrix) + +# 检查乘积是否接近单位矩阵 +identity_matrix = np.eye(3) + +# 打印结果 +print("Product of the matrices:") +print(product) +print("\nIdentity matrix:") +print(identity_matrix) +print("\nDifference:") +print(np.abs(product - identity_matrix) < 1e-9) \ No newline at end of file diff --git a/example/weno-coef/fractions/03/testprj.py b/example/weno-coef/fractions/03/testprj.py new file mode 100644 index 00000000..5383b701 --- /dev/null +++ b/example/weno-coef/fractions/03/testprj.py @@ -0,0 +1,12 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/03a/testprj.py b/example/weno-coef/fractions/03a/testprj.py new file mode 100644 index 00000000..d0c902b0 --- /dev/null +++ b/example/weno-coef/fractions/03a/testprj.py @@ -0,0 +1,31 @@ +import numpy as np +from fractions import Fraction + +# 定义矩阵 A 的元素 +A = np.array([ + [Fraction(1, 1), Fraction(-2, 1), Fraction(49, 12)], + [Fraction(1, 1), Fraction(-1, 1), Fraction(13, 12)], + [Fraction(1, 1), Fraction(0, 1), Fraction(1, 12)] +], dtype=object) + +# 打印矩阵 A +print("Matrix A:") +for row in A: + print("[" + ", ".join(str(frac) for frac in row) + "]") + + +# 计算 A * A +product_AA = np.dot(A, A) + +# 打印矩阵 A * A +print("Matrix A * A:") +for row in product_AA: + print("[" + ", ".join(str(frac) for frac in row) + "]") + +# 计算矩阵 A 的逆矩阵 +A_inv = np.linalg.inv(A).astype(object) + +# 打印矩阵 A 的逆矩阵 +print("Inverse of Matrix A:") +for row in A_inv: + print("[" + ", ".join(str(Fraction(int(x.real), int(y))) if y != 0 else str(int(x.real)) for x, y in zip(row, [1, 1, 1])) + "]") \ No newline at end of file diff --git a/example/weno-coef/fractions/03b/testprj.py b/example/weno-coef/fractions/03b/testprj.py new file mode 100644 index 00000000..2cb708f6 --- /dev/null +++ b/example/weno-coef/fractions/03b/testprj.py @@ -0,0 +1,18 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + print(row) + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/03c/testprj.py b/example/weno-coef/fractions/03c/testprj.py new file mode 100644 index 00000000..cbbb31d9 --- /dev/null +++ b/example/weno-coef/fractions/03c/testprj.py @@ -0,0 +1,19 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/03d/testprj.py b/example/weno-coef/fractions/03d/testprj.py new file mode 100644 index 00000000..511b7d82 --- /dev/null +++ b/example/weno-coef/fractions/03d/testprj.py @@ -0,0 +1,25 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵 +print_matrix_fraction(matrix) +print_matrix_fraction(inverse) \ No newline at end of file diff --git a/example/weno-coef/fractions/03e/testprj.py b/example/weno-coef/fractions/03e/testprj.py new file mode 100644 index 00000000..16011164 --- /dev/null +++ b/example/weno-coef/fractions/03e/testprj.py @@ -0,0 +1,45 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印,行列等宽对齐 +def print_matrix_fraction(matrix): + # 找到每列最大宽度 + col_widths = [0] * matrix.shape[1] + for row in matrix: + for i, elem in enumerate(row): + # 将元素转换为字符串形式,包括分子和分母 + elem_str = f"{elem.numerator}/{elem.denominator}" if hasattr(elem, 'denominator') and elem.denominator > 1 else str(elem) + col_widths[i] = max(col_widths[i], len(elem_str)) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in matrix: + formatted_row = ", ".join(f"{{:^{col_widths[i]}}}".format(f"{elem.numerator}/{elem.denominator}" if hasattr(elem, 'denominator') and elem.denominator > 1 else elem) for i, elem in enumerate(row)) + print(f"[{formatted_row}]") + + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03f/testprj.py b/example/weno-coef/fractions/03f/testprj.py new file mode 100644 index 00000000..0f6093d0 --- /dev/null +++ b/example/weno-coef/fractions/03f/testprj.py @@ -0,0 +1,52 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fractionOLD(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + # 使用格式化字符串确保每个元素占用相同的宽度 + formatted_row = ", ".join(f"{f.numerator:2}/{f.denominator:2}" if f.denominator > 1 else f"{f.numerator:2}" for f in row) + print(f"[{formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03g/testprj.py b/example/weno-coef/fractions/03g/testprj.py new file mode 100644 index 00000000..4edb3e5f --- /dev/null +++ b/example/weno-coef/fractions/03g/testprj.py @@ -0,0 +1,71 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + rows = len(str_matrix) + cols = len(str_matrix[0]) + + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐 + formatted_element = f"{element:>{max_width}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + + + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03h/testprj.py b/example/weno-coef/fractions/03h/testprj.py new file mode 100644 index 00000000..9876a6fe --- /dev/null +++ b/example/weno-coef/fractions/03h/testprj.py @@ -0,0 +1,70 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/04/testprj.py b/example/weno-coef/fractions/04/testprj.py new file mode 100644 index 00000000..11975c1f --- /dev/null +++ b/example/weno-coef/fractions/04/testprj.py @@ -0,0 +1,37 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽对齐 + print("Matrix in Fraction Form:") + for row in str_matrix: + formatted_elements = [f"{s:>{max_width}}" for s in row] + formatted_row = " ".join(formatted_elements) + print(f"[ {formatted_row} ]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04a/testprj.py b/example/weno-coef/fractions/04a/testprj.py new file mode 100644 index 00000000..bc3369ed --- /dev/null +++ b/example/weno-coef/fractions/04a/testprj.py @@ -0,0 +1,51 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + rows = len(str_matrix) + cols = len(str_matrix[0]) + + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐 + formatted_element = f"{element:>{max_width}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04b/testprj.py b/example/weno-coef/fractions/04b/testprj.py new file mode 100644 index 00000000..df522808 --- /dev/null +++ b/example/weno-coef/fractions/04b/testprj.py @@ -0,0 +1,52 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04c/testprj.py b/example/weno-coef/fractions/04c/testprj.py new file mode 100644 index 00000000..151b6784 --- /dev/null +++ b/example/weno-coef/fractions/04c/testprj.py @@ -0,0 +1,11 @@ +import numpy as np + +# 定义列表 ii +ii = [-2, -1, 0] + +# 将列表 ii 转化为 NumPy 数组 matrix +matrix = np.array(ii) + +# 打印结果 +print("Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04d/testprj.py b/example/weno-coef/fractions/04d/testprj.py new file mode 100644 index 00000000..dea6c772 --- /dev/null +++ b/example/weno-coef/fractions/04d/testprj.py @@ -0,0 +1,11 @@ +import numpy as np + +# 定义列表 ii +ii = [-2, -1, 0] + +# 将列表 ii 转化为一个 1x3 的 NumPy 二维数组 matrix +matrix = np.array(ii).reshape(1, -1) + +# 打印结果 +print("Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04e/testprj.py b/example/weno-coef/fractions/04e/testprj.py new file mode 100644 index 00000000..1a5b50cb --- /dev/null +++ b/example/weno-coef/fractions/04e/testprj.py @@ -0,0 +1,13 @@ +import numpy as np + +# 定义三个二维数组 +a1 = np.array([[1, 1, 1]]) +a2 = np.array([[2, 2, 2]]) +a3 = np.array([[3, 3, 3]]) + +# 使用 vstack 函数将这三个数组垂直堆叠成一个矩阵 +matrix = np.vstack((a1, a2, a3)) + +# 打印结果 +print("Assembled Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04f/testprj.py b/example/weno-coef/fractions/04f/testprj.py new file mode 100644 index 00000000..0fa20273 --- /dev/null +++ b/example/weno-coef/fractions/04f/testprj.py @@ -0,0 +1,19 @@ +import numpy as np + +# 创建一个列表来存储所有数组 +arrays_list = [] + +# 动态地添加数组到列表中 +arrays_list.append(np.array([[1, 1, 1]])) +arrays_list.append(np.array([[2, 2, 2]])) +arrays_list.append(np.array([[3, 3, 3]])) +# 如果有更多数组,可以继续添加 +# arrays_list.append(np.array([[4, 4, 4]])) +# arrays_list.append(np.array([[5, 5, 5]])) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +# 打印结果 +print("Assembled Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/05/testprj.py b/example/weno-coef/fractions/05/testprj.py new file mode 100644 index 00000000..7f078fb0 --- /dev/null +++ b/example/weno-coef/fractions/05/testprj.py @@ -0,0 +1,77 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + + +m1 = np.array([[1, 1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + diff --git a/example/weno-coef/fractions/05a/testprj.py b/example/weno-coef/fractions/05a/testprj.py new file mode 100644 index 00000000..4a78daa5 --- /dev/null +++ b/example/weno-coef/fractions/05a/testprj.py @@ -0,0 +1,112 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def create_matrix(): + ii = np.array([[-2,-1,0]]) + print(f"{ii=}") + ilower = ii - 1/2 + iupper = ii + 1/2 + print(f"{iupper=}") + print(f"{ilower=}") + + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +matrix = create_matrix() + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + + +m1 = np.array([[1, 1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05b/testprj.py b/example/weno-coef/fractions/05b/testprj.py new file mode 100644 index 00000000..6f0f2afe --- /dev/null +++ b/example/weno-coef/fractions/05b/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(): + ii = np.array([[-2,-1,0]]) + print(f"{ii=}") + ilower = ii - 1/2 + iupper = ii + 1/2 + print(f"{iupper=}") + print(f"{ilower=}") + + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +matrix = create_matrix() + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = compute_coef(0.5).reshape(1, -1) +print_matrix_fraction(m1) + +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05c/testprj.py b/example/weno-coef/fractions/05c/testprj.py new file mode 100644 index 00000000..b198ff6b --- /dev/null +++ b/example/weno-coef/fractions/05c/testprj.py @@ -0,0 +1,148 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(): + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def create_matrix_new(k): + k1 = k-1 + print(f'{k1=}') + + for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + #x0 = compute_diff_coef(-2) + #x1 = compute_diff_coef(-1) + #x2 = compute_diff_coef(0) + #print(f"{x0=}") + #print(f"{x1=}") + #print(f"{x2=}") + + + # 动态地生成一些一维数组并添加到列表中 + #arrays_list.append(x0) + #arrays_list.append(x1) + #arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +#matrix = create_matrix() +k=3 +matrix = create_matrix_new(k) + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = compute_coef(0.5).reshape(1, -1) +print_matrix_fraction(m1) + +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05d/testprj.py b/example/weno-coef/fractions/05d/testprj.py new file mode 100644 index 00000000..7700ace6 --- /dev/null +++ b/example/weno-coef/fractions/05d/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(k): + k1 = k-1 + print(f'{k1=}') + + for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def calc_eno_coef(k): + matrix = create_matrix(k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + print("\nInverse Matrix in Fraction Form:") + print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + print("\nProduct of Matrix and Inverse Matrix:") + print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + #print("\n Matrix C:") + #print_matrix_fraction(mc) + return mc + +k=3 +mc = calc_eno_coef(k) +print("\n Matrix C:") +print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05e/testprj.py b/example/weno-coef/fractions/05e/testprj.py new file mode 100644 index 00000000..e57f3cff --- /dev/null +++ b/example/weno-coef/fractions/05e/testprj.py @@ -0,0 +1,127 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(k): + #k1 = k-1 + #print(f'{k1=}') + # + #for s in range(k): + # r = k1 - s + # print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def calc_eno_coef(k): + matrix = create_matrix(k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + print("\nInverse Matrix in Fraction Form:") + print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + print("\nProduct of Matrix and Inverse Matrix:") + print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + #print("\n Matrix C:") + #print_matrix_fraction(mc) + return mc + +k=3 +k1 = k-1 +print(f'{k1=}') + +for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + +mc = calc_eno_coef(k) +print("\n Matrix C:") +print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05f/testprj.py b/example/weno-coef/fractions/05f/testprj.py new file mode 100644 index 00000000..f75c0cbb --- /dev/null +++ b/example/weno-coef/fractions/05f/testprj.py @@ -0,0 +1,117 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +print(f'{k1=}') + +for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + print("\n Matrix C:") + print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05g/testprj.py b/example/weno-coef/fractions/05g/testprj.py new file mode 100644 index 00000000..406849b7 --- /dev/null +++ b/example/weno-coef/fractions/05g/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +for s in range(k): + r = k1 - s + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + #print("\n Matrix C:") + #print_matrix_fraction(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/05h/testprj.py b/example/weno-coef/fractions/05h/testprj.py new file mode 100644 index 00000000..5f5be5b2 --- /dev/null +++ b/example/weno-coef/fractions/05h/testprj.py @@ -0,0 +1,122 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +for s in range(k+1): + r = k1 - s + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/05i/testprj.py b/example/weno-coef/fractions/05i/testprj.py new file mode 100644 index 00000000..cdbffb66 --- /dev/null +++ b/example/weno-coef/fractions/05i/testprj.py @@ -0,0 +1,127 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +#for s in range(k+1): +# r = k1 - s +# #print(f'{r=},{s=},{k=}') +# mc = calc_eno_coef(r,s) +# arrays_list.append(mc) +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06/testprj.py b/example/weno-coef/fractions/06/testprj.py new file mode 100644 index 00000000..937dc257 --- /dev/null +++ b/example/weno-coef/fractions/06/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +#k=3 +k=1 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +for r in range(-1,k): + s = k1 - r + print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06a/testprj.py b/example/weno-coef/fractions/06a/testprj.py new file mode 100644 index 00000000..97d33fff --- /dev/null +++ b/example/weno-coef/fractions/06a/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + + +k=1 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06b/testprj.py b/example/weno-coef/fractions/06b/testprj.py new file mode 100644 index 00000000..c859854f --- /dev/null +++ b/example/weno-coef/fractions/06b/testprj.py @@ -0,0 +1,125 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +kmax = 7 + +for k in range(1,kmax+1): + k1 = k-1 + print(f'{k=}') + #print(f'{k1=}') + arrays_list = [] + + for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + + # 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + + print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06c/testprj.py b/example/weno-coef/fractions/06c/testprj.py new file mode 100644 index 00000000..12c4ac56 --- /dev/null +++ b/example/weno-coef/fractions/06c/testprj.py @@ -0,0 +1,125 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}.0" + else: + s = f"{f.numerator}.0/{f.denominator}.0" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +kmax = 7 + +for k in range(1,kmax+1): + k1 = k-1 + print(f'{k=}') + #print(f'{k1=}') + arrays_list = [] + + for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + + # 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + + print_matrix_fraction(matrix)