diff --git a/README.md b/README.md index e159dede..44ffaba3 100644 --- a/README.md +++ b/README.md @@ -65,4 +65,4 @@ Email: If you have any problem in building or running the code, please do not hesitate to contact. -Copyright 2017-2024, He Xin, and the OneFLOW contributors. +Copyright 2017-2025, He Xin, and the OneFLOW contributors. diff --git a/README_zh_CN.md b/README_zh_CN.md index 12269c15..77a9115a 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -106,4 +106,4 @@ The current OneFLOW release has been coordinated by the OneFLOW International De 如果在编译和运行代码中遇到问题,可随时通过邮件联系。 -Copyright 2017-2024, He Xin, and the OneFLOW contributors. +Copyright 2017-2025, He Xin, and the OneFLOW contributors. diff --git a/codes/adt/include/AdtTree.h b/codes/adt/include/AdtTree.h index ebec76e6..16167ba9 100644 --- a/codes/adt/include/AdtTree.h +++ b/codes/adt/include/AdtTree.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/adt/src/AdtTree.hpp b/codes/adt/src/AdtTree.hpp index 66aba450..89219805 100644 --- a/codes/adt/src/AdtTree.hpp +++ b/codes/adt/src/AdtTree.hpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/array/include/HXArray.h b/codes/array/include/HXArray.h index 7e166115..c4706dce 100644 --- a/codes/array/include/HXArray.h +++ b/codes/array/include/HXArray.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/array/include/Marray.h b/codes/array/include/Marray.h index 99a552b0..c47b72e2 100644 --- a/codes/array/include/Marray.h +++ b/codes/array/include/Marray.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/array/src/Marray.cpp b/codes/array/src/Marray.cpp index 6ede6dad..48a6b430 100644 --- a/codes/array/src/Marray.cpp +++ b/codes/array/src/Marray.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/Constant.h b/codes/basic/include/Constant.h index 3f1908b3..7c5d11ab 100644 --- a/codes/basic/include/Constant.h +++ b/codes/basic/include/Constant.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXDefine.h b/codes/basic/include/HXDefine.h index d9dcf245..e1058aab 100644 --- a/codes/basic/include/HXDefine.h +++ b/codes/basic/include/HXDefine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXMid.h b/codes/basic/include/HXMid.h index fb0c7777..0efa7704 100644 --- a/codes/basic/include/HXMid.h +++ b/codes/basic/include/HXMid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXPointer.h b/codes/basic/include/HXPointer.h index 69a8df89..b54f97c8 100644 --- a/codes/basic/include/HXPointer.h +++ b/codes/basic/include/HXPointer.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXSort.h b/codes/basic/include/HXSort.h index b483416a..ddf25e4d 100644 --- a/codes/basic/include/HXSort.h +++ b/codes/basic/include/HXSort.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXStd.h b/codes/basic/include/HXStd.h index 03e041ff..1d15c062 100644 --- a/codes/basic/include/HXStd.h +++ b/codes/basic/include/HXStd.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXType.h b/codes/basic/include/HXType.h index 65a6b362..a73cfcc3 100644 --- a/codes/basic/include/HXType.h +++ b/codes/basic/include/HXType.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXTypeBasic.h b/codes/basic/include/HXTypeBasic.h index aaac1d81..9523e904 100644 --- a/codes/basic/include/HXTypeBasic.h +++ b/codes/basic/include/HXTypeBasic.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/include/HXVector.h b/codes/basic/include/HXVector.h index 906cb87e..dad9f8f1 100644 --- a/codes/basic/include/HXVector.h +++ b/codes/basic/include/HXVector.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/src/HXDefine.cpp b/codes/basic/src/HXDefine.cpp index 7a496d50..138e934e 100644 --- a/codes/basic/src/HXDefine.cpp +++ b/codes/basic/src/HXDefine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/basic/src/HXMid.cpp b/codes/basic/src/HXMid.cpp index fffc684a..ca9761b8 100644 --- a/codes/basic/src/HXMid.cpp +++ b/codes/basic/src/HXMid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBase.h b/codes/cgns/include/CgnsBase.h index 04216ed6..107e2c14 100644 --- a/codes/cgns/include/CgnsBase.h +++ b/codes/cgns/include/CgnsBase.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBaseUtil.h b/codes/cgns/include/CgnsBaseUtil.h index e599c62a..e2a5f6c8 100644 --- a/codes/cgns/include/CgnsBaseUtil.h +++ b/codes/cgns/include/CgnsBaseUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBc1to1.h b/codes/cgns/include/CgnsBc1to1.h index 3874ad85..8702bd86 100644 --- a/codes/cgns/include/CgnsBc1to1.h +++ b/codes/cgns/include/CgnsBc1to1.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBcBoco.h b/codes/cgns/include/CgnsBcBoco.h index ef9a59c8..e38b293a 100644 --- a/codes/cgns/include/CgnsBcBoco.h +++ b/codes/cgns/include/CgnsBcBoco.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBcConn.h b/codes/cgns/include/CgnsBcConn.h index 968f7ec2..8ce5048c 100644 --- a/codes/cgns/include/CgnsBcConn.h +++ b/codes/cgns/include/CgnsBcConn.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsBcLink.h b/codes/cgns/include/CgnsBcLink.h index 41d1ad0d..f88384fe 100644 --- a/codes/cgns/include/CgnsBcLink.h +++ b/codes/cgns/include/CgnsBcLink.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsCoor.h b/codes/cgns/include/CgnsCoor.h index 5079b353..f440858c 100644 --- a/codes/cgns/include/CgnsCoor.h +++ b/codes/cgns/include/CgnsCoor.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsFactory.h b/codes/cgns/include/CgnsFactory.h index 8ede8f49..42023824 100644 --- a/codes/cgns/include/CgnsFactory.h +++ b/codes/cgns/include/CgnsFactory.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsFamilyBc.h b/codes/cgns/include/CgnsFamilyBc.h index ccb19876..4b9b267d 100644 --- a/codes/cgns/include/CgnsFamilyBc.h +++ b/codes/cgns/include/CgnsFamilyBc.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsFile.h b/codes/cgns/include/CgnsFile.h index 7f1778ab..77a425c7 100644 --- a/codes/cgns/include/CgnsFile.h +++ b/codes/cgns/include/CgnsFile.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsGlobal.h b/codes/cgns/include/CgnsGlobal.h index 8d6303ed..9ec54e4f 100644 --- a/codes/cgns/include/CgnsGlobal.h +++ b/codes/cgns/include/CgnsGlobal.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsPeriod.h b/codes/cgns/include/CgnsPeriod.h index cb0821a1..2bdf89fb 100644 --- a/codes/cgns/include/CgnsPeriod.h +++ b/codes/cgns/include/CgnsPeriod.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsSection.h b/codes/cgns/include/CgnsSection.h index 0a9edb13..bc9c4352 100644 --- a/codes/cgns/include/CgnsSection.h +++ b/codes/cgns/include/CgnsSection.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsVariable.h b/codes/cgns/include/CgnsVariable.h index 2655add2..6ffee78e 100644 --- a/codes/cgns/include/CgnsVariable.h +++ b/codes/cgns/include/CgnsVariable.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbase.h b/codes/cgns/include/CgnsZbase.h index 40b5c1b7..e283e31b 100644 --- a/codes/cgns/include/CgnsZbase.h +++ b/codes/cgns/include/CgnsZbase.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbaseUtil.h b/codes/cgns/include/CgnsZbaseUtil.h index b5a81ca1..0355e880 100644 --- a/codes/cgns/include/CgnsZbaseUtil.h +++ b/codes/cgns/include/CgnsZbaseUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbc.h b/codes/cgns/include/CgnsZbc.h index f6f9ef2f..880604b6 100644 --- a/codes/cgns/include/CgnsZbc.h +++ b/codes/cgns/include/CgnsZbc.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbc1to1.h b/codes/cgns/include/CgnsZbc1to1.h index 6d98e936..e1331989 100644 --- a/codes/cgns/include/CgnsZbc1to1.h +++ b/codes/cgns/include/CgnsZbc1to1.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbcBoco.h b/codes/cgns/include/CgnsZbcBoco.h index e1dadc98..30ec9c40 100644 --- a/codes/cgns/include/CgnsZbcBoco.h +++ b/codes/cgns/include/CgnsZbcBoco.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZbcConn.h b/codes/cgns/include/CgnsZbcConn.h index 2f3cd749..7dd9e8a2 100644 --- a/codes/cgns/include/CgnsZbcConn.h +++ b/codes/cgns/include/CgnsZbcConn.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZone.h b/codes/cgns/include/CgnsZone.h index 62d68a11..f658aeaa 100644 --- a/codes/cgns/include/CgnsZone.h +++ b/codes/cgns/include/CgnsZone.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZoneUtil.h b/codes/cgns/include/CgnsZoneUtil.h index 32204ac8..41236b35 100644 --- a/codes/cgns/include/CgnsZoneUtil.h +++ b/codes/cgns/include/CgnsZoneUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/CgnsZsection.h b/codes/cgns/include/CgnsZsection.h index 8a75a66f..1d855504 100644 --- a/codes/cgns/include/CgnsZsection.h +++ b/codes/cgns/include/CgnsZsection.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/include/HXCgns.h b/codes/cgns/include/HXCgns.h index ea2df516..ca4d7477 100644 --- a/codes/cgns/include/HXCgns.h +++ b/codes/cgns/include/HXCgns.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBase.cpp b/codes/cgns/src/CgnsBase.cpp index 0f3420b5..c4620fc4 100644 --- a/codes/cgns/src/CgnsBase.cpp +++ b/codes/cgns/src/CgnsBase.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBaseUtil.cpp b/codes/cgns/src/CgnsBaseUtil.cpp index 8cc400dd..80fe7667 100644 --- a/codes/cgns/src/CgnsBaseUtil.cpp +++ b/codes/cgns/src/CgnsBaseUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBc1to1.cpp b/codes/cgns/src/CgnsBc1to1.cpp index a13e5afc..1ba91573 100644 --- a/codes/cgns/src/CgnsBc1to1.cpp +++ b/codes/cgns/src/CgnsBc1to1.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBcBoco.cpp b/codes/cgns/src/CgnsBcBoco.cpp index 991dbe2f..6405e294 100644 --- a/codes/cgns/src/CgnsBcBoco.cpp +++ b/codes/cgns/src/CgnsBcBoco.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBcConn.cpp b/codes/cgns/src/CgnsBcConn.cpp index ef8d82a9..6928905e 100644 --- a/codes/cgns/src/CgnsBcConn.cpp +++ b/codes/cgns/src/CgnsBcConn.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsBcLink.cpp b/codes/cgns/src/CgnsBcLink.cpp index b3417290..d84245d7 100644 --- a/codes/cgns/src/CgnsBcLink.cpp +++ b/codes/cgns/src/CgnsBcLink.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsCoor.cpp b/codes/cgns/src/CgnsCoor.cpp index 46900727..2d448b96 100644 --- a/codes/cgns/src/CgnsCoor.cpp +++ b/codes/cgns/src/CgnsCoor.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsFactory.cpp b/codes/cgns/src/CgnsFactory.cpp index bcdfaeaf..6927feca 100644 --- a/codes/cgns/src/CgnsFactory.cpp +++ b/codes/cgns/src/CgnsFactory.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsFamilyBc.cpp b/codes/cgns/src/CgnsFamilyBc.cpp index 6c88a363..975a49b3 100644 --- a/codes/cgns/src/CgnsFamilyBc.cpp +++ b/codes/cgns/src/CgnsFamilyBc.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsFile.cpp b/codes/cgns/src/CgnsFile.cpp index 5e714cfd..4643e26f 100644 --- a/codes/cgns/src/CgnsFile.cpp +++ b/codes/cgns/src/CgnsFile.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsGlobal.cpp b/codes/cgns/src/CgnsGlobal.cpp index 4896ab59..89e26ddc 100644 --- a/codes/cgns/src/CgnsGlobal.cpp +++ b/codes/cgns/src/CgnsGlobal.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsPeriod.cpp b/codes/cgns/src/CgnsPeriod.cpp index 96570208..23603a79 100644 --- a/codes/cgns/src/CgnsPeriod.cpp +++ b/codes/cgns/src/CgnsPeriod.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsSection.cpp b/codes/cgns/src/CgnsSection.cpp index 4e6ebe3d..9b8e7705 100644 --- a/codes/cgns/src/CgnsSection.cpp +++ b/codes/cgns/src/CgnsSection.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsVariable.cpp b/codes/cgns/src/CgnsVariable.cpp index a43925c1..c5711946 100644 --- a/codes/cgns/src/CgnsVariable.cpp +++ b/codes/cgns/src/CgnsVariable.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbase.cpp b/codes/cgns/src/CgnsZbase.cpp index cb8add62..e8c7fbde 100644 --- a/codes/cgns/src/CgnsZbase.cpp +++ b/codes/cgns/src/CgnsZbase.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbaseUtil.cpp b/codes/cgns/src/CgnsZbaseUtil.cpp index 1c5e669f..fe771ce2 100644 --- a/codes/cgns/src/CgnsZbaseUtil.cpp +++ b/codes/cgns/src/CgnsZbaseUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbc.cpp b/codes/cgns/src/CgnsZbc.cpp index f1f06680..1f57aae7 100644 --- a/codes/cgns/src/CgnsZbc.cpp +++ b/codes/cgns/src/CgnsZbc.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbc1to1.cpp b/codes/cgns/src/CgnsZbc1to1.cpp index f7ba2b97..9d8ebbf8 100644 --- a/codes/cgns/src/CgnsZbc1to1.cpp +++ b/codes/cgns/src/CgnsZbc1to1.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbcBoco.cpp b/codes/cgns/src/CgnsZbcBoco.cpp index edfca44a..83f7b183 100644 --- a/codes/cgns/src/CgnsZbcBoco.cpp +++ b/codes/cgns/src/CgnsZbcBoco.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZbcConn.cpp b/codes/cgns/src/CgnsZbcConn.cpp index dd459a0f..061b08eb 100644 --- a/codes/cgns/src/CgnsZbcConn.cpp +++ b/codes/cgns/src/CgnsZbcConn.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZone.cpp b/codes/cgns/src/CgnsZone.cpp index fbde18c0..e1c5ed7a 100644 --- a/codes/cgns/src/CgnsZone.cpp +++ b/codes/cgns/src/CgnsZone.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZoneUtil.cpp b/codes/cgns/src/CgnsZoneUtil.cpp index 38225d51..a85b75cb 100644 --- a/codes/cgns/src/CgnsZoneUtil.cpp +++ b/codes/cgns/src/CgnsZoneUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/CgnsZsection.cpp b/codes/cgns/src/CgnsZsection.cpp index 35bf3ad5..f60e2281 100644 --- a/codes/cgns/src/CgnsZsection.cpp +++ b/codes/cgns/src/CgnsZsection.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cgns/src/HXCgns.cpp b/codes/cgns/src/HXCgns.cpp index 26a66e4e..d06aa76f 100644 --- a/codes/cgns/src/HXCgns.cpp +++ b/codes/cgns/src/HXCgns.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/BlotterCurve.h b/codes/chemical/include/BlotterCurve.h index a6047aa6..d1f9dbe6 100644 --- a/codes/chemical/include/BlotterCurve.h +++ b/codes/chemical/include/BlotterCurve.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/Chemical.h b/codes/chemical/include/Chemical.h index 9da3effd..8a736847 100644 --- a/codes/chemical/include/Chemical.h +++ b/codes/chemical/include/Chemical.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/MolecularProperty.h b/codes/chemical/include/MolecularProperty.h index ad4ec024..042163a6 100644 --- a/codes/chemical/include/MolecularProperty.h +++ b/codes/chemical/include/MolecularProperty.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/ReactionRate.h b/codes/chemical/include/ReactionRate.h index 696e1515..c557c2d0 100644 --- a/codes/chemical/include/ReactionRate.h +++ b/codes/chemical/include/ReactionRate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/SchmidtNumber.h b/codes/chemical/include/SchmidtNumber.h index 28032b34..3e7c4dbe 100644 --- a/codes/chemical/include/SchmidtNumber.h +++ b/codes/chemical/include/SchmidtNumber.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/Stoichiometric.h b/codes/chemical/include/Stoichiometric.h index 56a2e6bd..53d39052 100644 --- a/codes/chemical/include/Stoichiometric.h +++ b/codes/chemical/include/Stoichiometric.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/include/Thermodynamic.h b/codes/chemical/include/Thermodynamic.h index 283e58a1..3716f3c4 100644 --- a/codes/chemical/include/Thermodynamic.h +++ b/codes/chemical/include/Thermodynamic.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/BlotterCurve.cpp b/codes/chemical/src/BlotterCurve.cpp index e7eb7ee1..ee74f99a 100644 --- a/codes/chemical/src/BlotterCurve.cpp +++ b/codes/chemical/src/BlotterCurve.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/Chemical.cpp b/codes/chemical/src/Chemical.cpp index 1e57ccc5..9b20eace 100644 --- a/codes/chemical/src/Chemical.cpp +++ b/codes/chemical/src/Chemical.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/MolecularProperty.cpp b/codes/chemical/src/MolecularProperty.cpp index 01b5958b..c58bf4ef 100644 --- a/codes/chemical/src/MolecularProperty.cpp +++ b/codes/chemical/src/MolecularProperty.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/ReactionRate.cpp b/codes/chemical/src/ReactionRate.cpp index 822825ed..65ea14ac 100644 --- a/codes/chemical/src/ReactionRate.cpp +++ b/codes/chemical/src/ReactionRate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/SchmidtNumber.cpp b/codes/chemical/src/SchmidtNumber.cpp index 9cc6f209..6b5a35cb 100644 --- a/codes/chemical/src/SchmidtNumber.cpp +++ b/codes/chemical/src/SchmidtNumber.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/Stoichiometric.cpp b/codes/chemical/src/Stoichiometric.cpp index be77cc4f..72a43c6a 100644 --- a/codes/chemical/src/Stoichiometric.cpp +++ b/codes/chemical/src/Stoichiometric.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/chemical/src/Thermodynamic.cpp b/codes/chemical/src/Thermodynamic.cpp index 967d39ae..581996e1 100644 --- a/codes/chemical/src/Thermodynamic.cpp +++ b/codes/chemical/src/Thermodynamic.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cuda/include/HybridParallel.h b/codes/cuda/include/HybridParallel.h index e1c90bbf..828073b1 100644 --- a/codes/cuda/include/HybridParallel.h +++ b/codes/cuda/include/HybridParallel.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/cuda/src/HybridParallel.cpp b/codes/cuda/src/HybridParallel.cpp index 3e70e601..6931dfcf 100644 --- a/codes/cuda/src/HybridParallel.cpp +++ b/codes/cuda/src/HybridParallel.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataBase.h b/codes/database/include/DataBase.h index bcb070cc..f1522b89 100644 --- a/codes/database/include/DataBase.h +++ b/codes/database/include/DataBase.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataBaseIO.h b/codes/database/include/DataBaseIO.h index 68d638b7..e622952a 100644 --- a/codes/database/include/DataBaseIO.h +++ b/codes/database/include/DataBaseIO.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataBaseType.h b/codes/database/include/DataBaseType.h index 672dd7da..81251482 100644 --- a/codes/database/include/DataBaseType.h +++ b/codes/database/include/DataBaseType.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataBook.h b/codes/database/include/DataBook.h index 26663fa4..87d0bdce 100644 --- a/codes/database/include/DataBook.h +++ b/codes/database/include/DataBook.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataField.h b/codes/database/include/DataField.h index e06599a8..51d3826d 100644 --- a/codes/database/include/DataField.h +++ b/codes/database/include/DataField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataObject.h b/codes/database/include/DataObject.h index 2774b450..58714394 100644 --- a/codes/database/include/DataObject.h +++ b/codes/database/include/DataObject.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataPage.h b/codes/database/include/DataPage.h index 992a3497..2d93fdd5 100644 --- a/codes/database/include/DataPage.h +++ b/codes/database/include/DataPage.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataPara.h b/codes/database/include/DataPara.h index fae64a26..e62b37b0 100644 --- a/codes/database/include/DataPara.h +++ b/codes/database/include/DataPara.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataPointer.h b/codes/database/include/DataPointer.h index c06410b6..41a1a7d9 100644 --- a/codes/database/include/DataPointer.h +++ b/codes/database/include/DataPointer.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/include/DataStorage.h b/codes/database/include/DataStorage.h index 705cf0c9..77e381f3 100644 --- a/codes/database/include/DataStorage.h +++ b/codes/database/include/DataStorage.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataBase.cpp b/codes/database/src/DataBase.cpp index de020cbd..5274b2b3 100644 --- a/codes/database/src/DataBase.cpp +++ b/codes/database/src/DataBase.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataBaseIO.cpp b/codes/database/src/DataBaseIO.cpp index 1a18f5a4..a78051c8 100644 --- a/codes/database/src/DataBaseIO.cpp +++ b/codes/database/src/DataBaseIO.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataBaseType.cpp b/codes/database/src/DataBaseType.cpp index c46ae3d6..f13397d4 100644 --- a/codes/database/src/DataBaseType.cpp +++ b/codes/database/src/DataBaseType.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataBook.cpp b/codes/database/src/DataBook.cpp index 0eb11f92..16ed3e99 100644 --- a/codes/database/src/DataBook.cpp +++ b/codes/database/src/DataBook.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataField.cpp b/codes/database/src/DataField.cpp index b3fd48b3..f3d687ab 100644 --- a/codes/database/src/DataField.cpp +++ b/codes/database/src/DataField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataPage.cpp b/codes/database/src/DataPage.cpp index f5e4b1e1..bc0c3e59 100644 --- a/codes/database/src/DataPage.cpp +++ b/codes/database/src/DataPage.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataPara.cpp b/codes/database/src/DataPara.cpp index 79124dca..09b8e30b 100644 --- a/codes/database/src/DataPara.cpp +++ b/codes/database/src/DataPara.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/database/src/DataStorage.cpp b/codes/database/src/DataStorage.cpp index e2585d1f..18e65b8a 100644 --- a/codes/database/src/DataStorage.cpp +++ b/codes/database/src/DataStorage.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/include/AeroForce.h b/codes/force/include/AeroForce.h index e4ad4b56..84d8584d 100644 --- a/codes/force/include/AeroForce.h +++ b/codes/force/include/AeroForce.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/include/AeroForceTask.h b/codes/force/include/AeroForceTask.h index 55eede15..7544165b 100644 --- a/codes/force/include/AeroForceTask.h +++ b/codes/force/include/AeroForceTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/include/AeroForceTaskReg.h b/codes/force/include/AeroForceTaskReg.h index a1d50d5f..396082f8 100644 --- a/codes/force/include/AeroForceTaskReg.h +++ b/codes/force/include/AeroForceTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/include/Force.h b/codes/force/include/Force.h index df5b1dfb..a5a9ae4d 100644 --- a/codes/force/include/Force.h +++ b/codes/force/include/Force.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/src/AeroForce.cpp b/codes/force/src/AeroForce.cpp index bb064051..a0f3e06d 100644 --- a/codes/force/src/AeroForce.cpp +++ b/codes/force/src/AeroForce.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/src/AeroForceTask.cpp b/codes/force/src/AeroForceTask.cpp index 1d4683d4..a9cd3d7d 100644 --- a/codes/force/src/AeroForceTask.cpp +++ b/codes/force/src/AeroForceTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/src/AeroForceTaskReg.cpp b/codes/force/src/AeroForceTaskReg.cpp index 06fd6a46..3dbaf6d0 100644 --- a/codes/force/src/AeroForceTaskReg.cpp +++ b/codes/force/src/AeroForceTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/force/src/Force.cpp b/codes/force/src/Force.cpp index 4965718b..3c2f2bd9 100644 --- a/codes/force/src/Force.cpp +++ b/codes/force/src/Force.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/BcRecord.h b/codes/geometry/include/BcRecord.h index 69b64ff3..47b05771 100644 --- a/codes/geometry/include/BcRecord.h +++ b/codes/geometry/include/BcRecord.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Boundary.h b/codes/geometry/include/Boundary.h index b9ade708..259e437f 100644 --- a/codes/geometry/include/Boundary.h +++ b/codes/geometry/include/Boundary.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/CalcGrid.h b/codes/geometry/include/CalcGrid.h index f51c0b0b..17195f0a 100644 --- a/codes/geometry/include/CalcGrid.h +++ b/codes/geometry/include/CalcGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/CellMesh.h b/codes/geometry/include/CellMesh.h index 1f6ab6ba..405b6fa9 100644 --- a/codes/geometry/include/CellMesh.h +++ b/codes/geometry/include/CellMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/CellTopo.h b/codes/geometry/include/CellTopo.h index 9c4e8d63..a9fb501d 100644 --- a/codes/geometry/include/CellTopo.h +++ b/codes/geometry/include/CellTopo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/DomainInp.h b/codes/geometry/include/DomainInp.h index 4ec78fce..a4fceb01 100644 --- a/codes/geometry/include/DomainInp.h +++ b/codes/geometry/include/DomainInp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/ElemFeature.h b/codes/geometry/include/ElemFeature.h index 53c7f066..894594d9 100644 --- a/codes/geometry/include/ElemFeature.h +++ b/codes/geometry/include/ElemFeature.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/ElementHome.h b/codes/geometry/include/ElementHome.h index da7ffa0e..006f0d75 100644 --- a/codes/geometry/include/ElementHome.h +++ b/codes/geometry/include/ElementHome.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/FaceMesh.h b/codes/geometry/include/FaceMesh.h index f9f5ea96..d486a73b 100644 --- a/codes/geometry/include/FaceMesh.h +++ b/codes/geometry/include/FaceMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/FaceSearch.h b/codes/geometry/include/FaceSearch.h index dd900d29..b8c0b147 100644 --- a/codes/geometry/include/FaceSearch.h +++ b/codes/geometry/include/FaceSearch.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/FaceSolver.h b/codes/geometry/include/FaceSolver.h index b91cce9b..1d5aa399 100644 --- a/codes/geometry/include/FaceSolver.h +++ b/codes/geometry/include/FaceSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/FaceTopo.h b/codes/geometry/include/FaceTopo.h index 26d89bc8..0d46200c 100644 --- a/codes/geometry/include/FaceTopo.h +++ b/codes/geometry/include/FaceTopo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Grid.h b/codes/geometry/include/Grid.h index 7dca4798..a5da1e01 100644 --- a/codes/geometry/include/Grid.h +++ b/codes/geometry/include/Grid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridDef.h b/codes/geometry/include/GridDef.h index fb90b158..9547ef44 100644 --- a/codes/geometry/include/GridDef.h +++ b/codes/geometry/include/GridDef.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridElem.h b/codes/geometry/include/GridElem.h index 4bb01ea0..7594e8dc 100644 --- a/codes/geometry/include/GridElem.h +++ b/codes/geometry/include/GridElem.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridFactory.h b/codes/geometry/include/GridFactory.h index 56a25123..74f1e04e 100644 --- a/codes/geometry/include/GridFactory.h +++ b/codes/geometry/include/GridFactory.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridMediator.h b/codes/geometry/include/GridMediator.h index f527c399..ff91d57f 100644 --- a/codes/geometry/include/GridMediator.h +++ b/codes/geometry/include/GridMediator.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridPara.h b/codes/geometry/include/GridPara.h index 6852d3d4..c6cb745d 100644 --- a/codes/geometry/include/GridPara.h +++ b/codes/geometry/include/GridPara.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/GridTask.h b/codes/geometry/include/GridTask.h index fd61eea8..7a3f61da 100644 --- a/codes/geometry/include/GridTask.h +++ b/codes/geometry/include/GridTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/IFaceLink.h b/codes/geometry/include/IFaceLink.h index be78e33d..aeeb1d74 100644 --- a/codes/geometry/include/IFaceLink.h +++ b/codes/geometry/include/IFaceLink.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/InterFace.h b/codes/geometry/include/InterFace.h index 3bad3c02..e35a6db1 100644 --- a/codes/geometry/include/InterFace.h +++ b/codes/geometry/include/InterFace.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/NodeMesh.h b/codes/geometry/include/NodeMesh.h index 41465852..d32a810b 100644 --- a/codes/geometry/include/NodeMesh.h +++ b/codes/geometry/include/NodeMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Plot3D.h b/codes/geometry/include/Plot3D.h index 8962ecd7..cf4b5599 100644 --- a/codes/geometry/include/Plot3D.h +++ b/codes/geometry/include/Plot3D.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Point.h b/codes/geometry/include/Point.h index b3c2797e..42824b2f 100644 --- a/codes/geometry/include/Point.h +++ b/codes/geometry/include/Point.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/PointFactory.h b/codes/geometry/include/PointFactory.h index cb5e7953..f4be43db 100644 --- a/codes/geometry/include/PointFactory.h +++ b/codes/geometry/include/PointFactory.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/PointSearch.h b/codes/geometry/include/PointSearch.h index a54c58af..40b7eb5d 100644 --- a/codes/geometry/include/PointSearch.h +++ b/codes/geometry/include/PointSearch.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/SlipFace.h b/codes/geometry/include/SlipFace.h index 54a56d6f..73aca811 100644 --- a/codes/geometry/include/SlipFace.h +++ b/codes/geometry/include/SlipFace.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/StrGrid.h b/codes/geometry/include/StrGrid.h index ade86ddf..03e2e53c 100644 --- a/codes/geometry/include/StrGrid.h +++ b/codes/geometry/include/StrGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/StrRegion.h b/codes/geometry/include/StrRegion.h index a23d685e..947a693c 100644 --- a/codes/geometry/include/StrRegion.h +++ b/codes/geometry/include/StrRegion.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Su2Grid.h b/codes/geometry/include/Su2Grid.h index 13ebe051..2e15c81b 100644 --- a/codes/geometry/include/Su2Grid.h +++ b/codes/geometry/include/Su2Grid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/UnitElement.h b/codes/geometry/include/UnitElement.h index bc082a3f..d06f4d0a 100644 --- a/codes/geometry/include/UnitElement.h +++ b/codes/geometry/include/UnitElement.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/UnsGrid.h b/codes/geometry/include/UnsGrid.h index d2c40003..a2105419 100644 --- a/codes/geometry/include/UnsGrid.h +++ b/codes/geometry/include/UnsGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/Visual.h b/codes/geometry/include/Visual.h index 67cca21c..0b68841c 100644 --- a/codes/geometry/include/Visual.h +++ b/codes/geometry/include/Visual.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/include/WallDist.h b/codes/geometry/include/WallDist.h index f56ae7a8..3a19c9c8 100644 --- a/codes/geometry/include/WallDist.h +++ b/codes/geometry/include/WallDist.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/BcRecord.cpp b/codes/geometry/src/BcRecord.cpp index 38092d46..27baaa57 100644 --- a/codes/geometry/src/BcRecord.cpp +++ b/codes/geometry/src/BcRecord.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Boundary.cpp b/codes/geometry/src/Boundary.cpp index 179cf109..a293eded 100644 --- a/codes/geometry/src/Boundary.cpp +++ b/codes/geometry/src/Boundary.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/CalcGrid.cpp b/codes/geometry/src/CalcGrid.cpp index cbaf8780..4cd97144 100644 --- a/codes/geometry/src/CalcGrid.cpp +++ b/codes/geometry/src/CalcGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/CellMesh.cpp b/codes/geometry/src/CellMesh.cpp index a29151ae..3c327864 100644 --- a/codes/geometry/src/CellMesh.cpp +++ b/codes/geometry/src/CellMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/CellTopo.cpp b/codes/geometry/src/CellTopo.cpp index 1d8ab957..deca7073 100644 --- a/codes/geometry/src/CellTopo.cpp +++ b/codes/geometry/src/CellTopo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/DomainInp.cpp b/codes/geometry/src/DomainInp.cpp index f1a3380c..aa027508 100644 --- a/codes/geometry/src/DomainInp.cpp +++ b/codes/geometry/src/DomainInp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/ElemFeature.cpp b/codes/geometry/src/ElemFeature.cpp index 36b5e811..16d559f1 100644 --- a/codes/geometry/src/ElemFeature.cpp +++ b/codes/geometry/src/ElemFeature.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/ElementHome.cpp b/codes/geometry/src/ElementHome.cpp index 46247eb9..47786aa8 100644 --- a/codes/geometry/src/ElementHome.cpp +++ b/codes/geometry/src/ElementHome.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/FaceMesh.cpp b/codes/geometry/src/FaceMesh.cpp index 837bde47..a5649a3c 100644 --- a/codes/geometry/src/FaceMesh.cpp +++ b/codes/geometry/src/FaceMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/FaceSearch.cpp b/codes/geometry/src/FaceSearch.cpp index aa9d6bd4..a7e038f0 100644 --- a/codes/geometry/src/FaceSearch.cpp +++ b/codes/geometry/src/FaceSearch.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/FaceSolver.cpp b/codes/geometry/src/FaceSolver.cpp index 71f2c490..6a585ab7 100644 --- a/codes/geometry/src/FaceSolver.cpp +++ b/codes/geometry/src/FaceSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/FaceTopo.cpp b/codes/geometry/src/FaceTopo.cpp index e0b91c0e..d6c5c548 100644 --- a/codes/geometry/src/FaceTopo.cpp +++ b/codes/geometry/src/FaceTopo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Grid.cpp b/codes/geometry/src/Grid.cpp index 639de79d..9a106204 100644 --- a/codes/geometry/src/Grid.cpp +++ b/codes/geometry/src/Grid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridDef.cpp b/codes/geometry/src/GridDef.cpp index 599f59ff..95486404 100644 --- a/codes/geometry/src/GridDef.cpp +++ b/codes/geometry/src/GridDef.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridElem.cpp b/codes/geometry/src/GridElem.cpp index 138fae54..3a1e6a02 100644 --- a/codes/geometry/src/GridElem.cpp +++ b/codes/geometry/src/GridElem.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridFactory.cpp b/codes/geometry/src/GridFactory.cpp index 9215d1be..95245147 100644 --- a/codes/geometry/src/GridFactory.cpp +++ b/codes/geometry/src/GridFactory.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridMediator.cpp b/codes/geometry/src/GridMediator.cpp index 3122a61c..2da43e5c 100644 --- a/codes/geometry/src/GridMediator.cpp +++ b/codes/geometry/src/GridMediator.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridPara.cpp b/codes/geometry/src/GridPara.cpp index ed2b1cf9..28452172 100644 --- a/codes/geometry/src/GridPara.cpp +++ b/codes/geometry/src/GridPara.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/GridTask.cpp b/codes/geometry/src/GridTask.cpp index 6aee72b6..706cdaab 100644 --- a/codes/geometry/src/GridTask.cpp +++ b/codes/geometry/src/GridTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/IFaceLink.cpp b/codes/geometry/src/IFaceLink.cpp index 52b68147..c3ecc6d2 100644 --- a/codes/geometry/src/IFaceLink.cpp +++ b/codes/geometry/src/IFaceLink.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/InterFace.cpp b/codes/geometry/src/InterFace.cpp index 8496d9db..a19bc3a4 100644 --- a/codes/geometry/src/InterFace.cpp +++ b/codes/geometry/src/InterFace.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/NodeMesh.cpp b/codes/geometry/src/NodeMesh.cpp index 7e9f541a..1a09f710 100644 --- a/codes/geometry/src/NodeMesh.cpp +++ b/codes/geometry/src/NodeMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Plot3D.cpp b/codes/geometry/src/Plot3D.cpp index 5ceaea92..e6a56937 100644 --- a/codes/geometry/src/Plot3D.cpp +++ b/codes/geometry/src/Plot3D.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Point.hpp b/codes/geometry/src/Point.hpp index 72f30dc7..8883642f 100644 --- a/codes/geometry/src/Point.hpp +++ b/codes/geometry/src/Point.hpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/PointFactory.cpp b/codes/geometry/src/PointFactory.cpp index 037d7acc..6c87e3d6 100644 --- a/codes/geometry/src/PointFactory.cpp +++ b/codes/geometry/src/PointFactory.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/PointSearch.cpp b/codes/geometry/src/PointSearch.cpp index d28dc2c3..bc457810 100644 --- a/codes/geometry/src/PointSearch.cpp +++ b/codes/geometry/src/PointSearch.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/SlipFace.cpp b/codes/geometry/src/SlipFace.cpp index 75f29a1a..601e0a74 100644 --- a/codes/geometry/src/SlipFace.cpp +++ b/codes/geometry/src/SlipFace.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/StrGrid.cpp b/codes/geometry/src/StrGrid.cpp index 952c5878..971bf185 100644 --- a/codes/geometry/src/StrGrid.cpp +++ b/codes/geometry/src/StrGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/StrRegion.cpp b/codes/geometry/src/StrRegion.cpp index adcfd5e6..6e91b183 100644 --- a/codes/geometry/src/StrRegion.cpp +++ b/codes/geometry/src/StrRegion.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Su2Grid.cpp b/codes/geometry/src/Su2Grid.cpp index 4521eec0..d679e737 100644 --- a/codes/geometry/src/Su2Grid.cpp +++ b/codes/geometry/src/Su2Grid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/UnitElement.cpp b/codes/geometry/src/UnitElement.cpp index 5234df87..51070cc4 100644 --- a/codes/geometry/src/UnitElement.cpp +++ b/codes/geometry/src/UnitElement.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/UnsGrid.cpp b/codes/geometry/src/UnsGrid.cpp index 86733430..f91e69d5 100644 --- a/codes/geometry/src/UnsGrid.cpp +++ b/codes/geometry/src/UnsGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/Visual.cpp b/codes/geometry/src/Visual.cpp index 1f728f88..0fcecb2f 100644 --- a/codes/geometry/src/Visual.cpp +++ b/codes/geometry/src/Visual.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/geometry/src/WallDist.cpp b/codes/geometry/src/WallDist.cpp index 3e91cf8e..8ad3df7f 100644 --- a/codes/geometry/src/WallDist.cpp +++ b/codes/geometry/src/WallDist.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/Com.h b/codes/global/include/Com.h index c54eaf47..d1f169d6 100644 --- a/codes/global/include/Com.h +++ b/codes/global/include/Com.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/Ctrl.h b/codes/global/include/Ctrl.h index ab2903f0..910839b4 100644 --- a/codes/global/include/Ctrl.h +++ b/codes/global/include/Ctrl.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/Dimension.h b/codes/global/include/Dimension.h index bd5763ed..389c9a7a 100644 --- a/codes/global/include/Dimension.h +++ b/codes/global/include/Dimension.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/DimensionImp.h b/codes/global/include/DimensionImp.h index a9612645..d3381b8c 100644 --- a/codes/global/include/DimensionImp.h +++ b/codes/global/include/DimensionImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FieldAlloc.h b/codes/global/include/FieldAlloc.h index f08426e7..af490e08 100644 --- a/codes/global/include/FieldAlloc.h +++ b/codes/global/include/FieldAlloc.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FieldBase.h b/codes/global/include/FieldBase.h index cbc3971e..1b55fa0b 100644 --- a/codes/global/include/FieldBase.h +++ b/codes/global/include/FieldBase.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FieldImp.h b/codes/global/include/FieldImp.h index 6d30d388..46483763 100644 --- a/codes/global/include/FieldImp.h +++ b/codes/global/include/FieldImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FieldRecord.h b/codes/global/include/FieldRecord.h index 79bcd9b0..eb4370c1 100644 --- a/codes/global/include/FieldRecord.h +++ b/codes/global/include/FieldRecord.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FieldSimu.h b/codes/global/include/FieldSimu.h index 08498f86..dccb80df 100644 --- a/codes/global/include/FieldSimu.h +++ b/codes/global/include/FieldSimu.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/FileMap.h b/codes/global/include/FileMap.h index 1a31ea5b..3ac27dfc 100644 --- a/codes/global/include/FileMap.h +++ b/codes/global/include/FileMap.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/Iteration.h b/codes/global/include/Iteration.h index b3eacdf4..213119b2 100644 --- a/codes/global/include/Iteration.h +++ b/codes/global/include/Iteration.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/SimuDef.h b/codes/global/include/SimuDef.h index 47461c7d..2fa3cf24 100644 --- a/codes/global/include/SimuDef.h +++ b/codes/global/include/SimuDef.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/SolverDef.h b/codes/global/include/SolverDef.h index 1988c040..19c6d2d3 100644 --- a/codes/global/include/SolverDef.h +++ b/codes/global/include/SolverDef.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/SolverName.h b/codes/global/include/SolverName.h index 0b8810c6..95df20d6 100644 --- a/codes/global/include/SolverName.h +++ b/codes/global/include/SolverName.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/SolverRegister.h b/codes/global/include/SolverRegister.h index 9e607475..812cd8a3 100644 --- a/codes/global/include/SolverRegister.h +++ b/codes/global/include/SolverRegister.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/SolverTaskReg.h b/codes/global/include/SolverTaskReg.h index 04ae7b97..22febf6a 100644 --- a/codes/global/include/SolverTaskReg.h +++ b/codes/global/include/SolverTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/System.h b/codes/global/include/System.h index cf5901d5..45407aab 100644 --- a/codes/global/include/System.h +++ b/codes/global/include/System.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/include/Tolerence.h b/codes/global/include/Tolerence.h index c1d5f22b..42a01000 100644 --- a/codes/global/include/Tolerence.h +++ b/codes/global/include/Tolerence.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/Com.cpp b/codes/global/src/Com.cpp index 8721c9d4..af20592d 100644 --- a/codes/global/src/Com.cpp +++ b/codes/global/src/Com.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/Ctrl.cpp b/codes/global/src/Ctrl.cpp index 45c35be4..803132a0 100644 --- a/codes/global/src/Ctrl.cpp +++ b/codes/global/src/Ctrl.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/Dimension.cpp b/codes/global/src/Dimension.cpp index bf1d9cfd..29cc0d83 100644 --- a/codes/global/src/Dimension.cpp +++ b/codes/global/src/Dimension.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/DimensionImp.cpp b/codes/global/src/DimensionImp.cpp index ccd2069a..599d051d 100644 --- a/codes/global/src/DimensionImp.cpp +++ b/codes/global/src/DimensionImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FieldAlloc.cpp b/codes/global/src/FieldAlloc.cpp index 68a600d8..1f706e4a 100644 --- a/codes/global/src/FieldAlloc.cpp +++ b/codes/global/src/FieldAlloc.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FieldBase.cpp b/codes/global/src/FieldBase.cpp index 574a38e5..7bf47e49 100644 --- a/codes/global/src/FieldBase.cpp +++ b/codes/global/src/FieldBase.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FieldImp.cpp b/codes/global/src/FieldImp.cpp index eda7513e..a2b9badf 100644 --- a/codes/global/src/FieldImp.cpp +++ b/codes/global/src/FieldImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FieldRecord.cpp b/codes/global/src/FieldRecord.cpp index 1338405f..10b869e5 100644 --- a/codes/global/src/FieldRecord.cpp +++ b/codes/global/src/FieldRecord.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FieldSimu.cpp b/codes/global/src/FieldSimu.cpp index 8b1e6a12..f905467b 100644 --- a/codes/global/src/FieldSimu.cpp +++ b/codes/global/src/FieldSimu.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/FileMap.cpp b/codes/global/src/FileMap.cpp index 73b4cfff..2a0d30f5 100644 --- a/codes/global/src/FileMap.cpp +++ b/codes/global/src/FileMap.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/Interation.cpp b/codes/global/src/Interation.cpp index 8d66ccf4..64dd8e0b 100644 --- a/codes/global/src/Interation.cpp +++ b/codes/global/src/Interation.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/SimuDef.cpp b/codes/global/src/SimuDef.cpp index 098ffbfa..feea3030 100644 --- a/codes/global/src/SimuDef.cpp +++ b/codes/global/src/SimuDef.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/SolverDef.cpp b/codes/global/src/SolverDef.cpp index 21c43d9e..669dd10e 100644 --- a/codes/global/src/SolverDef.cpp +++ b/codes/global/src/SolverDef.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/SolverName.cpp b/codes/global/src/SolverName.cpp index 61e3ff37..b75bbd75 100644 --- a/codes/global/src/SolverName.cpp +++ b/codes/global/src/SolverName.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/SolverRegister.cpp b/codes/global/src/SolverRegister.cpp index 69db9684..01497f7e 100644 --- a/codes/global/src/SolverRegister.cpp +++ b/codes/global/src/SolverRegister.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/SolverTaskReg.cpp b/codes/global/src/SolverTaskReg.cpp index a57bee8c..ee3d5729 100644 --- a/codes/global/src/SolverTaskReg.cpp +++ b/codes/global/src/SolverTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/System.cpp b/codes/global/src/System.cpp index 2e1ab6d5..9b32374b 100644 --- a/codes/global/src/System.cpp +++ b/codes/global/src/System.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/global/src/Tolerence.cpp b/codes/global/src/Tolerence.cpp index 4c7b3c72..1dd8baa7 100644 --- a/codes/global/src/Tolerence.cpp +++ b/codes/global/src/Tolerence.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/grad/include/Grad.h b/codes/grad/include/Grad.h index 6e1ef562..2d7fbe1d 100644 --- a/codes/grad/include/Grad.h +++ b/codes/grad/include/Grad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/grad/src/Grad.cpp b/codes/grad/src/Grad.cpp index 5a99161f..aca3d4da 100644 --- a/codes/grad/src/Grad.cpp +++ b/codes/grad/src/Grad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/implicit/include/ImplicitTaskReg.h b/codes/implicit/include/ImplicitTaskReg.h index 8ec21649..7acade1a 100644 --- a/codes/implicit/include/ImplicitTaskReg.h +++ b/codes/implicit/include/ImplicitTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/implicit/include/Lusgs.h b/codes/implicit/include/Lusgs.h index f49464bb..a914a014 100644 --- a/codes/implicit/include/Lusgs.h +++ b/codes/implicit/include/Lusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/implicit/src/ImplicitTaskReg.cpp b/codes/implicit/src/ImplicitTaskReg.cpp index 0db14f35..1e6a73a1 100644 --- a/codes/implicit/src/ImplicitTaskReg.cpp +++ b/codes/implicit/src/ImplicitTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/implicit/src/Lusgs.cpp b/codes/implicit/src/Lusgs.cpp index f8c917f1..f972f9b3 100644 --- a/codes/implicit/src/Lusgs.cpp +++ b/codes/implicit/src/Lusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsBcSolver.h b/codes/ins/include/INsBcSolver.h index 375019e0..964bc38b 100644 --- a/codes/ins/include/INsBcSolver.h +++ b/codes/ins/include/INsBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsCom.h b/codes/ins/include/INsCom.h index 6b056ad8..e6e0740c 100644 --- a/codes/ins/include/INsCom.h +++ b/codes/ins/include/INsCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsCtrl.h b/codes/ins/include/INsCtrl.h index 2c798ae5..89bb9968 100644 --- a/codes/ins/include/INsCtrl.h +++ b/codes/ins/include/INsCtrl.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsIdx.h b/codes/ins/include/INsIdx.h index 1a7ffd38..273b1fd8 100644 --- a/codes/ins/include/INsIdx.h +++ b/codes/ins/include/INsIdx.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsInvterm.h b/codes/ins/include/INsInvterm.h index 892eae0e..fedd2828 100644 --- a/codes/ins/include/INsInvterm.h +++ b/codes/ins/include/INsInvterm.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsLusgs.h b/codes/ins/include/INsLusgs.h index b69177d5..cf9dabe1 100644 --- a/codes/ins/include/INsLusgs.h +++ b/codes/ins/include/INsLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsRestart.h b/codes/ins/include/INsRestart.h index 9292d2a1..042d994d 100644 --- a/codes/ins/include/INsRestart.h +++ b/codes/ins/include/INsRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsRhs.h b/codes/ins/include/INsRhs.h index 5fd442d1..a02e0599 100644 --- a/codes/ins/include/INsRhs.h +++ b/codes/ins/include/INsRhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsSolver.h b/codes/ins/include/INsSolver.h index 04a37cbb..60994022 100644 --- a/codes/ins/include/INsSolver.h +++ b/codes/ins/include/INsSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsSolverImp.h b/codes/ins/include/INsSolverImp.h index e7735f5a..20da1d8a 100644 --- a/codes/ins/include/INsSolverImp.h +++ b/codes/ins/include/INsSolverImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsSpectrum.h b/codes/ins/include/INsSpectrum.h index 4bb644a7..27865753 100644 --- a/codes/ins/include/INsSpectrum.h +++ b/codes/ins/include/INsSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsUnsteady.h b/codes/ins/include/INsUnsteady.h index 6d995898..179001c2 100644 --- a/codes/ins/include/INsUnsteady.h +++ b/codes/ins/include/INsUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsUpdate.h b/codes/ins/include/INsUpdate.h index ef9e8791..83097ca8 100644 --- a/codes/ins/include/INsUpdate.h +++ b/codes/ins/include/INsUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/include/INsVisterm.h b/codes/ins/include/INsVisterm.h index ecb00698..05d5eabf 100644 --- a/codes/ins/include/INsVisterm.h +++ b/codes/ins/include/INsVisterm.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsBcSolver.cpp b/codes/ins/src/INsBcSolver.cpp index 45b52092..6743a532 100644 --- a/codes/ins/src/INsBcSolver.cpp +++ b/codes/ins/src/INsBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsCom.cpp b/codes/ins/src/INsCom.cpp index d2ffc4e6..3cde5afc 100644 --- a/codes/ins/src/INsCom.cpp +++ b/codes/ins/src/INsCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsCtrl.cpp b/codes/ins/src/INsCtrl.cpp index 5cd11780..374127b6 100644 --- a/codes/ins/src/INsCtrl.cpp +++ b/codes/ins/src/INsCtrl.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsInvterm.cpp b/codes/ins/src/INsInvterm.cpp index f36456db..1bea1af7 100644 --- a/codes/ins/src/INsInvterm.cpp +++ b/codes/ins/src/INsInvterm.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsLusgs.cpp b/codes/ins/src/INsLusgs.cpp index 04461d83..92fec9f2 100644 --- a/codes/ins/src/INsLusgs.cpp +++ b/codes/ins/src/INsLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsRestart.cpp b/codes/ins/src/INsRestart.cpp index 632f8958..df7cfa4a 100644 --- a/codes/ins/src/INsRestart.cpp +++ b/codes/ins/src/INsRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsRhs.cpp b/codes/ins/src/INsRhs.cpp index 18f00d88..a211ae49 100644 --- a/codes/ins/src/INsRhs.cpp +++ b/codes/ins/src/INsRhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsSolver.cpp b/codes/ins/src/INsSolver.cpp index 2ca710bb..197c15f4 100644 --- a/codes/ins/src/INsSolver.cpp +++ b/codes/ins/src/INsSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsSolverImp.cpp b/codes/ins/src/INsSolverImp.cpp index 196fe723..35cc079f 100644 --- a/codes/ins/src/INsSolverImp.cpp +++ b/codes/ins/src/INsSolverImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsSpectrum.cpp b/codes/ins/src/INsSpectrum.cpp index 6697bbe4..e3c53e7e 100644 --- a/codes/ins/src/INsSpectrum.cpp +++ b/codes/ins/src/INsSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsUnsteady.cpp b/codes/ins/src/INsUnsteady.cpp index 2cdb6af9..b08745e8 100644 --- a/codes/ins/src/INsUnsteady.cpp +++ b/codes/ins/src/INsUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsUpdate.cpp b/codes/ins/src/INsUpdate.cpp index 0fdc75d6..f6465061 100644 --- a/codes/ins/src/INsUpdate.cpp +++ b/codes/ins/src/INsUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ins/src/INsVisterm.cpp b/codes/ins/src/INsVisterm.cpp index 52c66352..4f1ea8e6 100644 --- a/codes/ins/src/INsVisterm.cpp +++ b/codes/ins/src/INsVisterm.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/interface/include/InterField.h b/codes/interface/include/InterField.h index dd912600..6933a6f4 100644 --- a/codes/interface/include/InterField.h +++ b/codes/interface/include/InterField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/interface/include/InterfaceTaskReg.h b/codes/interface/include/InterfaceTaskReg.h index 83509d5a..7d9c9b17 100644 --- a/codes/interface/include/InterfaceTaskReg.h +++ b/codes/interface/include/InterfaceTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/interface/src/InterField.cpp b/codes/interface/src/InterField.cpp index cd297ca1..df2b2554 100644 --- a/codes/interface/src/InterField.cpp +++ b/codes/interface/src/InterField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/interface/src/InterfaceTaskReg.cpp b/codes/interface/src/InterfaceTaskReg.cpp index 19090079..182083a7 100644 --- a/codes/interface/src/InterfaceTaskReg.cpp +++ b/codes/interface/src/InterfaceTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/CommentLine.h b/codes/io/include/CommentLine.h index 2f54c33e..272ef3c4 100644 --- a/codes/io/include/CommentLine.h +++ b/codes/io/include/CommentLine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/FileIO.h b/codes/io/include/FileIO.h index 4e40c95c..649a40f0 100644 --- a/codes/io/include/FileIO.h +++ b/codes/io/include/FileIO.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/FileO.h b/codes/io/include/FileO.h index 10071c01..2dc3d586 100644 --- a/codes/io/include/FileO.h +++ b/codes/io/include/FileO.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/LogFile.h b/codes/io/include/LogFile.h index aacc7170..4c109d52 100644 --- a/codes/io/include/LogFile.h +++ b/codes/io/include/LogFile.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/PIO.h b/codes/io/include/PIO.h index 1bbd5688..e89d58ef 100644 --- a/codes/io/include/PIO.h +++ b/codes/io/include/PIO.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/ParaFile.h b/codes/io/include/ParaFile.h index 6910720e..0660808b 100644 --- a/codes/io/include/ParaFile.h +++ b/codes/io/include/ParaFile.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/StrUtil.h b/codes/io/include/StrUtil.h index 807bcffa..a13e0bfa 100644 --- a/codes/io/include/StrUtil.h +++ b/codes/io/include/StrUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/include/Word.h b/codes/io/include/Word.h index bd560596..3b167bad 100644 --- a/codes/io/include/Word.h +++ b/codes/io/include/Word.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/CommentLine.cpp b/codes/io/src/CommentLine.cpp index 575156a3..ba61e704 100644 --- a/codes/io/src/CommentLine.cpp +++ b/codes/io/src/CommentLine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/FileIO.cpp b/codes/io/src/FileIO.cpp index c4e6f566..2de10417 100644 --- a/codes/io/src/FileIO.cpp +++ b/codes/io/src/FileIO.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/FileO.cpp b/codes/io/src/FileO.cpp index 5565eda8..f61c5cd0 100644 --- a/codes/io/src/FileO.cpp +++ b/codes/io/src/FileO.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/LogFile.cpp b/codes/io/src/LogFile.cpp index f4a4e968..9b56744b 100644 --- a/codes/io/src/LogFile.cpp +++ b/codes/io/src/LogFile.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/PIO.cpp b/codes/io/src/PIO.cpp index f8c7c3ac..9a0ad785 100644 --- a/codes/io/src/PIO.cpp +++ b/codes/io/src/PIO.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/ParaFile.cpp b/codes/io/src/ParaFile.cpp index 8daac0c3..698b8d50 100644 --- a/codes/io/src/ParaFile.cpp +++ b/codes/io/src/ParaFile.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/StrUtil.cpp b/codes/io/src/StrUtil.cpp index 705e61fb..ee6e5953 100644 --- a/codes/io/src/StrUtil.cpp +++ b/codes/io/src/StrUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/io/src/Word.cpp b/codes/io/src/Word.cpp index 1cd8724c..2414d3b7 100644 --- a/codes/io/src/Word.cpp +++ b/codes/io/src/Word.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/lhs/include/Lhs.h b/codes/lhs/include/Lhs.h index 8fdfd8f5..1d3c1235 100644 --- a/codes/lhs/include/Lhs.h +++ b/codes/lhs/include/Lhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/lhs/include/LhsTaskReg.h b/codes/lhs/include/LhsTaskReg.h index a118b5fe..e8a2c62b 100644 --- a/codes/lhs/include/LhsTaskReg.h +++ b/codes/lhs/include/LhsTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/lhs/src/Lhs.cpp b/codes/lhs/src/Lhs.cpp index 190e57bb..5a56f7c1 100644 --- a/codes/lhs/src/Lhs.cpp +++ b/codes/lhs/src/Lhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/lhs/src/LhsTaskReg.cpp b/codes/lhs/src/LhsTaskReg.cpp index 95dc5abc..0b3b6f20 100644 --- a/codes/lhs/src/LhsTaskReg.cpp +++ b/codes/lhs/src/LhsTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/include/SimpleSimu.h b/codes/main/include/SimpleSimu.h index 2088b05e..da655524 100644 --- a/codes/main/include/SimpleSimu.h +++ b/codes/main/include/SimpleSimu.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/include/SimuImp.h b/codes/main/include/SimuImp.h index a758615a..32d2024a 100644 --- a/codes/main/include/SimuImp.h +++ b/codes/main/include/SimuImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/include/Simulation.h b/codes/main/include/Simulation.h index c3a9076a..f3fc2851 100644 --- a/codes/main/include/Simulation.h +++ b/codes/main/include/Simulation.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/src/OneFlow.cpp b/codes/main/src/OneFlow.cpp index bc824c6d..dc7c0e25 100644 --- a/codes/main/src/OneFlow.cpp +++ b/codes/main/src/OneFlow.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/src/SimpleSimu.cpp b/codes/main/src/SimpleSimu.cpp index 2506339b..e0682c55 100644 --- a/codes/main/src/SimpleSimu.cpp +++ b/codes/main/src/SimpleSimu.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/src/SimuImp.cpp b/codes/main/src/SimuImp.cpp index ea19e7db..fb8dd48a 100644 --- a/codes/main/src/SimuImp.cpp +++ b/codes/main/src/SimuImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/main/src/Simulation.cpp b/codes/main/src/Simulation.cpp index 655f35d2..68b5e1a5 100644 --- a/codes/main/src/Simulation.cpp +++ b/codes/main/src/Simulation.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/math/include/HXMath.h b/codes/math/include/HXMath.h index f9bd2465..1057a630 100644 --- a/codes/math/include/HXMath.h +++ b/codes/math/include/HXMath.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/math/include/HXMathExt.h b/codes/math/include/HXMathExt.h index 57a06429..33baf9c1 100644 --- a/codes/math/include/HXMathExt.h +++ b/codes/math/include/HXMathExt.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/math/src/HXMath.cpp b/codes/math/src/HXMath.cpp index fa86bf9d..a3c6255e 100644 --- a/codes/math/src/HXMath.cpp +++ b/codes/math/src/HXMath.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/math/src/HXMathExt.cpp b/codes/math/src/HXMathExt.cpp index f9db15a0..6b30b9ef 100644 --- a/codes/math/src/HXMathExt.cpp +++ b/codes/math/src/HXMathExt.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/model/include/FlowModel.h b/codes/model/include/FlowModel.h index a56c20b9..ea29f68e 100644 --- a/codes/model/include/FlowModel.h +++ b/codes/model/include/FlowModel.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/model/include/Sutherland.h b/codes/model/include/Sutherland.h index 374d9337..3761adbf 100644 --- a/codes/model/include/Sutherland.h +++ b/codes/model/include/Sutherland.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/model/src/FlowModel.cpp b/codes/model/src/FlowModel.cpp index dbf9f1a7..dd4931fb 100644 --- a/codes/model/src/FlowModel.cpp +++ b/codes/model/src/FlowModel.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/model/src/Sutherland.cpp b/codes/model/src/Sutherland.cpp index 02e2035c..6446fc2b 100644 --- a/codes/model/src/Sutherland.cpp +++ b/codes/model/src/Sutherland.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/include/Memop.h b/codes/multiarray/include/Memop.h index 42fbe7e4..a8e9d99f 100644 --- a/codes/multiarray/include/Memop.h +++ b/codes/multiarray/include/Memop.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/include/Multiarray.h b/codes/multiarray/include/Multiarray.h index 846a9b0f..f88a1d9e 100644 --- a/codes/multiarray/include/Multiarray.h +++ b/codes/multiarray/include/Multiarray.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/include/Range.h b/codes/multiarray/include/Range.h index b1676f64..646a1436 100644 --- a/codes/multiarray/include/Range.h +++ b/codes/multiarray/include/Range.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/src/Memop.cpp b/codes/multiarray/src/Memop.cpp index 4030c3bb..5734b7f7 100644 --- a/codes/multiarray/src/Memop.cpp +++ b/codes/multiarray/src/Memop.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/src/Multiarray.cpp b/codes/multiarray/src/Multiarray.cpp index 4030c3bb..5734b7f7 100644 --- a/codes/multiarray/src/Multiarray.cpp +++ b/codes/multiarray/src/Multiarray.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multiarray/src/Range.cpp b/codes/multiarray/src/Range.cpp index cd64aab2..325d14d2 100644 --- a/codes/multiarray/src/Range.cpp +++ b/codes/multiarray/src/Range.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/include/BgField.h b/codes/multigrid/include/BgField.h index 59ae4ef1..8e27b9de 100644 --- a/codes/multigrid/include/BgField.h +++ b/codes/multigrid/include/BgField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/include/BgGrid.h b/codes/multigrid/include/BgGrid.h index f333e4a7..35a1dab4 100644 --- a/codes/multigrid/include/BgGrid.h +++ b/codes/multigrid/include/BgGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/include/Multigrid.h b/codes/multigrid/include/Multigrid.h index 3b20966f..6608f860 100644 --- a/codes/multigrid/include/Multigrid.h +++ b/codes/multigrid/include/Multigrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/include/MultigridTaskReg.h b/codes/multigrid/include/MultigridTaskReg.h index 279fd8f2..7688dea7 100644 --- a/codes/multigrid/include/MultigridTaskReg.h +++ b/codes/multigrid/include/MultigridTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/src/BgField.cpp b/codes/multigrid/src/BgField.cpp index 21c70c0e..a83816a4 100644 --- a/codes/multigrid/src/BgField.cpp +++ b/codes/multigrid/src/BgField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/src/BgGrid.cpp b/codes/multigrid/src/BgGrid.cpp index 43f7ba82..919343b8 100644 --- a/codes/multigrid/src/BgGrid.cpp +++ b/codes/multigrid/src/BgGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/src/Multigrid.cpp b/codes/multigrid/src/Multigrid.cpp index 3b3cb79c..5700f501 100644 --- a/codes/multigrid/src/Multigrid.cpp +++ b/codes/multigrid/src/Multigrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/multigrid/src/MultigridTaskReg.cpp b/codes/multigrid/src/MultigridTaskReg.cpp index d25cac17..ce0029a3 100644 --- a/codes/multigrid/src/MultigridTaskReg.cpp +++ b/codes/multigrid/src/MultigridTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsBcSolver.h b/codes/ns/include/NsBcSolver.h index 2bc30b58..53ce7ba3 100644 --- a/codes/ns/include/NsBcSolver.h +++ b/codes/ns/include/NsBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsCom.h b/codes/ns/include/NsCom.h index 6e5c11b5..949101e1 100644 --- a/codes/ns/include/NsCom.h +++ b/codes/ns/include/NsCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsCtrl.h b/codes/ns/include/NsCtrl.h index a258e006..12d44237 100644 --- a/codes/ns/include/NsCtrl.h +++ b/codes/ns/include/NsCtrl.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsIdx.h b/codes/ns/include/NsIdx.h index 1df70bea..c6d16b95 100644 --- a/codes/ns/include/NsIdx.h +++ b/codes/ns/include/NsIdx.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsInvFlux.h b/codes/ns/include/NsInvFlux.h index 949f5cac..d068a801 100644 --- a/codes/ns/include/NsInvFlux.h +++ b/codes/ns/include/NsInvFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsLusgs.h b/codes/ns/include/NsLusgs.h index e25aca5e..277dd541 100644 --- a/codes/ns/include/NsLusgs.h +++ b/codes/ns/include/NsLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsRestart.h b/codes/ns/include/NsRestart.h index 7bb4ada9..eb7740b9 100644 --- a/codes/ns/include/NsRestart.h +++ b/codes/ns/include/NsRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsRhs.h b/codes/ns/include/NsRhs.h index 84db7197..044f30de 100644 --- a/codes/ns/include/NsRhs.h +++ b/codes/ns/include/NsRhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsSolver.h b/codes/ns/include/NsSolver.h index bb7ae180..79f68741 100644 --- a/codes/ns/include/NsSolver.h +++ b/codes/ns/include/NsSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsSolverImp.h b/codes/ns/include/NsSolverImp.h index 42a80330..932d481e 100644 --- a/codes/ns/include/NsSolverImp.h +++ b/codes/ns/include/NsSolverImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsSpectrum.h b/codes/ns/include/NsSpectrum.h index 995894a9..b8ca158d 100644 --- a/codes/ns/include/NsSpectrum.h +++ b/codes/ns/include/NsSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsUnsteady.h b/codes/ns/include/NsUnsteady.h index 3a8e2dc7..4cc66205 100644 --- a/codes/ns/include/NsUnsteady.h +++ b/codes/ns/include/NsUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsUpdate.h b/codes/ns/include/NsUpdate.h index 921763f1..8fa26d0c 100644 --- a/codes/ns/include/NsUpdate.h +++ b/codes/ns/include/NsUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/NsVisFlux.h b/codes/ns/include/NsVisFlux.h index 82223392..e6277f64 100644 --- a/codes/ns/include/NsVisFlux.h +++ b/codes/ns/include/NsVisFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/include/TimeStep.h b/codes/ns/include/TimeStep.h index 99c2163e..d76404f0 100644 --- a/codes/ns/include/TimeStep.h +++ b/codes/ns/include/TimeStep.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsBcSolver.cpp b/codes/ns/src/NsBcSolver.cpp index bb3fdc14..53b2ff0b 100644 --- a/codes/ns/src/NsBcSolver.cpp +++ b/codes/ns/src/NsBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsCom.cpp b/codes/ns/src/NsCom.cpp index 60615c03..4ec2bb1f 100644 --- a/codes/ns/src/NsCom.cpp +++ b/codes/ns/src/NsCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsCtrl.cpp b/codes/ns/src/NsCtrl.cpp index 1e625fb2..43c3cefc 100644 --- a/codes/ns/src/NsCtrl.cpp +++ b/codes/ns/src/NsCtrl.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsInvFlux.cpp b/codes/ns/src/NsInvFlux.cpp index 21f73ec0..ddd8b25f 100644 --- a/codes/ns/src/NsInvFlux.cpp +++ b/codes/ns/src/NsInvFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsLusgs.cpp b/codes/ns/src/NsLusgs.cpp index 2381484a..2ec1ba60 100644 --- a/codes/ns/src/NsLusgs.cpp +++ b/codes/ns/src/NsLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsRestart.cpp b/codes/ns/src/NsRestart.cpp index b38daba5..4e2e632f 100644 --- a/codes/ns/src/NsRestart.cpp +++ b/codes/ns/src/NsRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsRhs.cpp b/codes/ns/src/NsRhs.cpp index 26fce1e6..05133543 100644 --- a/codes/ns/src/NsRhs.cpp +++ b/codes/ns/src/NsRhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsSolver.cpp b/codes/ns/src/NsSolver.cpp index b6ee2e2c..52578a66 100644 --- a/codes/ns/src/NsSolver.cpp +++ b/codes/ns/src/NsSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsSolverImp.cpp b/codes/ns/src/NsSolverImp.cpp index db845091..d0c94e01 100644 --- a/codes/ns/src/NsSolverImp.cpp +++ b/codes/ns/src/NsSolverImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsSpectrum.cpp b/codes/ns/src/NsSpectrum.cpp index 291b82e5..071f6b77 100644 --- a/codes/ns/src/NsSpectrum.cpp +++ b/codes/ns/src/NsSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsUnsteady.cpp b/codes/ns/src/NsUnsteady.cpp index 91ef9874..c5b32d19 100644 --- a/codes/ns/src/NsUnsteady.cpp +++ b/codes/ns/src/NsUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsUpdate.cpp b/codes/ns/src/NsUpdate.cpp index f8f49454..f19e37d1 100644 --- a/codes/ns/src/NsUpdate.cpp +++ b/codes/ns/src/NsUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/NsVisFlux.cpp b/codes/ns/src/NsVisFlux.cpp index 648e1865..e7a85d8a 100644 --- a/codes/ns/src/NsVisFlux.cpp +++ b/codes/ns/src/NsVisFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/ns/src/TimeStep.cpp b/codes/ns/src/TimeStep.cpp index 53ea2627..a5e35380 100644 --- a/codes/ns/src/TimeStep.cpp +++ b/codes/ns/src/TimeStep.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/parallel/include/BasicParallel.h b/codes/parallel/include/BasicParallel.h index d9deba41..d1eddc54 100644 --- a/codes/parallel/include/BasicParallel.h +++ b/codes/parallel/include/BasicParallel.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/parallel/include/Parallel.h b/codes/parallel/include/Parallel.h index 1e122f2f..79bac8d2 100644 --- a/codes/parallel/include/Parallel.h +++ b/codes/parallel/include/Parallel.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/parallel/src/BasicParallel.cpp b/codes/parallel/src/BasicParallel.cpp index 7ab2c7ee..749af76d 100644 --- a/codes/parallel/src/BasicParallel.cpp +++ b/codes/parallel/src/BasicParallel.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/parallel/src/Parallel.cpp b/codes/parallel/src/Parallel.cpp index 28352ee2..2ad2516f 100644 --- a/codes/parallel/src/Parallel.cpp +++ b/codes/parallel/src/Parallel.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/partition/include/Partition.h b/codes/partition/include/Partition.h index 5cfb50bc..fcdba41f 100644 --- a/codes/partition/include/Partition.h +++ b/codes/partition/include/Partition.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/partition/include/SmartGrid.h b/codes/partition/include/SmartGrid.h index e221e859..e621b456 100644 --- a/codes/partition/include/SmartGrid.h +++ b/codes/partition/include/SmartGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/partition/src/Partition.cpp b/codes/partition/src/Partition.cpp index d6be8ee6..b5ea45fe 100644 --- a/codes/partition/src/Partition.cpp +++ b/codes/partition/src/Partition.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/partition/src/SmartGrid.cpp b/codes/partition/src/SmartGrid.cpp index eadabbbb..c150a9ff 100644 --- a/codes/partition/src/SmartGrid.cpp +++ b/codes/partition/src/SmartGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/physics/include/Atmosphere.h b/codes/physics/include/Atmosphere.h index 847e2d76..2f0ecf16 100644 --- a/codes/physics/include/Atmosphere.h +++ b/codes/physics/include/Atmosphere.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/physics/src/Atmosphere.cpp b/codes/physics/src/Atmosphere.cpp index 618ed1ea..6a8d56a4 100644 --- a/codes/physics/src/Atmosphere.cpp +++ b/codes/physics/src/Atmosphere.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/postprocess/include/PostProcess.h b/codes/postprocess/include/PostProcess.h index a6a6ec95..9b4fe4d4 100644 --- a/codes/postprocess/include/PostProcess.h +++ b/codes/postprocess/include/PostProcess.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/postprocess/src/PostProcess.cpp b/codes/postprocess/src/PostProcess.cpp index b5bc9294..e4c6c27a 100644 --- a/codes/postprocess/src/PostProcess.cpp +++ b/codes/postprocess/src/PostProcess.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/include/Configure.h b/codes/project/include/Configure.h index d9bc975f..7f03c82f 100644 --- a/codes/project/include/Configure.h +++ b/codes/project/include/Configure.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/include/FileUtil.h b/codes/project/include/FileUtil.h index 6cef6e25..c382d87e 100644 --- a/codes/project/include/FileUtil.h +++ b/codes/project/include/FileUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/include/OStream.h b/codes/project/include/OStream.h index 4110bf1f..fb26de11 100644 --- a/codes/project/include/OStream.h +++ b/codes/project/include/OStream.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/include/Prj.h b/codes/project/include/Prj.h index e2ed849f..a9dadc01 100644 --- a/codes/project/include/Prj.h +++ b/codes/project/include/Prj.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/include/Stop.h b/codes/project/include/Stop.h index 8ba52301..90294eb0 100644 --- a/codes/project/include/Stop.h +++ b/codes/project/include/Stop.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/src/FileUtil.cpp b/codes/project/src/FileUtil.cpp index bb3739eb..8dcaca47 100644 --- a/codes/project/src/FileUtil.cpp +++ b/codes/project/src/FileUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/src/OStream.cpp b/codes/project/src/OStream.cpp index e9fea8b0..7bfd2bb3 100644 --- a/codes/project/src/OStream.cpp +++ b/codes/project/src/OStream.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/src/Prj.cpp b/codes/project/src/Prj.cpp index b537b2ea..21c49f1e 100644 --- a/codes/project/src/Prj.cpp +++ b/codes/project/src/Prj.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/project/src/Stop.cpp b/codes/project/src/Stop.cpp index 29b9d8e8..2f143359 100644 --- a/codes/project/src/Stop.cpp +++ b/codes/project/src/Stop.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/include/HXClone.h b/codes/register/include/HXClone.h index f564dacf..ebae759a 100644 --- a/codes/register/include/HXClone.h +++ b/codes/register/include/HXClone.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/include/Message.h b/codes/register/include/Message.h index 2ab7414a..83dde89b 100644 --- a/codes/register/include/Message.h +++ b/codes/register/include/Message.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/include/MsgMapImp.h b/codes/register/include/MsgMapImp.h index 9ef31999..2e2110e6 100644 --- a/codes/register/include/MsgMapImp.h +++ b/codes/register/include/MsgMapImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/include/Register.h b/codes/register/include/Register.h index eb0e036e..13398d1e 100644 --- a/codes/register/include/Register.h +++ b/codes/register/include/Register.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/include/RegisterUtil.h b/codes/register/include/RegisterUtil.h index 15e8eb4a..f00025fd 100644 --- a/codes/register/include/RegisterUtil.h +++ b/codes/register/include/RegisterUtil.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/src/HXClone.cpp b/codes/register/src/HXClone.cpp index d6566915..8aae6bea 100644 --- a/codes/register/src/HXClone.cpp +++ b/codes/register/src/HXClone.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/src/Message.cpp b/codes/register/src/Message.cpp index 096d16ad..35191768 100644 --- a/codes/register/src/Message.cpp +++ b/codes/register/src/Message.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/src/MsgMapImp.cpp b/codes/register/src/MsgMapImp.cpp index c7299e19..a8711bc2 100644 --- a/codes/register/src/MsgMapImp.cpp +++ b/codes/register/src/MsgMapImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/src/Register.cpp b/codes/register/src/Register.cpp index 2ec09e14..4c78d2c3 100644 --- a/codes/register/src/Register.cpp +++ b/codes/register/src/Register.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/register/src/RegisterUtil.cpp b/codes/register/src/RegisterUtil.cpp index 1ca5dac7..c030d666 100644 --- a/codes/register/src/RegisterUtil.cpp +++ b/codes/register/src/RegisterUtil.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/include/Residual.h b/codes/residual/include/Residual.h index 8dd06c23..384ee91c 100644 --- a/codes/residual/include/Residual.h +++ b/codes/residual/include/Residual.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/include/ResidualTask.h b/codes/residual/include/ResidualTask.h index 1263206b..186675ec 100644 --- a/codes/residual/include/ResidualTask.h +++ b/codes/residual/include/ResidualTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/include/ResidualTaskReg.h b/codes/residual/include/ResidualTaskReg.h index bcd7cfad..0601b306 100644 --- a/codes/residual/include/ResidualTaskReg.h +++ b/codes/residual/include/ResidualTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/src/Residual.cpp b/codes/residual/src/Residual.cpp index 8c20bddf..ba523526 100644 --- a/codes/residual/src/Residual.cpp +++ b/codes/residual/src/Residual.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/src/ResidualTask.cpp b/codes/residual/src/ResidualTask.cpp index 051313f3..c4d02f4d 100644 --- a/codes/residual/src/ResidualTask.cpp +++ b/codes/residual/src/ResidualTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/residual/src/ResidualTaskReg.cpp b/codes/residual/src/ResidualTaskReg.cpp index 78eaa518..68b991e9 100644 --- a/codes/residual/src/ResidualTaskReg.cpp +++ b/codes/residual/src/ResidualTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/restart/include/Restart.h b/codes/restart/include/Restart.h index 333cc4e9..7fad4c6b 100644 --- a/codes/restart/include/Restart.h +++ b/codes/restart/include/Restart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/restart/include/RestartTaskReg.h b/codes/restart/include/RestartTaskReg.h index f34fde1b..fbbe3426 100644 --- a/codes/restart/include/RestartTaskReg.h +++ b/codes/restart/include/RestartTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/restart/src/Restart.cpp b/codes/restart/src/Restart.cpp index 3d47fac1..504a78f1 100644 --- a/codes/restart/src/Restart.cpp +++ b/codes/restart/src/Restart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/restart/src/RestartTaskReg.cpp b/codes/restart/src/RestartTaskReg.cpp index bfd3f262..5b5d7845 100644 --- a/codes/restart/src/RestartTaskReg.cpp +++ b/codes/restart/src/RestartTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/Blasius.h b/codes/scalar/include/Blasius.h index 20736f10..5614970f 100644 --- a/codes/scalar/include/Blasius.h +++ b/codes/scalar/include/Blasius.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/FieldPara.h b/codes/scalar/include/FieldPara.h index e9f4fa42..1b75866f 100644 --- a/codes/scalar/include/FieldPara.h +++ b/codes/scalar/include/FieldPara.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/FieldSolver.h b/codes/scalar/include/FieldSolver.h index c6f46b7e..33663fa9 100644 --- a/codes/scalar/include/FieldSolver.h +++ b/codes/scalar/include/FieldSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/FieldSolverBasic.h b/codes/scalar/include/FieldSolverBasic.h index e221b4f6..1ceab7f2 100644 --- a/codes/scalar/include/FieldSolverBasic.h +++ b/codes/scalar/include/FieldSolverBasic.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/FieldSolverCuda.h b/codes/scalar/include/FieldSolverCuda.h index 7bc91636..b78c481d 100644 --- a/codes/scalar/include/FieldSolverCuda.h +++ b/codes/scalar/include/FieldSolverCuda.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/FieldSolverOpenMP.h b/codes/scalar/include/FieldSolverOpenMP.h index 758cbe20..7a052612 100644 --- a/codes/scalar/include/FieldSolverOpenMP.h +++ b/codes/scalar/include/FieldSolverOpenMP.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/MetisGrid.h b/codes/scalar/include/MetisGrid.h index 759cd7e9..e8bd90ee 100644 --- a/codes/scalar/include/MetisGrid.h +++ b/codes/scalar/include/MetisGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/Numpy.h b/codes/scalar/include/Numpy.h index 5493bea2..f9e5d03e 100644 --- a/codes/scalar/include/Numpy.h +++ b/codes/scalar/include/Numpy.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/Scalar.h b/codes/scalar/include/Scalar.h index 286bf5ef..e0716608 100644 --- a/codes/scalar/include/Scalar.h +++ b/codes/scalar/include/Scalar.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarAlloc.h b/codes/scalar/include/ScalarAlloc.h index 88bb3964..e48a71db 100644 --- a/codes/scalar/include/ScalarAlloc.h +++ b/codes/scalar/include/ScalarAlloc.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarCgns.h b/codes/scalar/include/ScalarCgns.h index 51f85fc7..921dd934 100644 --- a/codes/scalar/include/ScalarCgns.h +++ b/codes/scalar/include/ScalarCgns.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarDataIO.h b/codes/scalar/include/ScalarDataIO.h index e9ba57e2..137947b4 100644 --- a/codes/scalar/include/ScalarDataIO.h +++ b/codes/scalar/include/ScalarDataIO.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarField.h b/codes/scalar/include/ScalarField.h index a1f57eb2..a15477fb 100644 --- a/codes/scalar/include/ScalarField.h +++ b/codes/scalar/include/ScalarField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarFieldRecord.h b/codes/scalar/include/ScalarFieldRecord.h index 87a79a44..9908baea 100644 --- a/codes/scalar/include/ScalarFieldRecord.h +++ b/codes/scalar/include/ScalarFieldRecord.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarGrid.h b/codes/scalar/include/ScalarGrid.h index 9d8d7fa8..ce2f25d7 100644 --- a/codes/scalar/include/ScalarGrid.h +++ b/codes/scalar/include/ScalarGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarIFace.h b/codes/scalar/include/ScalarIFace.h index 32bd6f2a..dd15cd45 100644 --- a/codes/scalar/include/ScalarIFace.h +++ b/codes/scalar/include/ScalarIFace.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarMetis.h b/codes/scalar/include/ScalarMetis.h index 2371624e..61149bc5 100644 --- a/codes/scalar/include/ScalarMetis.h +++ b/codes/scalar/include/ScalarMetis.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarOrder.h b/codes/scalar/include/ScalarOrder.h index 248f0b3c..cbae1d91 100644 --- a/codes/scalar/include/ScalarOrder.h +++ b/codes/scalar/include/ScalarOrder.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarSolver.h b/codes/scalar/include/ScalarSolver.h index f996458c..2fbab427 100644 --- a/codes/scalar/include/ScalarSolver.h +++ b/codes/scalar/include/ScalarSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/ScalarZone.h b/codes/scalar/include/ScalarZone.h index a7c54410..473180d6 100644 --- a/codes/scalar/include/ScalarZone.h +++ b/codes/scalar/include/ScalarZone.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/include/SolverDevice.h b/codes/scalar/include/SolverDevice.h index be9f9afb..5b09b275 100644 --- a/codes/scalar/include/SolverDevice.h +++ b/codes/scalar/include/SolverDevice.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/Blasius.cpp b/codes/scalar/src/Blasius.cpp index c432fa1a..7f489d50 100644 --- a/codes/scalar/src/Blasius.cpp +++ b/codes/scalar/src/Blasius.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/FieldPara.cpp b/codes/scalar/src/FieldPara.cpp index 9d7af66a..2852f6d5 100644 --- a/codes/scalar/src/FieldPara.cpp +++ b/codes/scalar/src/FieldPara.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/FieldSolver.cpp b/codes/scalar/src/FieldSolver.cpp index dc464258..2571e20a 100644 --- a/codes/scalar/src/FieldSolver.cpp +++ b/codes/scalar/src/FieldSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/FieldSolverBasic.cpp b/codes/scalar/src/FieldSolverBasic.cpp index 94406f80..306b08cb 100644 --- a/codes/scalar/src/FieldSolverBasic.cpp +++ b/codes/scalar/src/FieldSolverBasic.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/FieldSolverCuda.cpp b/codes/scalar/src/FieldSolverCuda.cpp index b4a09a47..d02582be 100644 --- a/codes/scalar/src/FieldSolverCuda.cpp +++ b/codes/scalar/src/FieldSolverCuda.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/FieldSolverOpenMP.cpp b/codes/scalar/src/FieldSolverOpenMP.cpp index 3c2f9804..7be3f4ad 100644 --- a/codes/scalar/src/FieldSolverOpenMP.cpp +++ b/codes/scalar/src/FieldSolverOpenMP.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/MetisGrid.cpp b/codes/scalar/src/MetisGrid.cpp index 8c586ee6..5c3a1476 100644 --- a/codes/scalar/src/MetisGrid.cpp +++ b/codes/scalar/src/MetisGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/Numpy.cpp b/codes/scalar/src/Numpy.cpp index b42f216d..37cf9d2e 100644 --- a/codes/scalar/src/Numpy.cpp +++ b/codes/scalar/src/Numpy.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/Scalar.cpp b/codes/scalar/src/Scalar.cpp index 0feee103..d4868f1d 100644 --- a/codes/scalar/src/Scalar.cpp +++ b/codes/scalar/src/Scalar.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarAlloc.cpp b/codes/scalar/src/ScalarAlloc.cpp index 54a954c9..bb32681d 100644 --- a/codes/scalar/src/ScalarAlloc.cpp +++ b/codes/scalar/src/ScalarAlloc.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarCgns.cpp b/codes/scalar/src/ScalarCgns.cpp index 1181165e..84475991 100644 --- a/codes/scalar/src/ScalarCgns.cpp +++ b/codes/scalar/src/ScalarCgns.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarDataIO.cpp b/codes/scalar/src/ScalarDataIO.cpp index 2d98c0e0..0023ad75 100644 --- a/codes/scalar/src/ScalarDataIO.cpp +++ b/codes/scalar/src/ScalarDataIO.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarField.cpp b/codes/scalar/src/ScalarField.cpp index 076a05d6..455dc1fa 100644 --- a/codes/scalar/src/ScalarField.cpp +++ b/codes/scalar/src/ScalarField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarFieldRecord.cpp b/codes/scalar/src/ScalarFieldRecord.cpp index b99bbd5c..949fc30a 100644 --- a/codes/scalar/src/ScalarFieldRecord.cpp +++ b/codes/scalar/src/ScalarFieldRecord.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarGrid.cpp b/codes/scalar/src/ScalarGrid.cpp index 2ea39874..0be346bc 100644 --- a/codes/scalar/src/ScalarGrid.cpp +++ b/codes/scalar/src/ScalarGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarIFace.cpp b/codes/scalar/src/ScalarIFace.cpp index 2eb9f91b..8f446da1 100644 --- a/codes/scalar/src/ScalarIFace.cpp +++ b/codes/scalar/src/ScalarIFace.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarMetis.cpp b/codes/scalar/src/ScalarMetis.cpp index 735385c4..a7dbf7a8 100644 --- a/codes/scalar/src/ScalarMetis.cpp +++ b/codes/scalar/src/ScalarMetis.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarOrder.cpp b/codes/scalar/src/ScalarOrder.cpp index 63330e56..ce013218 100644 --- a/codes/scalar/src/ScalarOrder.cpp +++ b/codes/scalar/src/ScalarOrder.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarSolver.cpp b/codes/scalar/src/ScalarSolver.cpp index e3bde362..6f61720b 100644 --- a/codes/scalar/src/ScalarSolver.cpp +++ b/codes/scalar/src/ScalarSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/ScalarZone.cpp b/codes/scalar/src/ScalarZone.cpp index 7559eb8d..6f0ac08e 100644 --- a/codes/scalar/src/ScalarZone.cpp +++ b/codes/scalar/src/ScalarZone.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/scalar/src/SolverDevice.cu b/codes/scalar/src/SolverDevice.cu index 40bd2055..300028e8 100644 --- a/codes/scalar/src/SolverDevice.cu +++ b/codes/scalar/src/SolverDevice.cu @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/BcData.h b/codes/solver/include/BcData.h index cb580dfa..797849ed 100644 --- a/codes/solver/include/BcData.h +++ b/codes/solver/include/BcData.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/BcSolver.h b/codes/solver/include/BcSolver.h index 64007382..00c6b816 100644 --- a/codes/solver/include/BcSolver.h +++ b/codes/solver/include/BcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/Converge.h b/codes/solver/include/Converge.h index fddcf7b9..b99e5f3b 100644 --- a/codes/solver/include/Converge.h +++ b/codes/solver/include/Converge.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/FieldTaskReg.h b/codes/solver/include/FieldTaskReg.h index d6ab9a1b..03894d5a 100644 --- a/codes/solver/include/FieldTaskReg.h +++ b/codes/solver/include/FieldTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/FieldWrap.h b/codes/solver/include/FieldWrap.h index b42b7c30..9cedd528 100644 --- a/codes/solver/include/FieldWrap.h +++ b/codes/solver/include/FieldWrap.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/Rhs.h b/codes/solver/include/Rhs.h index a4525e21..20a49907 100644 --- a/codes/solver/include/Rhs.h +++ b/codes/solver/include/Rhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/Solver.h b/codes/solver/include/Solver.h index 7d7090a5..0cb214a3 100644 --- a/codes/solver/include/Solver.h +++ b/codes/solver/include/Solver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/SolverImp.h b/codes/solver/include/SolverImp.h index d6a64c24..ae961572 100644 --- a/codes/solver/include/SolverImp.h +++ b/codes/solver/include/SolverImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/SolverInfo.h b/codes/solver/include/SolverInfo.h index efa50e0d..cc7b5a6d 100644 --- a/codes/solver/include/SolverInfo.h +++ b/codes/solver/include/SolverInfo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/SolverMap.h b/codes/solver/include/SolverMap.h index 0c82cee8..7b4f9306 100644 --- a/codes/solver/include/SolverMap.h +++ b/codes/solver/include/SolverMap.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/SolverRegData.h b/codes/solver/include/SolverRegData.h index e14f807d..5d727e2c 100644 --- a/codes/solver/include/SolverRegData.h +++ b/codes/solver/include/SolverRegData.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/SolverState.h b/codes/solver/include/SolverState.h index b438d366..8145ab98 100644 --- a/codes/solver/include/SolverState.h +++ b/codes/solver/include/SolverState.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/Stress.h b/codes/solver/include/Stress.h index cec41da6..01bc75ca 100644 --- a/codes/solver/include/Stress.h +++ b/codes/solver/include/Stress.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/include/TimeIntegral.h b/codes/solver/include/TimeIntegral.h index d4012daa..32965e68 100644 --- a/codes/solver/include/TimeIntegral.h +++ b/codes/solver/include/TimeIntegral.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/BcData.cpp b/codes/solver/src/BcData.cpp index b305872f..9814c05a 100644 --- a/codes/solver/src/BcData.cpp +++ b/codes/solver/src/BcData.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/BcSolver.cpp b/codes/solver/src/BcSolver.cpp index 95e0a6ba..f401e81f 100644 --- a/codes/solver/src/BcSolver.cpp +++ b/codes/solver/src/BcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/Converge.cpp b/codes/solver/src/Converge.cpp index 5b530222..1461cf09 100644 --- a/codes/solver/src/Converge.cpp +++ b/codes/solver/src/Converge.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/FieldTaskReg.cpp b/codes/solver/src/FieldTaskReg.cpp index 2559a4e2..42682567 100644 --- a/codes/solver/src/FieldTaskReg.cpp +++ b/codes/solver/src/FieldTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/FieldWrap.cpp b/codes/solver/src/FieldWrap.cpp index 63c022fb..8ebc70b2 100644 --- a/codes/solver/src/FieldWrap.cpp +++ b/codes/solver/src/FieldWrap.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/Rhs.cpp b/codes/solver/src/Rhs.cpp index 26091218..85b186bd 100644 --- a/codes/solver/src/Rhs.cpp +++ b/codes/solver/src/Rhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/Solver.cpp b/codes/solver/src/Solver.cpp index cbde3e9b..bc2954d9 100644 --- a/codes/solver/src/Solver.cpp +++ b/codes/solver/src/Solver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/SolverImp.cpp b/codes/solver/src/SolverImp.cpp index 7c6cde36..56f9a1ef 100644 --- a/codes/solver/src/SolverImp.cpp +++ b/codes/solver/src/SolverImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/SolverInfo.cpp b/codes/solver/src/SolverInfo.cpp index 57ffd1ec..f353ad59 100644 --- a/codes/solver/src/SolverInfo.cpp +++ b/codes/solver/src/SolverInfo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/SolverMap.cpp b/codes/solver/src/SolverMap.cpp index 560faf63..0c624413 100644 --- a/codes/solver/src/SolverMap.cpp +++ b/codes/solver/src/SolverMap.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/SolverRegData.cpp b/codes/solver/src/SolverRegData.cpp index e917a8a5..9417fe54 100644 --- a/codes/solver/src/SolverRegData.cpp +++ b/codes/solver/src/SolverRegData.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/SolverState.cpp b/codes/solver/src/SolverState.cpp index f8f1709e..c0df2102 100644 --- a/codes/solver/src/SolverState.cpp +++ b/codes/solver/src/SolverState.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/Stress.cpp b/codes/solver/src/Stress.cpp index cfd6b6ed..38ff2299 100644 --- a/codes/solver/src/Stress.cpp +++ b/codes/solver/src/Stress.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/solver/src/TimeIntegral.cpp b/codes/solver/src/TimeIntegral.cpp index 373982ec..d46cc289 100644 --- a/codes/solver/src/TimeIntegral.cpp +++ b/codes/solver/src/TimeIntegral.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/BlkMesh.h b/codes/special/include/BlkMesh.h index ce9bb1b9..4f892a08 100644 --- a/codes/special/include/BlkMesh.h +++ b/codes/special/include/BlkMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Block2D.h b/codes/special/include/Block2D.h index 66d94da9..20b0a19c 100644 --- a/codes/special/include/Block2D.h +++ b/codes/special/include/Block2D.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Block3D.h b/codes/special/include/Block3D.h index a620eb1c..43543f21 100644 --- a/codes/special/include/Block3D.h +++ b/codes/special/include/Block3D.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/BlockElem.h b/codes/special/include/BlockElem.h index 1a9133d7..44001ab9 100644 --- a/codes/special/include/BlockElem.h +++ b/codes/special/include/BlockElem.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/BlockFaceSolver.h b/codes/special/include/BlockFaceSolver.h index 50f4a2da..a20bdab4 100644 --- a/codes/special/include/BlockFaceSolver.h +++ b/codes/special/include/BlockFaceSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/BlockMachine.h b/codes/special/include/BlockMachine.h index 6ed91fe3..ce48ba6a 100644 --- a/codes/special/include/BlockMachine.h +++ b/codes/special/include/BlockMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CalcCoor.h b/codes/special/include/CalcCoor.h index 8c78678f..2b6e529a 100644 --- a/codes/special/include/CalcCoor.h +++ b/codes/special/include/CalcCoor.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Cavity.h b/codes/special/include/Cavity.h index f785815d..c8b2ec15 100644 --- a/codes/special/include/Cavity.h +++ b/codes/special/include/Cavity.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CgnsTest.h b/codes/special/include/CgnsTest.h index 99471827..c3c08fb5 100644 --- a/codes/special/include/CgnsTest.h +++ b/codes/special/include/CgnsTest.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CgnsTestTmp.h b/codes/special/include/CgnsTestTmp.h index f9e36186..17c974c9 100644 --- a/codes/special/include/CgnsTestTmp.h +++ b/codes/special/include/CgnsTestTmp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CircleInfo.h b/codes/special/include/CircleInfo.h index 8a7252a7..e977c55e 100644 --- a/codes/special/include/CircleInfo.h +++ b/codes/special/include/CircleInfo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CircleLineMesh.h b/codes/special/include/CircleLineMesh.h index 33e1e26a..7babc600 100644 --- a/codes/special/include/CircleLineMesh.h +++ b/codes/special/include/CircleLineMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/ClassicGrid.h b/codes/special/include/ClassicGrid.h index 0b011c3a..39b045c4 100644 --- a/codes/special/include/ClassicGrid.h +++ b/codes/special/include/ClassicGrid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CurveInfo.h b/codes/special/include/CurveInfo.h index 392dc119..21eeb9b6 100644 --- a/codes/special/include/CurveInfo.h +++ b/codes/special/include/CurveInfo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CurveLine.h b/codes/special/include/CurveLine.h index 5cd3241e..271c3f67 100644 --- a/codes/special/include/CurveLine.h +++ b/codes/special/include/CurveLine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CurveMachine.h b/codes/special/include/CurveMachine.h index 212f22df..5e70c425 100644 --- a/codes/special/include/CurveMachine.h +++ b/codes/special/include/CurveMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/CurveMesh.h b/codes/special/include/CurveMesh.h index b4aff627..17f73d4e 100644 --- a/codes/special/include/CurveMesh.h +++ b/codes/special/include/CurveMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Cylinder.h b/codes/special/include/Cylinder.h index 2845041c..573bcefc 100644 --- a/codes/special/include/Cylinder.h +++ b/codes/special/include/Cylinder.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/DomainMachine.h b/codes/special/include/DomainMachine.h index b3de3c65..fc19bc15 100644 --- a/codes/special/include/DomainMachine.h +++ b/codes/special/include/DomainMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/GridCreate.h b/codes/special/include/GridCreate.h index 0faf9a72..ab22a728 100644 --- a/codes/special/include/GridCreate.h +++ b/codes/special/include/GridCreate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/GridMachine.h b/codes/special/include/GridMachine.h index 76a0022a..22eca26d 100644 --- a/codes/special/include/GridMachine.h +++ b/codes/special/include/GridMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/LineInfo.h b/codes/special/include/LineInfo.h index e1b64220..566c6d39 100644 --- a/codes/special/include/LineInfo.h +++ b/codes/special/include/LineInfo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/LineMachine.h b/codes/special/include/LineMachine.h index f79927fb..d100b1cb 100644 --- a/codes/special/include/LineMachine.h +++ b/codes/special/include/LineMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/LineMesh.h b/codes/special/include/LineMesh.h index 07e4e612..20ffb35d 100644 --- a/codes/special/include/LineMesh.h +++ b/codes/special/include/LineMesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/LineMeshImp.h b/codes/special/include/LineMeshImp.h index bb35fec4..26de3989 100644 --- a/codes/special/include/LineMeshImp.h +++ b/codes/special/include/LineMeshImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/MDomain.h b/codes/special/include/MDomain.h index 385ffd3b..bfa54d9f 100644 --- a/codes/special/include/MDomain.h +++ b/codes/special/include/MDomain.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/MLine.h b/codes/special/include/MLine.h index 3063951d..dd981793 100644 --- a/codes/special/include/MLine.h +++ b/codes/special/include/MLine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Mesh.h b/codes/special/include/Mesh.h index 93a6bd8a..0b97563c 100644 --- a/codes/special/include/Mesh.h +++ b/codes/special/include/Mesh.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/MpiTest.h b/codes/special/include/MpiTest.h index e77bc591..1ad15da6 100644 --- a/codes/special/include/MpiTest.h +++ b/codes/special/include/MpiTest.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/PointMachine.h b/codes/special/include/PointMachine.h index 86f6399f..7503388d 100644 --- a/codes/special/include/PointMachine.h +++ b/codes/special/include/PointMachine.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Rae2822.h b/codes/special/include/Rae2822.h index 087c0c3f..ab4bf8a1 100644 --- a/codes/special/include/Rae2822.h +++ b/codes/special/include/Rae2822.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/SDomain.h b/codes/special/include/SDomain.h index b777d715..0bc02128 100644 --- a/codes/special/include/SDomain.h +++ b/codes/special/include/SDomain.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/SegmentCtrl.h b/codes/special/include/SegmentCtrl.h index 2a80ad87..58c10a3d 100644 --- a/codes/special/include/SegmentCtrl.h +++ b/codes/special/include/SegmentCtrl.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/SimpleDomain.h b/codes/special/include/SimpleDomain.h index 1310dcf8..8e2b3230 100644 --- a/codes/special/include/SimpleDomain.h +++ b/codes/special/include/SimpleDomain.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/StrBcSetting.h b/codes/special/include/StrBcSetting.h index 474ff41d..eee47db9 100644 --- a/codes/special/include/StrBcSetting.h +++ b/codes/special/include/StrBcSetting.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/include/Transfinite.h b/codes/special/include/Transfinite.h index 654cc929..a807dce8 100644 --- a/codes/special/include/Transfinite.h +++ b/codes/special/include/Transfinite.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/BlkMesh.cpp b/codes/special/src/BlkMesh.cpp index b21cb252..adb711d3 100644 --- a/codes/special/src/BlkMesh.cpp +++ b/codes/special/src/BlkMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Block2D.cpp b/codes/special/src/Block2D.cpp index 731d95f7..163f5037 100644 --- a/codes/special/src/Block2D.cpp +++ b/codes/special/src/Block2D.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Block3D.cpp b/codes/special/src/Block3D.cpp index 144b3dd6..59777ecd 100644 --- a/codes/special/src/Block3D.cpp +++ b/codes/special/src/Block3D.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/BlockElem.cpp b/codes/special/src/BlockElem.cpp index e1c9b6ac..da513aa4 100644 --- a/codes/special/src/BlockElem.cpp +++ b/codes/special/src/BlockElem.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/BlockFaceSolver.cpp b/codes/special/src/BlockFaceSolver.cpp index 8bbbe4ba..1e588148 100644 --- a/codes/special/src/BlockFaceSolver.cpp +++ b/codes/special/src/BlockFaceSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/BlockMachine.cpp b/codes/special/src/BlockMachine.cpp index 6b58a004..c4f7dfd8 100644 --- a/codes/special/src/BlockMachine.cpp +++ b/codes/special/src/BlockMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CalcCoor.cpp b/codes/special/src/CalcCoor.cpp index 1b01188f..8f17112c 100644 --- a/codes/special/src/CalcCoor.cpp +++ b/codes/special/src/CalcCoor.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Cavity.cpp b/codes/special/src/Cavity.cpp index af2accdb..f78909cb 100644 --- a/codes/special/src/Cavity.cpp +++ b/codes/special/src/Cavity.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CgnsTest.cpp b/codes/special/src/CgnsTest.cpp index a17e5916..599a55a9 100644 --- a/codes/special/src/CgnsTest.cpp +++ b/codes/special/src/CgnsTest.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CgnsTestTmp.cpp b/codes/special/src/CgnsTestTmp.cpp index 3feb95ce..27084abe 100644 --- a/codes/special/src/CgnsTestTmp.cpp +++ b/codes/special/src/CgnsTestTmp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CircleInfo.cpp b/codes/special/src/CircleInfo.cpp index d528400d..5574e93c 100644 --- a/codes/special/src/CircleInfo.cpp +++ b/codes/special/src/CircleInfo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CircleLineMesh.cpp b/codes/special/src/CircleLineMesh.cpp index 4eaf93e6..ee4f7d08 100644 --- a/codes/special/src/CircleLineMesh.cpp +++ b/codes/special/src/CircleLineMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/ClassicGrid.cpp b/codes/special/src/ClassicGrid.cpp index b79c4636..2e587c80 100644 --- a/codes/special/src/ClassicGrid.cpp +++ b/codes/special/src/ClassicGrid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CurveInfo.cpp b/codes/special/src/CurveInfo.cpp index 63c2dfd5..549ca30f 100644 --- a/codes/special/src/CurveInfo.cpp +++ b/codes/special/src/CurveInfo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CurveLine.cpp b/codes/special/src/CurveLine.cpp index 3ac0f4df..d8324520 100644 --- a/codes/special/src/CurveLine.cpp +++ b/codes/special/src/CurveLine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CurveMachine.cpp b/codes/special/src/CurveMachine.cpp index 354a1a51..d358d180 100644 --- a/codes/special/src/CurveMachine.cpp +++ b/codes/special/src/CurveMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/CurveMesh.cpp b/codes/special/src/CurveMesh.cpp index 2e74c640..86984e7a 100644 --- a/codes/special/src/CurveMesh.cpp +++ b/codes/special/src/CurveMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Cylinder.cpp b/codes/special/src/Cylinder.cpp index 018c2be0..fbed9180 100644 --- a/codes/special/src/Cylinder.cpp +++ b/codes/special/src/Cylinder.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/DomainMachine.cpp b/codes/special/src/DomainMachine.cpp index 0f15bb7b..9474863b 100644 --- a/codes/special/src/DomainMachine.cpp +++ b/codes/special/src/DomainMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/GridCreate.cpp b/codes/special/src/GridCreate.cpp index 317be724..31d2f76f 100644 --- a/codes/special/src/GridCreate.cpp +++ b/codes/special/src/GridCreate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/GridMachine.cpp b/codes/special/src/GridMachine.cpp index 88cb11df..93d7d128 100644 --- a/codes/special/src/GridMachine.cpp +++ b/codes/special/src/GridMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/LineInfo.cpp b/codes/special/src/LineInfo.cpp index 0de8b47a..c8c2ae49 100644 --- a/codes/special/src/LineInfo.cpp +++ b/codes/special/src/LineInfo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/LineMachine.cpp b/codes/special/src/LineMachine.cpp index 76d7d759..337c33e2 100644 --- a/codes/special/src/LineMachine.cpp +++ b/codes/special/src/LineMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/LineMesh.cpp b/codes/special/src/LineMesh.cpp index 0d6a06a9..479ec1fb 100644 --- a/codes/special/src/LineMesh.cpp +++ b/codes/special/src/LineMesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/LineMeshImp.cpp b/codes/special/src/LineMeshImp.cpp index ed274477..a3d7f2ef 100644 --- a/codes/special/src/LineMeshImp.cpp +++ b/codes/special/src/LineMeshImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/MDomain.cpp b/codes/special/src/MDomain.cpp index 919bd0ba..c6df8d02 100644 --- a/codes/special/src/MDomain.cpp +++ b/codes/special/src/MDomain.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/MLine.cpp b/codes/special/src/MLine.cpp index 7f6a79a4..d1caa410 100644 --- a/codes/special/src/MLine.cpp +++ b/codes/special/src/MLine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Mesh.cpp b/codes/special/src/Mesh.cpp index 98ac1761..a760182b 100644 --- a/codes/special/src/Mesh.cpp +++ b/codes/special/src/Mesh.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/MpiTest.cpp b/codes/special/src/MpiTest.cpp index 38bbff74..42c16892 100644 --- a/codes/special/src/MpiTest.cpp +++ b/codes/special/src/MpiTest.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/PointMachine.cpp b/codes/special/src/PointMachine.cpp index e4c27872..c1675072 100644 --- a/codes/special/src/PointMachine.cpp +++ b/codes/special/src/PointMachine.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Rae2822.cpp b/codes/special/src/Rae2822.cpp index 8dc2c9b6..4f70a407 100644 --- a/codes/special/src/Rae2822.cpp +++ b/codes/special/src/Rae2822.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/SDomain.cpp b/codes/special/src/SDomain.cpp index 33a12285..b16de12e 100644 --- a/codes/special/src/SDomain.cpp +++ b/codes/special/src/SDomain.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/SegmentCtrl.cpp b/codes/special/src/SegmentCtrl.cpp index eebd7b6c..dbe45441 100644 --- a/codes/special/src/SegmentCtrl.cpp +++ b/codes/special/src/SegmentCtrl.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/SimpleDomain.cpp b/codes/special/src/SimpleDomain.cpp index 7af0f52c..1ffcda63 100644 --- a/codes/special/src/SimpleDomain.cpp +++ b/codes/special/src/SimpleDomain.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/StrBcSetting.cpp b/codes/special/src/StrBcSetting.cpp index 7af5f625..65532b89 100644 --- a/codes/special/src/StrBcSetting.cpp +++ b/codes/special/src/StrBcSetting.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/special/src/Transfinite.cpp b/codes/special/src/Transfinite.cpp index b64f418d..27bf951b 100644 --- a/codes/special/src/Transfinite.cpp +++ b/codes/special/src/Transfinite.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/ActionMap.h b/codes/task/include/ActionMap.h index 4dd7dd23..586ed55b 100644 --- a/codes/task/include/ActionMap.h +++ b/codes/task/include/ActionMap.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/ActionState.h b/codes/task/include/ActionState.h index cf68b21e..1efbc76e 100644 --- a/codes/task/include/ActionState.h +++ b/codes/task/include/ActionState.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/Category.h b/codes/task/include/Category.h index f8b50ebc..6eeb5c9a 100644 --- a/codes/task/include/Category.h +++ b/codes/task/include/Category.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/CmxTask.h b/codes/task/include/CmxTask.h index 7f24d162..94e41c78 100644 --- a/codes/task/include/CmxTask.h +++ b/codes/task/include/CmxTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/Command.h b/codes/task/include/Command.h index b1687ab1..9a3ba4e7 100644 --- a/codes/task/include/Command.h +++ b/codes/task/include/Command.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/FileInfo.h b/codes/task/include/FileInfo.h index e3080ceb..8b481ccf 100644 --- a/codes/task/include/FileInfo.h +++ b/codes/task/include/FileInfo.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/GridState.h b/codes/task/include/GridState.h index 25a4ca05..17ea7c5b 100644 --- a/codes/task/include/GridState.h +++ b/codes/task/include/GridState.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/InterfaceTask.h b/codes/task/include/InterfaceTask.h index 75a6279c..7b9e4e57 100644 --- a/codes/task/include/InterfaceTask.h +++ b/codes/task/include/InterfaceTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/OversetTask.h b/codes/task/include/OversetTask.h index 602284ef..43a6363a 100644 --- a/codes/task/include/OversetTask.h +++ b/codes/task/include/OversetTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/ReadTask.h b/codes/task/include/ReadTask.h index 1cca8d9a..182b2ae6 100644 --- a/codes/task/include/ReadTask.h +++ b/codes/task/include/ReadTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/SimpleTask.h b/codes/task/include/SimpleTask.h index d935e7f9..7e842b12 100644 --- a/codes/task/include/SimpleTask.h +++ b/codes/task/include/SimpleTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/State.h b/codes/task/include/State.h index 964de4d3..6ab584bf 100644 --- a/codes/task/include/State.h +++ b/codes/task/include/State.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/Task.h b/codes/task/include/Task.h index e1558c32..39cd07c5 100644 --- a/codes/task/include/Task.h +++ b/codes/task/include/Task.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/TaskCom.h b/codes/task/include/TaskCom.h index 1cbcc2ab..dd40940d 100644 --- a/codes/task/include/TaskCom.h +++ b/codes/task/include/TaskCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/TaskImp.h b/codes/task/include/TaskImp.h index cd721b63..0a88830f 100644 --- a/codes/task/include/TaskImp.h +++ b/codes/task/include/TaskImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/TaskRegister.h b/codes/task/include/TaskRegister.h index 9423dff4..b9ee15cf 100644 --- a/codes/task/include/TaskRegister.h +++ b/codes/task/include/TaskRegister.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/TaskState.h b/codes/task/include/TaskState.h index 6fdb8d00..2c849f93 100644 --- a/codes/task/include/TaskState.h +++ b/codes/task/include/TaskState.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/include/WriteTask.h b/codes/task/include/WriteTask.h index 66d9fc08..8fb768a6 100644 --- a/codes/task/include/WriteTask.h +++ b/codes/task/include/WriteTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/ActionMap.cpp b/codes/task/src/ActionMap.cpp index bfaab80a..e929655b 100644 --- a/codes/task/src/ActionMap.cpp +++ b/codes/task/src/ActionMap.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/ActionState.cpp b/codes/task/src/ActionState.cpp index 5582c1be..490c06af 100644 --- a/codes/task/src/ActionState.cpp +++ b/codes/task/src/ActionState.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/Category.cpp b/codes/task/src/Category.cpp index 8d4610dd..b795aff9 100644 --- a/codes/task/src/Category.cpp +++ b/codes/task/src/Category.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/CmxTask.cpp b/codes/task/src/CmxTask.cpp index 3de1df2e..65e011fc 100644 --- a/codes/task/src/CmxTask.cpp +++ b/codes/task/src/CmxTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/Command.cpp b/codes/task/src/Command.cpp index df75c92e..284e166c 100644 --- a/codes/task/src/Command.cpp +++ b/codes/task/src/Command.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/FileInfo.cpp b/codes/task/src/FileInfo.cpp index 412daa6a..e93d1bd8 100644 --- a/codes/task/src/FileInfo.cpp +++ b/codes/task/src/FileInfo.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/GridState.cpp b/codes/task/src/GridState.cpp index f7a1398b..b4eb63e1 100644 --- a/codes/task/src/GridState.cpp +++ b/codes/task/src/GridState.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/InterfaceTask.cpp b/codes/task/src/InterfaceTask.cpp index e80ed68c..e7c31109 100644 --- a/codes/task/src/InterfaceTask.cpp +++ b/codes/task/src/InterfaceTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/OversetTask.cpp b/codes/task/src/OversetTask.cpp index 6de91732..56c578e6 100644 --- a/codes/task/src/OversetTask.cpp +++ b/codes/task/src/OversetTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/ReadTask.cpp b/codes/task/src/ReadTask.cpp index 28a1a2dc..62bf0d2c 100644 --- a/codes/task/src/ReadTask.cpp +++ b/codes/task/src/ReadTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/SimpleTask.cpp b/codes/task/src/SimpleTask.cpp index 48739c7c..049fd0cc 100644 --- a/codes/task/src/SimpleTask.cpp +++ b/codes/task/src/SimpleTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/State.cpp b/codes/task/src/State.cpp index 304fc08c..8bed39f3 100644 --- a/codes/task/src/State.cpp +++ b/codes/task/src/State.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/Task.cpp b/codes/task/src/Task.cpp index ab3fbe6b..5981c9c7 100644 --- a/codes/task/src/Task.cpp +++ b/codes/task/src/Task.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/TaskCom.cpp b/codes/task/src/TaskCom.cpp index 52c17942..15b6e448 100644 --- a/codes/task/src/TaskCom.cpp +++ b/codes/task/src/TaskCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/TaskImp.cpp b/codes/task/src/TaskImp.cpp index a32caa29..eb1816ca 100644 --- a/codes/task/src/TaskImp.cpp +++ b/codes/task/src/TaskImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/TaskRegister.cpp b/codes/task/src/TaskRegister.cpp index 2671e26f..4df159ce 100644 --- a/codes/task/src/TaskRegister.cpp +++ b/codes/task/src/TaskRegister.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/TaskState.cpp b/codes/task/src/TaskState.cpp index f3b62bb8..8a082242 100644 --- a/codes/task/src/TaskState.cpp +++ b/codes/task/src/TaskState.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/task/src/WriteTask.cpp b/codes/task/src/WriteTask.cpp index 20906cc7..1eecb26a 100644 --- a/codes/task/src/WriteTask.cpp +++ b/codes/task/src/WriteTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/test/include/JsonTest.h b/codes/test/include/JsonTest.h index 8c0d7385..dd773b41 100644 --- a/codes/test/include/JsonTest.h +++ b/codes/test/include/JsonTest.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/test/include/Test.h b/codes/test/include/Test.h index 2b31334d..92e56818 100644 --- a/codes/test/include/Test.h +++ b/codes/test/include/Test.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/test/src/JsonTest.cpp b/codes/test/src/JsonTest.cpp index fe733609..9ff8ac3e 100644 --- a/codes/test/src/JsonTest.cpp +++ b/codes/test/src/JsonTest.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/test/src/Test.cpp b/codes/test/src/Test.cpp index 799256de..b9cbfc2c 100644 --- a/codes/test/src/Test.cpp +++ b/codes/test/src/Test.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/theory/include/Sod.h b/codes/theory/include/Sod.h index b5e37290..88c6e3b6 100644 --- a/codes/theory/include/Sod.h +++ b/codes/theory/include/Sod.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/theory/include/Theory.h b/codes/theory/include/Theory.h index 5e065091..ae664397 100644 --- a/codes/theory/include/Theory.h +++ b/codes/theory/include/Theory.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/theory/src/Sod.cpp b/codes/theory/src/Sod.cpp index 19cf4ea1..b806e9e4 100644 --- a/codes/theory/src/Sod.cpp +++ b/codes/theory/src/Sod.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/theory/src/Theory.cpp b/codes/theory/src/Theory.cpp index 4f197863..e7e23d4a 100644 --- a/codes/theory/src/Theory.cpp +++ b/codes/theory/src/Theory.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/time/include/TimeSpan.h b/codes/time/include/TimeSpan.h index d66b0a8c..24174e9a 100644 --- a/codes/time/include/TimeSpan.h +++ b/codes/time/include/TimeSpan.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/time/include/TimeTest.h b/codes/time/include/TimeTest.h index 0f69c986..8bd99c56 100644 --- a/codes/time/include/TimeTest.h +++ b/codes/time/include/TimeTest.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/time/src/TimeSpan.cpp b/codes/time/src/TimeSpan.cpp index 969189fa..d62b8ceb 100644 --- a/codes/time/src/TimeSpan.cpp +++ b/codes/time/src/TimeSpan.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/time/src/TimeTest.cpp b/codes/time/src/TimeTest.cpp index c1a588d3..6d2b8b2e 100644 --- a/codes/time/src/TimeTest.cpp +++ b/codes/time/src/TimeTest.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbBcSolver.h b/codes/turb/include/TurbBcSolver.h index 3cb9eeac..a582aac1 100644 --- a/codes/turb/include/TurbBcSolver.h +++ b/codes/turb/include/TurbBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbCom.h b/codes/turb/include/TurbCom.h index 1055af04..04b867e1 100644 --- a/codes/turb/include/TurbCom.h +++ b/codes/turb/include/TurbCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbCtrl.h b/codes/turb/include/TurbCtrl.h index 3e51adf3..e920811f 100644 --- a/codes/turb/include/TurbCtrl.h +++ b/codes/turb/include/TurbCtrl.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbInvFlux.h b/codes/turb/include/TurbInvFlux.h index f942baab..14e437b9 100644 --- a/codes/turb/include/TurbInvFlux.h +++ b/codes/turb/include/TurbInvFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbLusgs.h b/codes/turb/include/TurbLusgs.h index 52f57eab..680cc239 100644 --- a/codes/turb/include/TurbLusgs.h +++ b/codes/turb/include/TurbLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbRestart.h b/codes/turb/include/TurbRestart.h index e2b00793..cef6e486 100644 --- a/codes/turb/include/TurbRestart.h +++ b/codes/turb/include/TurbRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbRhs.h b/codes/turb/include/TurbRhs.h index 6b214b2d..606dbdd6 100644 --- a/codes/turb/include/TurbRhs.h +++ b/codes/turb/include/TurbRhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbSolver.h b/codes/turb/include/TurbSolver.h index 8bf2a278..3e883dc4 100644 --- a/codes/turb/include/TurbSolver.h +++ b/codes/turb/include/TurbSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbSolverImp.h b/codes/turb/include/TurbSolverImp.h index b4680578..763a82dc 100644 --- a/codes/turb/include/TurbSolverImp.h +++ b/codes/turb/include/TurbSolverImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbSpectrum.h b/codes/turb/include/TurbSpectrum.h index 59c455f7..097c295f 100644 --- a/codes/turb/include/TurbSpectrum.h +++ b/codes/turb/include/TurbSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbSrcFlux.h b/codes/turb/include/TurbSrcFlux.h index 1a96e98b..00b151d9 100644 --- a/codes/turb/include/TurbSrcFlux.h +++ b/codes/turb/include/TurbSrcFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbTrans.h b/codes/turb/include/TurbTrans.h index f01acbf9..9eae03dc 100644 --- a/codes/turb/include/TurbTrans.h +++ b/codes/turb/include/TurbTrans.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbUnsteady.h b/codes/turb/include/TurbUnsteady.h index 7358cb9f..fa57238b 100644 --- a/codes/turb/include/TurbUnsteady.h +++ b/codes/turb/include/TurbUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbUpdate.h b/codes/turb/include/TurbUpdate.h index 6fd017bf..b4ee7c33 100644 --- a/codes/turb/include/TurbUpdate.h +++ b/codes/turb/include/TurbUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/include/TurbVisFlux.h b/codes/turb/include/TurbVisFlux.h index d90048b3..83f29180 100644 --- a/codes/turb/include/TurbVisFlux.h +++ b/codes/turb/include/TurbVisFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbBcSolver.cpp b/codes/turb/src/TurbBcSolver.cpp index 9421ba9d..8f5bac59 100644 --- a/codes/turb/src/TurbBcSolver.cpp +++ b/codes/turb/src/TurbBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbCom.cpp b/codes/turb/src/TurbCom.cpp index 56282055..951e0ee2 100644 --- a/codes/turb/src/TurbCom.cpp +++ b/codes/turb/src/TurbCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbCtrl.cpp b/codes/turb/src/TurbCtrl.cpp index b034aaea..105ac93f 100644 --- a/codes/turb/src/TurbCtrl.cpp +++ b/codes/turb/src/TurbCtrl.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbInvFlux.cpp b/codes/turb/src/TurbInvFlux.cpp index a6a9ca81..8eb36686 100644 --- a/codes/turb/src/TurbInvFlux.cpp +++ b/codes/turb/src/TurbInvFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbLusgs.cpp b/codes/turb/src/TurbLusgs.cpp index 70fad37e..29d9668b 100644 --- a/codes/turb/src/TurbLusgs.cpp +++ b/codes/turb/src/TurbLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbRestart.cpp b/codes/turb/src/TurbRestart.cpp index 57e35c30..cc877718 100644 --- a/codes/turb/src/TurbRestart.cpp +++ b/codes/turb/src/TurbRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbRhs.cpp b/codes/turb/src/TurbRhs.cpp index 88688325..60974424 100644 --- a/codes/turb/src/TurbRhs.cpp +++ b/codes/turb/src/TurbRhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbSolver.cpp b/codes/turb/src/TurbSolver.cpp index 0078e60b..75412357 100644 --- a/codes/turb/src/TurbSolver.cpp +++ b/codes/turb/src/TurbSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbSolverImp.cpp b/codes/turb/src/TurbSolverImp.cpp index e783ffa3..6c795ce2 100644 --- a/codes/turb/src/TurbSolverImp.cpp +++ b/codes/turb/src/TurbSolverImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbSpectrum.cpp b/codes/turb/src/TurbSpectrum.cpp index b16e0c89..0eaf01da 100644 --- a/codes/turb/src/TurbSpectrum.cpp +++ b/codes/turb/src/TurbSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbSrcFlux.cpp b/codes/turb/src/TurbSrcFlux.cpp index 6f17ed8e..d66ba359 100644 --- a/codes/turb/src/TurbSrcFlux.cpp +++ b/codes/turb/src/TurbSrcFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbTrans.cpp b/codes/turb/src/TurbTrans.cpp index a779957a..8d8eceda 100644 --- a/codes/turb/src/TurbTrans.cpp +++ b/codes/turb/src/TurbTrans.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbUnsteady.cpp b/codes/turb/src/TurbUnsteady.cpp index 8b5ac73c..64863a8b 100644 --- a/codes/turb/src/TurbUnsteady.cpp +++ b/codes/turb/src/TurbUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbUpdate.cpp b/codes/turb/src/TurbUpdate.cpp index 1203a58f..ff9b78b3 100644 --- a/codes/turb/src/TurbUpdate.cpp +++ b/codes/turb/src/TurbUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/turb/src/TurbVisFlux.cpp b/codes/turb/src/TurbVisFlux.cpp index 0374fa5e..6ddc2ead 100644 --- a/codes/turb/src/TurbVisFlux.cpp +++ b/codes/turb/src/TurbVisFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsBcSolver.h b/codes/uins/include/UINsBcSolver.h index 767caca6..38f8637e 100644 --- a/codes/uins/include/UINsBcSolver.h +++ b/codes/uins/include/UINsBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsCom.h b/codes/uins/include/UINsCom.h index 01c53c61..2be66660 100644 --- a/codes/uins/include/UINsCom.h +++ b/codes/uins/include/UINsCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsGrad.h b/codes/uins/include/UINsGrad.h index 56afae0a..b0e0417e 100644 --- a/codes/uins/include/UINsGrad.h +++ b/codes/uins/include/UINsGrad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsInvterm.h b/codes/uins/include/UINsInvterm.h index b788c598..3dcc4e02 100644 --- a/codes/uins/include/UINsInvterm.h +++ b/codes/uins/include/UINsInvterm.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsLimiter.h b/codes/uins/include/UINsLimiter.h index 8ace7276..f3c14124 100644 --- a/codes/uins/include/UINsLimiter.h +++ b/codes/uins/include/UINsLimiter.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsLusgs.h b/codes/uins/include/UINsLusgs.h index 65fc03c3..f2dc330b 100644 --- a/codes/uins/include/UINsLusgs.h +++ b/codes/uins/include/UINsLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsRestart.h b/codes/uins/include/UINsRestart.h index da13216b..0841f318 100644 --- a/codes/uins/include/UINsRestart.h +++ b/codes/uins/include/UINsRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsSolver.h b/codes/uins/include/UINsSolver.h index 2b805cbe..d418d811 100644 --- a/codes/uins/include/UINsSolver.h +++ b/codes/uins/include/UINsSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsSpectrum.h b/codes/uins/include/UINsSpectrum.h index f2c7702e..b344b264 100644 --- a/codes/uins/include/UINsSpectrum.h +++ b/codes/uins/include/UINsSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsUnsteady.h b/codes/uins/include/UINsUnsteady.h index 63ddd713..3f18a73b 100644 --- a/codes/uins/include/UINsUnsteady.h +++ b/codes/uins/include/UINsUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsUpdate.h b/codes/uins/include/UINsUpdate.h index 0411049d..d0dd5967 100644 --- a/codes/uins/include/UINsUpdate.h +++ b/codes/uins/include/UINsUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/include/UINsVisterm.h b/codes/uins/include/UINsVisterm.h index 9a5326e4..379ad416 100644 --- a/codes/uins/include/UINsVisterm.h +++ b/codes/uins/include/UINsVisterm.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsBcSolver.cpp b/codes/uins/src/UINsBcSolver.cpp index 3712e12d..3a32f636 100644 --- a/codes/uins/src/UINsBcSolver.cpp +++ b/codes/uins/src/UINsBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsCom.cpp b/codes/uins/src/UINsCom.cpp index 5b2961ca..36be6509 100644 --- a/codes/uins/src/UINsCom.cpp +++ b/codes/uins/src/UINsCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsGrad.cpp b/codes/uins/src/UINsGrad.cpp index c49baf17..0d79c532 100644 --- a/codes/uins/src/UINsGrad.cpp +++ b/codes/uins/src/UINsGrad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsInvterm.cpp b/codes/uins/src/UINsInvterm.cpp index 22c70e32..9ba1ad0b 100644 --- a/codes/uins/src/UINsInvterm.cpp +++ b/codes/uins/src/UINsInvterm.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsLimiter.cpp b/codes/uins/src/UINsLimiter.cpp index ebfede29..91623e2e 100644 --- a/codes/uins/src/UINsLimiter.cpp +++ b/codes/uins/src/UINsLimiter.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsLusgs.cpp b/codes/uins/src/UINsLusgs.cpp index 4f3212c9..2dd9e80d 100644 --- a/codes/uins/src/UINsLusgs.cpp +++ b/codes/uins/src/UINsLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsRestart.cpp b/codes/uins/src/UINsRestart.cpp index 65dc00b5..6b056f8e 100644 --- a/codes/uins/src/UINsRestart.cpp +++ b/codes/uins/src/UINsRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsSolver.cpp b/codes/uins/src/UINsSolver.cpp index b93057fc..fe31de51 100644 --- a/codes/uins/src/UINsSolver.cpp +++ b/codes/uins/src/UINsSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsSpectrum.cpp b/codes/uins/src/UINsSpectrum.cpp index e3158406..6aad4702 100644 --- a/codes/uins/src/UINsSpectrum.cpp +++ b/codes/uins/src/UINsSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsUnsteady.cpp b/codes/uins/src/UINsUnsteady.cpp index 99c86be1..e6211e71 100644 --- a/codes/uins/src/UINsUnsteady.cpp +++ b/codes/uins/src/UINsUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsUpdate.cpp b/codes/uins/src/UINsUpdate.cpp index 719d40d3..f281ce9d 100644 --- a/codes/uins/src/UINsUpdate.cpp +++ b/codes/uins/src/UINsUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uins/src/UINsVisterm.cpp b/codes/uins/src/UINsVisterm.cpp index 2f2e4713..e0a61410 100644 --- a/codes/uins/src/UINsVisterm.cpp +++ b/codes/uins/src/UINsVisterm.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsBcSolver.h b/codes/uns/include/UNsBcSolver.h index fca6778d..f3ea85fb 100644 --- a/codes/uns/include/UNsBcSolver.h +++ b/codes/uns/include/UNsBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsCom.h b/codes/uns/include/UNsCom.h index df967f11..39bc3362 100644 --- a/codes/uns/include/UNsCom.h +++ b/codes/uns/include/UNsCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsGrad.h b/codes/uns/include/UNsGrad.h index a88bbe5b..09658439 100644 --- a/codes/uns/include/UNsGrad.h +++ b/codes/uns/include/UNsGrad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsInvFlux.h b/codes/uns/include/UNsInvFlux.h index ec00cead..bd8036c3 100644 --- a/codes/uns/include/UNsInvFlux.h +++ b/codes/uns/include/UNsInvFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsLimiter.h b/codes/uns/include/UNsLimiter.h index 9e738a92..4050f42f 100644 --- a/codes/uns/include/UNsLimiter.h +++ b/codes/uns/include/UNsLimiter.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsLusgs.h b/codes/uns/include/UNsLusgs.h index 12f43330..86863a10 100644 --- a/codes/uns/include/UNsLusgs.h +++ b/codes/uns/include/UNsLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsRestart.h b/codes/uns/include/UNsRestart.h index 2d6446d7..0f12ce0f 100644 --- a/codes/uns/include/UNsRestart.h +++ b/codes/uns/include/UNsRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsSolver.h b/codes/uns/include/UNsSolver.h index 9247863f..a43123b1 100644 --- a/codes/uns/include/UNsSolver.h +++ b/codes/uns/include/UNsSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsSpectrum.h b/codes/uns/include/UNsSpectrum.h index 987531bd..27812c82 100644 --- a/codes/uns/include/UNsSpectrum.h +++ b/codes/uns/include/UNsSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsUnsteady.h b/codes/uns/include/UNsUnsteady.h index ab669a03..9c580e63 100644 --- a/codes/uns/include/UNsUnsteady.h +++ b/codes/uns/include/UNsUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsUpdate.h b/codes/uns/include/UNsUpdate.h index f87ce6f2..a2213766 100644 --- a/codes/uns/include/UNsUpdate.h +++ b/codes/uns/include/UNsUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UNsVisFlux.h b/codes/uns/include/UNsVisFlux.h index 560ed63b..bcc3c8b4 100644 --- a/codes/uns/include/UNsVisFlux.h +++ b/codes/uns/include/UNsVisFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/include/UTimeStep.h b/codes/uns/include/UTimeStep.h index 0ac2192f..a37ac716 100644 --- a/codes/uns/include/UTimeStep.h +++ b/codes/uns/include/UTimeStep.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsBcSolver.cpp b/codes/uns/src/UNsBcSolver.cpp index 6fba5ad3..140a2840 100644 --- a/codes/uns/src/UNsBcSolver.cpp +++ b/codes/uns/src/UNsBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsCom.cpp b/codes/uns/src/UNsCom.cpp index 99b0045d..f06f0f6b 100644 --- a/codes/uns/src/UNsCom.cpp +++ b/codes/uns/src/UNsCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsGrad.cpp b/codes/uns/src/UNsGrad.cpp index 4d30ebf6..9ca2711b 100644 --- a/codes/uns/src/UNsGrad.cpp +++ b/codes/uns/src/UNsGrad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsInvFlux.cpp b/codes/uns/src/UNsInvFlux.cpp index 73edae0b..69fff695 100644 --- a/codes/uns/src/UNsInvFlux.cpp +++ b/codes/uns/src/UNsInvFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsLimiter.cpp b/codes/uns/src/UNsLimiter.cpp index b41d5ab8..8be80768 100644 --- a/codes/uns/src/UNsLimiter.cpp +++ b/codes/uns/src/UNsLimiter.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsLusgs.cpp b/codes/uns/src/UNsLusgs.cpp index 933b7a0e..fefbbba2 100644 --- a/codes/uns/src/UNsLusgs.cpp +++ b/codes/uns/src/UNsLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsRestart.cpp b/codes/uns/src/UNsRestart.cpp index b9e27a83..38194a28 100644 --- a/codes/uns/src/UNsRestart.cpp +++ b/codes/uns/src/UNsRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsSolver.cpp b/codes/uns/src/UNsSolver.cpp index 2f6a78dc..93f27391 100644 --- a/codes/uns/src/UNsSolver.cpp +++ b/codes/uns/src/UNsSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsSpectrum.cpp b/codes/uns/src/UNsSpectrum.cpp index 756a49fa..705ff7bb 100644 --- a/codes/uns/src/UNsSpectrum.cpp +++ b/codes/uns/src/UNsSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsUnsteady.cpp b/codes/uns/src/UNsUnsteady.cpp index b6e64462..3cc3bf1d 100644 --- a/codes/uns/src/UNsUnsteady.cpp +++ b/codes/uns/src/UNsUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsUpdate.cpp b/codes/uns/src/UNsUpdate.cpp index 6b841b9b..239cc1b9 100644 --- a/codes/uns/src/UNsUpdate.cpp +++ b/codes/uns/src/UNsUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UNsVisFlux.cpp b/codes/uns/src/UNsVisFlux.cpp index dbde46c9..fe809c40 100644 --- a/codes/uns/src/UNsVisFlux.cpp +++ b/codes/uns/src/UNsVisFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uns/src/UTimeStep.cpp b/codes/uns/src/UTimeStep.cpp index 234eff66..16a66615 100644 --- a/codes/uns/src/UTimeStep.cpp +++ b/codes/uns/src/UTimeStep.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/Unsteady.h b/codes/unsteady/include/Unsteady.h index edefe68c..8d4d0458 100644 --- a/codes/unsteady/include/Unsteady.h +++ b/codes/unsteady/include/Unsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UnsteadyImp.h b/codes/unsteady/include/UnsteadyImp.h index 01b8aef4..93db079f 100644 --- a/codes/unsteady/include/UnsteadyImp.h +++ b/codes/unsteady/include/UnsteadyImp.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UnsteadyTaskReg.h b/codes/unsteady/include/UnsteadyTaskReg.h index fda635c2..9166fe4f 100644 --- a/codes/unsteady/include/UnsteadyTaskReg.h +++ b/codes/unsteady/include/UnsteadyTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UsdBasic.h b/codes/unsteady/include/UsdBasic.h index 07dd7875..c2758d84 100644 --- a/codes/unsteady/include/UsdBasic.h +++ b/codes/unsteady/include/UsdBasic.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UsdData.h b/codes/unsteady/include/UsdData.h index 699625b0..a1601f91 100644 --- a/codes/unsteady/include/UsdData.h +++ b/codes/unsteady/include/UsdData.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UsdField.h b/codes/unsteady/include/UsdField.h index 49364081..e57a2903 100644 --- a/codes/unsteady/include/UsdField.h +++ b/codes/unsteady/include/UsdField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/include/UsdPara.h b/codes/unsteady/include/UsdPara.h index 5cb0aff7..366c236b 100644 --- a/codes/unsteady/include/UsdPara.h +++ b/codes/unsteady/include/UsdPara.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/Unsteady.cpp b/codes/unsteady/src/Unsteady.cpp index 2fc33985..3f12a501 100644 --- a/codes/unsteady/src/Unsteady.cpp +++ b/codes/unsteady/src/Unsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UnsteadyImp.cpp b/codes/unsteady/src/UnsteadyImp.cpp index 9672a45d..e9949189 100644 --- a/codes/unsteady/src/UnsteadyImp.cpp +++ b/codes/unsteady/src/UnsteadyImp.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UnsteadyTaskReg.cpp b/codes/unsteady/src/UnsteadyTaskReg.cpp index 9dedae06..065c4b3d 100644 --- a/codes/unsteady/src/UnsteadyTaskReg.cpp +++ b/codes/unsteady/src/UnsteadyTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UsdBasic.cpp b/codes/unsteady/src/UsdBasic.cpp index 4130179a..25d4e51a 100644 --- a/codes/unsteady/src/UsdBasic.cpp +++ b/codes/unsteady/src/UsdBasic.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UsdData.cpp b/codes/unsteady/src/UsdData.cpp index 2d73b451..9d772d3f 100644 --- a/codes/unsteady/src/UsdData.cpp +++ b/codes/unsteady/src/UsdData.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UsdField.cpp b/codes/unsteady/src/UsdField.cpp index a1c924ed..823e8fc7 100644 --- a/codes/unsteady/src/UsdField.cpp +++ b/codes/unsteady/src/UsdField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/unsteady/src/UsdPara.cpp b/codes/unsteady/src/UsdPara.cpp index adca5477..62326be3 100644 --- a/codes/unsteady/src/UsdPara.cpp +++ b/codes/unsteady/src/UsdPara.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/update/include/Update.h b/codes/update/include/Update.h index 54605560..751f889d 100644 --- a/codes/update/include/Update.h +++ b/codes/update/include/Update.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/update/include/UpdateTaskReg.h b/codes/update/include/UpdateTaskReg.h index d467d2b3..584cd682 100644 --- a/codes/update/include/UpdateTaskReg.h +++ b/codes/update/include/UpdateTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/update/src/Update.cpp b/codes/update/src/Update.cpp index e92141a9..1111b2bd 100644 --- a/codes/update/src/Update.cpp +++ b/codes/update/src/Update.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/update/src/UpdateTaskReg.cpp b/codes/update/src/UpdateTaskReg.cpp index b5850892..9613e9e9 100644 --- a/codes/update/src/UpdateTaskReg.cpp +++ b/codes/update/src/UpdateTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UBcSolver.h b/codes/usolver/include/UBcSolver.h index 0b38cc82..512edf36 100644 --- a/codes/usolver/include/UBcSolver.h +++ b/codes/usolver/include/UBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UCom.h b/codes/usolver/include/UCom.h index 3d0d5653..4b36666f 100644 --- a/codes/usolver/include/UCom.h +++ b/codes/usolver/include/UCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UGrad.h b/codes/usolver/include/UGrad.h index 271dbd2b..7e7772e6 100644 --- a/codes/usolver/include/UGrad.h +++ b/codes/usolver/include/UGrad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/ULhs.h b/codes/usolver/include/ULhs.h index 7efc86c4..969055c4 100644 --- a/codes/usolver/include/ULhs.h +++ b/codes/usolver/include/ULhs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/ULimiter.h b/codes/usolver/include/ULimiter.h index 5b11cf5e..60300bd1 100644 --- a/codes/usolver/include/ULimiter.h +++ b/codes/usolver/include/ULimiter.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UResidual.h b/codes/usolver/include/UResidual.h index 71f77c29..ff6012f5 100644 --- a/codes/usolver/include/UResidual.h +++ b/codes/usolver/include/UResidual.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UUnsteady.h b/codes/usolver/include/UUnsteady.h index 9a4014f2..7ca4db91 100644 --- a/codes/usolver/include/UUnsteady.h +++ b/codes/usolver/include/UUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/UVisualize.h b/codes/usolver/include/UVisualize.h index 471f2f7f..a74cc19b 100644 --- a/codes/usolver/include/UVisualize.h +++ b/codes/usolver/include/UVisualize.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/include/VisGrad.h b/codes/usolver/include/VisGrad.h index 0ce2142d..79b72f84 100644 --- a/codes/usolver/include/VisGrad.h +++ b/codes/usolver/include/VisGrad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UBcSolver.cpp b/codes/usolver/src/UBcSolver.cpp index 9a063a1d..2f852753 100644 --- a/codes/usolver/src/UBcSolver.cpp +++ b/codes/usolver/src/UBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UCom.cpp b/codes/usolver/src/UCom.cpp index 1ab83455..a271644c 100644 --- a/codes/usolver/src/UCom.cpp +++ b/codes/usolver/src/UCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UGrad.cpp b/codes/usolver/src/UGrad.cpp index cb46778a..da9596f2 100644 --- a/codes/usolver/src/UGrad.cpp +++ b/codes/usolver/src/UGrad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/ULhs.cpp b/codes/usolver/src/ULhs.cpp index b21c9ff3..8cd972e3 100644 --- a/codes/usolver/src/ULhs.cpp +++ b/codes/usolver/src/ULhs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/ULimiter.cpp b/codes/usolver/src/ULimiter.cpp index e0b028c7..1a52b8d9 100644 --- a/codes/usolver/src/ULimiter.cpp +++ b/codes/usolver/src/ULimiter.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UResidual.cpp b/codes/usolver/src/UResidual.cpp index e4a7370f..aa81506b 100644 --- a/codes/usolver/src/UResidual.cpp +++ b/codes/usolver/src/UResidual.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UUnsteady.cpp b/codes/usolver/src/UUnsteady.cpp index c6218509..594cb4cf 100644 --- a/codes/usolver/src/UUnsteady.cpp +++ b/codes/usolver/src/UUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/UVisualize.cpp b/codes/usolver/src/UVisualize.cpp index f15e9eec..36dae893 100644 --- a/codes/usolver/src/UVisualize.cpp +++ b/codes/usolver/src/UVisualize.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/usolver/src/VisGrad.cpp b/codes/usolver/src/VisGrad.cpp index 1606a370..0c907e74 100644 --- a/codes/usolver/src/VisGrad.cpp +++ b/codes/usolver/src/VisGrad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbBcSolver.h b/codes/uturb/include/UTurbBcSolver.h index 4cb3e5ff..a225431e 100644 --- a/codes/uturb/include/UTurbBcSolver.h +++ b/codes/uturb/include/UTurbBcSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbCom.h b/codes/uturb/include/UTurbCom.h index f9ea5ae8..2e94bcfe 100644 --- a/codes/uturb/include/UTurbCom.h +++ b/codes/uturb/include/UTurbCom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbGrad.h b/codes/uturb/include/UTurbGrad.h index 542d442f..adc4dd68 100644 --- a/codes/uturb/include/UTurbGrad.h +++ b/codes/uturb/include/UTurbGrad.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbInvFlux.h b/codes/uturb/include/UTurbInvFlux.h index df3e9374..c8ce2ce8 100644 --- a/codes/uturb/include/UTurbInvFlux.h +++ b/codes/uturb/include/UTurbInvFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbLimiter.h b/codes/uturb/include/UTurbLimiter.h index ac75129e..4b946cb4 100644 --- a/codes/uturb/include/UTurbLimiter.h +++ b/codes/uturb/include/UTurbLimiter.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbLusgs.h b/codes/uturb/include/UTurbLusgs.h index 8eda4a15..b7937785 100644 --- a/codes/uturb/include/UTurbLusgs.h +++ b/codes/uturb/include/UTurbLusgs.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbRestart.h b/codes/uturb/include/UTurbRestart.h index fa86de2c..a5be3f93 100644 --- a/codes/uturb/include/UTurbRestart.h +++ b/codes/uturb/include/UTurbRestart.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbSolver.h b/codes/uturb/include/UTurbSolver.h index c490fc23..b6ebc330 100644 --- a/codes/uturb/include/UTurbSolver.h +++ b/codes/uturb/include/UTurbSolver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbSpectrum.h b/codes/uturb/include/UTurbSpectrum.h index f3ecb81c..f2a9cbbe 100644 --- a/codes/uturb/include/UTurbSpectrum.h +++ b/codes/uturb/include/UTurbSpectrum.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbSrcFlux.h b/codes/uturb/include/UTurbSrcFlux.h index db519c0e..031b1b86 100644 --- a/codes/uturb/include/UTurbSrcFlux.h +++ b/codes/uturb/include/UTurbSrcFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbUnsteady.h b/codes/uturb/include/UTurbUnsteady.h index 90f358e0..ed29d4a7 100644 --- a/codes/uturb/include/UTurbUnsteady.h +++ b/codes/uturb/include/UTurbUnsteady.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbUpdate.h b/codes/uturb/include/UTurbUpdate.h index 79c6ce0a..9d90d4c3 100644 --- a/codes/uturb/include/UTurbUpdate.h +++ b/codes/uturb/include/UTurbUpdate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/include/UTurbVisFlux.h b/codes/uturb/include/UTurbVisFlux.h index 7de2ec2c..574f30d2 100644 --- a/codes/uturb/include/UTurbVisFlux.h +++ b/codes/uturb/include/UTurbVisFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbBcSolver.cpp b/codes/uturb/src/UTurbBcSolver.cpp index 26331bf2..373be97e 100644 --- a/codes/uturb/src/UTurbBcSolver.cpp +++ b/codes/uturb/src/UTurbBcSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbCom.cpp b/codes/uturb/src/UTurbCom.cpp index d5d8fa61..534a7a33 100644 --- a/codes/uturb/src/UTurbCom.cpp +++ b/codes/uturb/src/UTurbCom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbGrad.cpp b/codes/uturb/src/UTurbGrad.cpp index ca77d44c..dac38ce8 100644 --- a/codes/uturb/src/UTurbGrad.cpp +++ b/codes/uturb/src/UTurbGrad.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbInvFlux.cpp b/codes/uturb/src/UTurbInvFlux.cpp index b1525fd1..43f5c816 100644 --- a/codes/uturb/src/UTurbInvFlux.cpp +++ b/codes/uturb/src/UTurbInvFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbLimiter.cpp b/codes/uturb/src/UTurbLimiter.cpp index 8bcf7a63..9e5d7bf6 100644 --- a/codes/uturb/src/UTurbLimiter.cpp +++ b/codes/uturb/src/UTurbLimiter.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbLusgs.cpp b/codes/uturb/src/UTurbLusgs.cpp index 1a7b65dd..b21a618c 100644 --- a/codes/uturb/src/UTurbLusgs.cpp +++ b/codes/uturb/src/UTurbLusgs.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbRestart.cpp b/codes/uturb/src/UTurbRestart.cpp index 2ba56045..4f0f3b46 100644 --- a/codes/uturb/src/UTurbRestart.cpp +++ b/codes/uturb/src/UTurbRestart.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbSolver.cpp b/codes/uturb/src/UTurbSolver.cpp index 2c30aa8e..faed0db5 100644 --- a/codes/uturb/src/UTurbSolver.cpp +++ b/codes/uturb/src/UTurbSolver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbSpectrum.cpp b/codes/uturb/src/UTurbSpectrum.cpp index 69cd5e9f..2dc7a4eb 100644 --- a/codes/uturb/src/UTurbSpectrum.cpp +++ b/codes/uturb/src/UTurbSpectrum.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbSrcFlux.cpp b/codes/uturb/src/UTurbSrcFlux.cpp index e4c0fa23..73596fa3 100644 --- a/codes/uturb/src/UTurbSrcFlux.cpp +++ b/codes/uturb/src/UTurbSrcFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbUnsteady.cpp b/codes/uturb/src/UTurbUnsteady.cpp index d77cf95b..9d5c430f 100644 --- a/codes/uturb/src/UTurbUnsteady.cpp +++ b/codes/uturb/src/UTurbUnsteady.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbUpdate.cpp b/codes/uturb/src/UTurbUpdate.cpp index f3da1b78..7208b8a7 100644 --- a/codes/uturb/src/UTurbUpdate.cpp +++ b/codes/uturb/src/UTurbUpdate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/uturb/src/UTurbVisFlux.cpp b/codes/uturb/src/UTurbVisFlux.cpp index 4ba6faa3..2114da29 100644 --- a/codes/uturb/src/UTurbVisFlux.cpp +++ b/codes/uturb/src/UTurbVisFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/FaceJoint.h b/codes/visual/include/FaceJoint.h index 8fa0cdc0..ee817d90 100644 --- a/codes/visual/include/FaceJoint.h +++ b/codes/visual/include/FaceJoint.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/HeatFlux.h b/codes/visual/include/HeatFlux.h index 3e3a1853..eb2e623c 100644 --- a/codes/visual/include/HeatFlux.h +++ b/codes/visual/include/HeatFlux.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/HeatFluxTask.h b/codes/visual/include/HeatFluxTask.h index 1e8a1816..dcbc2afb 100644 --- a/codes/visual/include/HeatFluxTask.h +++ b/codes/visual/include/HeatFluxTask.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/HeatFluxTaskReg.h b/codes/visual/include/HeatFluxTaskReg.h index 089d3c31..bb51cb0a 100644 --- a/codes/visual/include/HeatFluxTaskReg.h +++ b/codes/visual/include/HeatFluxTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/LaminarPlate.h b/codes/visual/include/LaminarPlate.h index 6dde6766..567d8e96 100644 --- a/codes/visual/include/LaminarPlate.h +++ b/codes/visual/include/LaminarPlate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/NodeField.h b/codes/visual/include/NodeField.h index 8bc5f0bb..3bc54f56 100644 --- a/codes/visual/include/NodeField.h +++ b/codes/visual/include/NodeField.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/Plate.h b/codes/visual/include/Plate.h index b7c65576..ae84df86 100644 --- a/codes/visual/include/Plate.h +++ b/codes/visual/include/Plate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/TurbPlate.h b/codes/visual/include/TurbPlate.h index e6cfab7f..b08bb4ae 100644 --- a/codes/visual/include/TurbPlate.h +++ b/codes/visual/include/TurbPlate.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/VisualTaskReg.h b/codes/visual/include/VisualTaskReg.h index 5a941c98..2c7b0b38 100644 --- a/codes/visual/include/VisualTaskReg.h +++ b/codes/visual/include/VisualTaskReg.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/Visualize.h b/codes/visual/include/Visualize.h index 69d09092..06fbb72d 100644 --- a/codes/visual/include/Visualize.h +++ b/codes/visual/include/Visualize.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/include/WallVisual.h b/codes/visual/include/WallVisual.h index 560bc2f7..12989cbf 100644 --- a/codes/visual/include/WallVisual.h +++ b/codes/visual/include/WallVisual.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/FaceJoint.cpp b/codes/visual/src/FaceJoint.cpp index 9c66fa4c..d5af8dc7 100644 --- a/codes/visual/src/FaceJoint.cpp +++ b/codes/visual/src/FaceJoint.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/HeatFlux.cpp b/codes/visual/src/HeatFlux.cpp index ebb73cd3..c9dea237 100644 --- a/codes/visual/src/HeatFlux.cpp +++ b/codes/visual/src/HeatFlux.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/HeatFluxTask.cpp b/codes/visual/src/HeatFluxTask.cpp index 0eb95ae2..e19c8295 100644 --- a/codes/visual/src/HeatFluxTask.cpp +++ b/codes/visual/src/HeatFluxTask.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/HeatFluxTaskReg.cpp b/codes/visual/src/HeatFluxTaskReg.cpp index a53c1239..08a2b4a9 100644 --- a/codes/visual/src/HeatFluxTaskReg.cpp +++ b/codes/visual/src/HeatFluxTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/LaminarPlate.cpp b/codes/visual/src/LaminarPlate.cpp index c40dcc2f..aea132e1 100644 --- a/codes/visual/src/LaminarPlate.cpp +++ b/codes/visual/src/LaminarPlate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/NodeField.cpp b/codes/visual/src/NodeField.cpp index 7cadaf7c..60192c1c 100644 --- a/codes/visual/src/NodeField.cpp +++ b/codes/visual/src/NodeField.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/Plate.cpp b/codes/visual/src/Plate.cpp index 0ebf0d65..dca1dc6f 100644 --- a/codes/visual/src/Plate.cpp +++ b/codes/visual/src/Plate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/TurbPlate.cpp b/codes/visual/src/TurbPlate.cpp index 7cbd56bb..d2dd541a 100644 --- a/codes/visual/src/TurbPlate.cpp +++ b/codes/visual/src/TurbPlate.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/VisualTaskReg.cpp b/codes/visual/src/VisualTaskReg.cpp index f97967a7..ad967dab 100644 --- a/codes/visual/src/VisualTaskReg.cpp +++ b/codes/visual/src/VisualTaskReg.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/Visualize.cpp b/codes/visual/src/Visualize.cpp index bf67f6b5..0e78c44c 100644 --- a/codes/visual/src/Visualize.cpp +++ b/codes/visual/src/Visualize.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/visual/src/WallVisual.cpp b/codes/visual/src/WallVisual.cpp index ffec8e1e..36c9d728 100644 --- a/codes/visual/src/WallVisual.cpp +++ b/codes/visual/src/WallVisual.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/include/GridGroup.h b/codes/zone/include/GridGroup.h index abd79d3f..d77ad080 100644 --- a/codes/zone/include/GridGroup.h +++ b/codes/zone/include/GridGroup.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/include/MultiBlock.h b/codes/zone/include/MultiBlock.h index 928afb7b..c47fdf4d 100644 --- a/codes/zone/include/MultiBlock.h +++ b/codes/zone/include/MultiBlock.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/include/Zone.h b/codes/zone/include/Zone.h index 757b0ce2..4afe7349 100644 --- a/codes/zone/include/Zone.h +++ b/codes/zone/include/Zone.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/include/ZoneState.h b/codes/zone/include/ZoneState.h index b12d383d..98d484ec 100644 --- a/codes/zone/include/ZoneState.h +++ b/codes/zone/include/ZoneState.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/src/GridGroup.cpp b/codes/zone/src/GridGroup.cpp index 2eee9321..6c6a7428 100644 --- a/codes/zone/src/GridGroup.cpp +++ b/codes/zone/src/GridGroup.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/src/MultiBlock.cpp b/codes/zone/src/MultiBlock.cpp index 1a71d988..20868fdf 100644 --- a/codes/zone/src/MultiBlock.cpp +++ b/codes/zone/src/MultiBlock.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/src/Zone.cpp b/codes/zone/src/Zone.cpp index 95e3ed30..355ac9a1 100644 --- a/codes/zone/src/Zone.cpp +++ b/codes/zone/src/Zone.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/codes/zone/src/ZoneState.cpp b/codes/zone/src/ZoneState.cpp index d0c09448..3f5a94ac 100644 --- a/codes/zone/src/ZoneState.cpp +++ b/codes/zone/src/ZoneState.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp similarity index 80% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.cpp rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp index 825442a2..3bcbd100 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.cpp +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp @@ -1,279 +1,13 @@ -#include "CgnsGrid.h" +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" #include "Parallel.h" -#include "cgnslib.h" -#include "global.h" #include "ZoneState.h" +#include "cgnslib.h" #include #include -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 << xd[ i ] << " "; - if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; - } - std::cout << "\n"; -} - -void Coor::DumpCoorX( std::vector &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 ]; - } - } -} +BaseZoneList global_zone_names; void ReadCgnsGridBaseZone( const std::string & filename ) { @@ -284,7 +18,7 @@ void ReadCgnsGridBaseZone( const std::string & filename ) std::cout << "Parallel::pid = " << Parallel::pid << " "; std::cout << "fileId = " << fileId << "\n"; } - + int nbases = -1; if ( Parallel::IsServer() ) { @@ -293,7 +27,7 @@ void ReadCgnsGridBaseZone( const std::string & filename ) 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 ]; @@ -374,7 +108,7 @@ void ReadCgnsGridBaseZone( const std::string & filename ) BaseZone baseZone; baseZone.zone_name = zonename; - Global::zone_names.AddBaseZone( baseZone ); + global_zone_names.AddBaseZone( baseZone ); } } @@ -392,13 +126,13 @@ void ReadCgnsGrid( const std::string & filename ) cg_open( filename.c_str(), CG_MODE_READ, &fileId ); std::cout << "fileId = " << fileId << "\n"; } - + int nbases = -1; if ( Parallel::IsServer() ) { cg_nbases( fileId, &nbases ); } - MPI_Bcast( &nbases, 1, MPI_INT, Parallel::serverid, MPI_COMM_WORLD ); + HXBcastData( &nbases, 1, Parallel::serverid ); std::cout << "Parallel::pid = " << Parallel::pid << " "; std::cout << "nbases = " << nbases << "\n"; @@ -532,7 +266,7 @@ void ReadCgnsGrid( const std::string & filename ) if ( Parallel::IsServer() ) { baseZone.zone_name = zonename; - gZoneId = Global::zone_names.FindBaseZone( baseZone ); + gZoneId = global_zone_names.FindBaseZone( baseZone ); } HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); @@ -602,7 +336,7 @@ void ReadCgnsGrid( const std::string & filename ) if ( icoord == 0 ) { - grid->x.resize( nNodes ); + grid->x.Allocate( 0, nNodes - 1 ); coor->DumpCoorX( grid->x ); } } @@ -657,7 +391,7 @@ void ReadCgnsGrid( const std::string & filename ) { 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 ) ); @@ -817,7 +551,7 @@ void ReadCgnsGrid( const std::string & filename ) BaseZone baseZoneDonor; baseZoneDonor.zone_name = donorname; - gDonorZoneId = Global::zone_names.FindBaseZone( baseZoneDonor ); + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); } HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.h similarity index 91% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.h rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.h index fddf1db6..b92a53ab 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CgnsGrid.h +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Grid.h @@ -1,7 +1,17 @@ #pragma once +#include "Vec1d.h" #include #include +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + class Region { public: @@ -28,7 +38,7 @@ class Coor std::vector coord; public: void DumpCoor(); - void DumpCoorX( std::vector & x ); + void DumpCoorX( Vec1d & x ); }; class ZoneBc @@ -98,6 +108,3 @@ class Transform void MapIndex( std::vector & index1, std::vector & index2 ); void Multiply( std::vector & a, std::vector & b ); }; - -void ReadCgnsGridBaseZone( const std::string & filename ); -void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/LogFile.cpp similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/LogFile.cpp rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/LogFile.cpp diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/LogFile.h similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/LogFile.h rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/LogFile.h diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.h similarity index 82% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.h rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.h index 880a71cb..c104bca8 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.h +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Parallel.h @@ -19,8 +19,11 @@ class Parallel static bool IsServer(); }; -void HXSendChar( void * data, int size, int pid, int tag ); -void HXRecvChar( void * data, int size, int pid, int tag ); +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 ); diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/README.txt similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/README.txt rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/README.txt diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.cpp new file mode 100644 index 00000000..8ccefe05 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/ZoneState.cpp rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/ZoneState.h similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/ZoneState.h rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/ZoneState.h diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/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-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/main.cpp similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/main.cpp rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/main.cpp diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/plot.py similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/plot.py rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/plot.py diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/plotting2.jl similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/plotting2.jl rename to example/1d-heat-equation/RK3/cpp/multiblock/parallel/2blocks/01/plotting2.jl diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.cpp new file mode 100644 index 00000000..ea6cc11a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heat1d4blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/4blocks/02/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.cpp new file mode 100644 index 00000000..7a443eae --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/parallel/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.cpp new file mode 100644 index 00000000..8ccefe05 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/2blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.cpp new file mode 100644 index 00000000..ea6cc11a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/4blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/LogFile.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/README.txt b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.cpp new file mode 100644 index 00000000..7a443eae --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Vec1d.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/ZoneState.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heatplot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/hxmath.h b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/main.cpp b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/plot.py b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/plotting2.jl b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/multiblock/serial/8blocks/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-heat-equation/RK3/cpp/singleblock/02/CMakeLists.txt b/example/1d-heat-equation/RK3/cpp/singleblock/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/RK3/cpp/singleblock/02/CgnsUtil.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/RK3/cpp/singleblock/02/CgnsUtil.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/Field.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Field.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Global.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/RK3/cpp/singleblock/02/Global.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Grid.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/RK3/cpp/singleblock/02/Grid.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/RK3/cpp/singleblock/02/LogFile.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/LogFile.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/MyCRWenoPlot.py b/example/1d-heat-equation/RK3/cpp/singleblock/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/MyWenoPlot.py b/example/1d-heat-equation/RK3/cpp/singleblock/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/Parallel.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Parallel.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/README.txt b/example/1d-heat-equation/RK3/cpp/singleblock/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/Solver.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Solver.cpp new file mode 100644 index 00000000..e8630daa --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + this->scheme = Scheme::RungeKutta; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/RK3/cpp/singleblock/02/Solver.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Vec1d.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/WenoPlot.py b/example/1d-heat-equation/RK3/cpp/singleblock/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/RK3/cpp/singleblock/02/ZoneState.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/ZoneState.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/heat1d1block.cgns b/example/1d-heat-equation/RK3/cpp/singleblock/02/heat1d1blocks.cgns similarity index 100% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/heat1d1block.cgns rename to example/1d-heat-equation/RK3/cpp/singleblock/02/heat1d1blocks.cgns diff --git a/example/1d-heat-equation/RK3/cpp/singleblock/02/heatplot.py b/example/1d-heat-equation/RK3/cpp/singleblock/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/RK3/cpp/singleblock/02/hxmath.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/hxmath.h b/example/1d-heat-equation/RK3/cpp/singleblock/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/main.cpp b/example/1d-heat-equation/RK3/cpp/singleblock/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/plot.py b/example/1d-heat-equation/RK3/cpp/singleblock/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/RK3/cpp/singleblock/02/plotting2.jl b/example/1d-heat-equation/RK3/cpp/singleblock/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/RK3/cpp/singleblock/02/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.cpp new file mode 100644 index 00000000..2afb76dc --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.cpp @@ -0,0 +1,287 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.cpp new file mode 100644 index 00000000..f8ddf8c0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/2blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.cpp new file mode 100644 index 00000000..99567946 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.cpp @@ -0,0 +1,323 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.cpp new file mode 100644 index 00000000..ff15e9ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heat1d4blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/4blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.cpp new file mode 100644 index 00000000..99567946 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.cpp @@ -0,0 +1,323 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.cpp new file mode 100644 index 00000000..d69c7123 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/parallel/8blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.cpp new file mode 100644 index 00000000..2afb76dc --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.cpp @@ -0,0 +1,287 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.cpp new file mode 100644 index 00000000..f8ddf8c0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/2blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/2blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.cpp new file mode 100644 index 00000000..98c4576a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.cpp @@ -0,0 +1,375 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +//{ +// double rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 ] = - 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 ]; +// } +// +// 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 ]; +// //} +// +// for ( int i = 0; i < ni; ++ i ) +// { +// d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; +// } +// +// u[ -1 ] = 2 * values[ 0 ] - values[ 1 ]; +// u[ ni ] = 2 * values[ ni - 1 ] - values[ ni - 2 ]; +// +// d[ 0 ] -= a[ 0 ] * u[ -1 ]; +// d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; +// +// thomas_algorithm( a, b, c, d, values ); +// +// for ( int i = 0; i < ni; ++ i ) +// { +// u[ i ] = values[ i ]; +// } +// +//} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.cpp new file mode 100644 index 00000000..ff15e9ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/4blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/4blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.cpp new file mode 100644 index 00000000..99567946 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.cpp @@ -0,0 +1,323 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/LogFile.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/LogFile.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/README.txt b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.cpp new file mode 100644 index 00000000..d69c7123 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Vec1d.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/WenoPlot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/ZoneState.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heatplot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/hxmath.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/hxmath.h b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/main.cpp b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/plot.py b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/multiblock/serial/8blocks/01/plotting2.jl b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/multiblock/serial/8blocks/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-heat-equation/cn/cpp/singleblock/02/CMakeLists.txt b/example/1d-heat-equation/cn/cpp/singleblock/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/cn/cpp/singleblock/02/CgnsUtil.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/cn/cpp/singleblock/02/CgnsUtil.h b/example/1d-heat-equation/cn/cpp/singleblock/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/Field.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Field.cpp new file mode 100644 index 00000000..2afb76dc --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Field.cpp @@ -0,0 +1,287 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Field.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Global.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/cn/cpp/singleblock/02/Global.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Grid.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/cn/cpp/singleblock/02/Grid.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/cn/cpp/singleblock/02/LogFile.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/LogFile.h b/example/1d-heat-equation/cn/cpp/singleblock/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/MyCRWenoPlot.py b/example/1d-heat-equation/cn/cpp/singleblock/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/MyWenoPlot.py b/example/1d-heat-equation/cn/cpp/singleblock/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/Parallel.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Parallel.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Post.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Post.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/README.txt b/example/1d-heat-equation/cn/cpp/singleblock/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/Solver.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Solver.cpp new file mode 100644 index 00000000..ed26f7fd --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + this->scheme = Scheme::CN; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/cn/cpp/singleblock/02/Solver.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Vec1d.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.h b/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/WenoPlot.py b/example/1d-heat-equation/cn/cpp/singleblock/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/cn/cpp/singleblock/02/ZoneState.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/ZoneState.h b/example/1d-heat-equation/cn/cpp/singleblock/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/heat1d1blocks.cgns b/example/1d-heat-equation/cn/cpp/singleblock/02/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/cn/cpp/singleblock/02/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/cn/cpp/singleblock/02/heatplot.py b/example/1d-heat-equation/cn/cpp/singleblock/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/cn/cpp/singleblock/02/hxmath.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/hxmath.h b/example/1d-heat-equation/cn/cpp/singleblock/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/main.cpp b/example/1d-heat-equation/cn/cpp/singleblock/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/plot.py b/example/1d-heat-equation/cn/cpp/singleblock/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/cn/cpp/singleblock/02/plotting2.jl b/example/1d-heat-equation/cn/cpp/singleblock/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/cn/cpp/singleblock/02/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-heat-equation/ftcs/cpp/04/BurgersField.cpp b/example/1d-heat-equation/ftcs/cpp/04/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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( 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-heat-equation/ftcs/cpp/04/BurgersField.h b/example/1d-heat-equation/ftcs/cpp/04/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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( 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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/04/CMakeLists.txt similarity index 85% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CMakeLists.txt rename to example/1d-heat-equation/ftcs/cpp/04/CMakeLists.txt index 51402052..5dd1f642 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/CMakeLists.txt +++ b/example/1d-heat-equation/ftcs/cpp/04/CMakeLists.txt @@ -9,6 +9,12 @@ 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}" ) @@ -19,17 +25,8 @@ if ( MPI_FOUND ) list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) endif () -#get_directory_property( my_import_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} IMPORTED_TARGETS ) -#message( STATUS "my_import_targets=${my_import_targets}" ) - list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) -find_package(Eigen3 CONFIG REQUIRED) - -message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) - -#list ( APPEND PRJ_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR} ) -list ( APPEND PRJ_LIBRARIES Eigen3::Eigen ) set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) @@ -61,14 +58,21 @@ add_executable( ${PROJECT_NAME} set( PROJECT_SOURCES main.cpp - global.h global.cpp - CgnsGrid.h CgnsGrid.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.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 + ZoneState.h ZoneState.cpp ) message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") diff --git a/example/1d-heat-equation/ftcs/cpp/04/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/04/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/04/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/EulerField.cpp b/example/1d-heat-equation/ftcs/cpp/04/EulerField.cpp new file mode 100644 index 00000000..a3273711 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/EulerField.cpp @@ -0,0 +1,306 @@ +#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::Init( 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 EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::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 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 ); + + 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 EulerField::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 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 + 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 EulerField::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 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( "{:.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-heat-equation/ftcs/cpp/04/EulerField.h b/example/1d-heat-equation/ftcs/cpp/04/EulerField.h new file mode 100644 index 00000000..78441d62 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( 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 & 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-heat-equation/ftcs/cpp/04/Field.cpp b/example/1d-heat-equation/ftcs/cpp/04/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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-heat-equation/ftcs/cpp/04/Field.h b/example/1d-heat-equation/ftcs/cpp/04/Field.h new file mode 100644 index 00000000..5012b508 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/04/Global.cpp b/example/1d-heat-equation/ftcs/cpp/04/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/04/Global.h b/example/1d-heat-equation/ftcs/cpp/04/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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-heat-equation/ftcs/cpp/04/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/04/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Grid.h b/example/1d-heat-equation/ftcs/cpp/04/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/HeatField.cpp b/example/1d-heat-equation/ftcs/cpp/04/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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( 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-heat-equation/ftcs/cpp/04/HeatField.h b/example/1d-heat-equation/ftcs/cpp/04/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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( 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-heat-equation/ftcs/cpp/04/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/04/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/LogFile.h b/example/1d-heat-equation/ftcs/cpp/04/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/04/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/04/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/04/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Parallel.h b/example/1d-heat-equation/ftcs/cpp/04/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Post.cpp b/example/1d-heat-equation/ftcs/cpp/04/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Post.h b/example/1d-heat-equation/ftcs/cpp/04/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/README.txt b/example/1d-heat-equation/ftcs/cpp/04/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/04/Solver.cpp new file mode 100644 index 00000000..3ecf1806 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../heat.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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-heat-equation/ftcs/cpp/04/Solver.h b/example/1d-heat-equation/ftcs/cpp/04/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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-heat-equation/ftcs/cpp/04/Vec1d.cpp b/example/1d-heat-equation/ftcs/cpp/04/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/04/Vec1d.h new file mode 100644 index 00000000..47d23577 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Vec1d.h @@ -0,0 +1,67 @@ +#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(); } +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/04/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/04/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/04/Weno.h b/example/1d-heat-equation/ftcs/cpp/04/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/04/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/04/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/04/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/burgers.json b/example/1d-heat-equation/ftcs/cpp/04/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/burgers1d1blocksv1.cgns b/example/1d-heat-equation/ftcs/cpp/04/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/04/burgers1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/04/burgers_ftcs.json b/example/1d-heat-equation/ftcs/cpp/04/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/burgers_plot.py b/example/1d-heat-equation/ftcs/cpp/04/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/cfd.json b/example/1d-heat-equation/ftcs/cpp/04/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/heat.json b/example/1d-heat-equation/ftcs/cpp/04/heat.json new file mode 100644 index 00000000..234146f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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" : "../heat1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/04/heat1d1blocksv1.cgns b/example/1d-heat-equation/ftcs/cpp/04/heat1d1blocksv1.cgns new file mode 100644 index 00000000..a367704f Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/04/heat1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/04/heat_plot.py b/example/1d-heat-equation/ftcs/cpp/04/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/heaticp.json b/example/1d-heat-equation/ftcs/cpp/04/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/04/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/hxmath.h b/example/1d-heat-equation/ftcs/cpp/04/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/main.cpp b/example/1d-heat-equation/ftcs/cpp/04/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/plot.py b/example/1d-heat-equation/ftcs/cpp/04/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/04/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/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-heat-equation/ftcs/cpp/04/sod.json b/example/1d-heat-equation/ftcs/cpp/04/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/04/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.cpp new file mode 100644 index 00000000..8915838f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.cpp @@ -0,0 +1,290 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/2blocks/01/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.cpp new file mode 100644 index 00000000..5d7f6dae --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.cpp @@ -0,0 +1,558 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../heat1d1blocksv1.cgns"; + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + //for ( int ig = 0; ig <= nghost; ++ ig ) + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/heatplot.py new file mode 100644 index 00000000..ffa09e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/heatplot.py @@ -0,0 +1,106 @@ +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 + +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/2blocks/01/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/01/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/2blocks/02/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/2blocks/02/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/2blocks/02/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.cpp new file mode 100644 index 00000000..5a309656 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../heat1d1blocksv1.cgns"; + std::string fileName = "../heat1d2blocks.cgns"; + //std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/2blocks/02/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/heat1d2blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/2blocks/02/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/02/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/02/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/BurgersField.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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( 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/BurgersField.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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( 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.cpp new file mode 100644 index 00000000..a3273711 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.cpp @@ -0,0 +1,306 @@ +#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::Init( 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 EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::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 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 ); + + 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 EulerField::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 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 + 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 EulerField::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 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( "{:.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-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.h new file mode 100644 index 00000000..78441d62 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( 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 & 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.h new file mode 100644 index 00000000..5012b508 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/HeatField.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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( 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/HeatField.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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( 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.cpp new file mode 100644 index 00000000..3ecf1806 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../heat.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Vec1d.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Vec1d.h new file mode 100644 index 00000000..47d23577 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Vec1d.h @@ -0,0 +1,67 @@ +#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(); } +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers1d1blocksv1.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers_ftcs.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers_plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/cfd.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d1blocksv1.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d1blocksv1.cgns new file mode 100644 index 00000000..a367704f Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d2blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat_plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/heaticp.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/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-heat-equation/ftcs/cpp/multiblock/2blocks/03/sod.json b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/2blocks/03/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/4blocks/02/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/4blocks/02/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/4blocks/02/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.cpp new file mode 100644 index 00000000..9f34ee20 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../heat1d1blocksv1.cgns"; + //std::string fileName = "../heat1d2blocks.cgns"; + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/4blocks/02/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/heat1d4blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/4blocks/02/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/4blocks/02/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/4blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/8blocks/02/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/8blocks/02/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/8blocks/02/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.cpp new file mode 100644 index 00000000..ee896af7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../heat1d1blocksv1.cgns"; + //std::string fileName = "../heat1d2blocks.cgns"; + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/8blocks/02/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/heat1d8blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/8blocks/02/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/8blocks/02/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.cpp new file mode 100644 index 00000000..10878039 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.cpp @@ -0,0 +1,559 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../heat1d1blocksv1.cgns"; + std::string fileName = "../heat1d2blocks.cgns"; + //std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/2blocks/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.cpp new file mode 100644 index 00000000..123226b9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.cpp @@ -0,0 +1,557 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heat1d4blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/4blocks/03/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.cpp new file mode 100644 index 00000000..edaea6be --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.cpp @@ -0,0 +1,291 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/LogFile.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/README.txt b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.cpp new file mode 100644 index 00000000..80acc6a5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.cpp @@ -0,0 +1,557 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d8blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heat1d8blocks.cgns b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heat1d8blocks.cgns new file mode 100644 index 00000000..4dc174d4 Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heat1d8blocks.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heatplot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/hxmath.h b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/main.cpp b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/plot.py b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/multiblock/parallel/8blocks/02/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-heat-equation/ftcs/cpp/single_block/02/CMakeLists.txt b/example/1d-heat-equation/ftcs/cpp/single_block/02/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/ftcs/cpp/single_block/02/CgnsUtil.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/ftcs/cpp/single_block/02/CgnsUtil.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/Field.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Field.cpp new file mode 100644 index 00000000..8915838f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Field.cpp @@ -0,0 +1,290 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Field.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Field.h new file mode 100644 index 00000000..d6129dde --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Field.h @@ -0,0 +1,61 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Global.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/ftcs/cpp/single_block/02/Global.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Grid.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/ftcs/cpp/single_block/02/Grid.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/ftcs/cpp/single_block/02/LogFile.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/LogFile.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/MyCRWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/single_block/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/MyWenoPlot.py b/example/1d-heat-equation/ftcs/cpp/single_block/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/Parallel.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Parallel.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/README.txt b/example/1d-heat-equation/ftcs/cpp/single_block/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/Solver.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Solver.cpp new file mode 100644 index 00000000..3557e728 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Solver.cpp @@ -0,0 +1,557 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + this->scheme = Scheme::FTCS; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocksv1.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + //for ( int ig = 0; ig <= nghost; ++ ig ) + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/ftcs/cpp/single_block/02/Solver.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Vec1d.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/WenoPlot.py b/example/1d-heat-equation/ftcs/cpp/single_block/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/ftcs/cpp/single_block/02/ZoneState.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/ZoneState.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/heat1d1blocksv1.cgns b/example/1d-heat-equation/ftcs/cpp/single_block/02/heat1d1blocksv1.cgns new file mode 100644 index 00000000..a367704f Binary files /dev/null and b/example/1d-heat-equation/ftcs/cpp/single_block/02/heat1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/ftcs/cpp/single_block/02/heatplot.py b/example/1d-heat-equation/ftcs/cpp/single_block/02/heatplot.py new file mode 100644 index 00000000..ffa09e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/heatplot.py @@ -0,0 +1,106 @@ +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 + +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/ftcs/cpp/single_block/02/hxmath.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/hxmath.h b/example/1d-heat-equation/ftcs/cpp/single_block/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/main.cpp b/example/1d-heat-equation/ftcs/cpp/single_block/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/plot.py b/example/1d-heat-equation/ftcs/cpp/single_block/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/ftcs/cpp/single_block/02/plotting2.jl b/example/1d-heat-equation/ftcs/cpp/single_block/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/ftcs/cpp/single_block/02/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.cpp new file mode 100644 index 00000000..99567946 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.cpp @@ -0,0 +1,323 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.cpp new file mode 100644 index 00000000..b71cb22e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.cpp @@ -0,0 +1,560 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + this->scheme = Scheme::ICP; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.cpp new file mode 100644 index 00000000..28f3838c --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.cpp @@ -0,0 +1,312 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + 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 FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.cpp new file mode 100644 index 00000000..b71cb22e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.cpp @@ -0,0 +1,560 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + this->scheme = Scheme::ICP; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heat1d2blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heat1d2blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01a/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CMakeLists.txt new file mode 100644 index 00000000..5f10de9e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CMakeLists.txt @@ -0,0 +1,101 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.cpp new file mode 100644 index 00000000..91a69f4e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.cpp @@ -0,0 +1,455 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +//{ +// double rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// std::vector values( d.size() ); +// +// thomas_algorithm( a, b, c, d, values ); +// +// for ( int i = 0; i < ni; ++ i ) +// { +// u[ i ] = values[ i ]; +// } +//} + + +void FieldSub::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::RungeKutta( Zone * zone, int nStage, int istage ) +//{ +// if ( nStage == 1 ) +// { +// this->RungeKutta1( zone, istage ); +// } +// if ( nStage == 3 ) +// { +// this->RungeKutta3( zone, istage ); +// } +//} +// +//void FieldSub::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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +//void FieldSub::RungeKutta3Stage0( Zone * zone ) +//{ +// this->Rhs( this->u, this->res ); +// +// for ( int i = 0; i < ni; ++ i ) +// { +// u[ i ] = u[ i ] + dt * res[ i ]; +// } +//} +// +//void FieldSub::RungeKutta3Stage1( Zone * zone ) +//{ +// this->Rhs( this->u, this->res ); +// +// for ( int i = 0; i < ni; ++ i ) +// { +// u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; +// } +//} +// +//void FieldSub::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 i = 0; i < ni; ++ i ) +// { +// u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; +// } +//} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.h new file mode 100644 index 00000000..cd611dca --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Field.h @@ -0,0 +1,73 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + //virtual void RungeKutta( Zone * zone, int nStage, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & 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: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + +class FieldSub : public Field +{ +public: + //int ni; + int nt; + double dx, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + //void RungeKutta( Zone * zone, int nStage, int istage ); + //void RungeKutta3( Zone * zone, int istage ); + //void RungeKutta3Stage0( Zone * zone ); + //void RungeKutta3Stage1( Zone * zone ); + //void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.cpp new file mode 100644 index 00000000..d3e5fcef --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.cpp @@ -0,0 +1,374 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 == "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 + { + 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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.h new file mode 100644 index 00000000..5ddff16e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Global.h @@ -0,0 +1,150 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.cpp new file mode 100644 index 00000000..d51af846 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.cpp @@ -0,0 +1,569 @@ +#include "Solver.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(); + std::ifstream f("../cfd.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + Global::scheme.viscous = static_cast( BasicScheme::CENTER ); + + this->nghost = 1; + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + int kkk = 1; + + //this->nghost = 3; + Global::nghost = this->nghost; +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +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->RungeKutta( 1 ); + } +} + +void Solver::SolveFields() +{ + this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % 250 == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->PostProcess(); + } + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.h new file mode 100644 index 00000000..9bbaf58f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Solver.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.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: + //Scheme scheme; + int nghost; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.cpp new file mode 100644 index 00000000..a2053584 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.h new file mode 100644 index 00000000..08ae4253 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + //int ni; + int nt; + double dx, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/cfd.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/cfd.json new file mode 100644 index 00000000..3e6e49a4 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/cfd.json @@ -0,0 +1,11 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01b/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CMakeLists.txt new file mode 100644 index 00000000..29850780 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CMakeLists.txt @@ -0,0 +1,102 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.cpp new file mode 100644 index 00000000..a8bba400 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.cpp @@ -0,0 +1,79 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.h new file mode 100644 index 00000000..f21e1cca --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Field.h @@ -0,0 +1,40 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void InviscidFlux( Vec1d & u, Vec1d & r ) {}; + virtual void ViscousFlux( Vec1d & u, Vec1d & 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: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.cpp new file mode 100644 index 00000000..83b95e04 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.cpp @@ -0,0 +1,375 @@ +#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::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 == "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 + { + 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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.h similarity index 69% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.h rename to example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.h index 933cec05..4bd90d9e 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.h +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Global.h @@ -1,63 +1,13 @@ #pragma once +#include "Vec1d.h" #include #include #include #include #include #include -#include "CgnsGrid.h" - -class Grid; - -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; - } -}; - -class Grid -{ -public: - int zoneIndex; - std::vector x; -}; +#include +using json = nlohmann::json; class Face { @@ -121,12 +71,59 @@ class Interface 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 CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid, int nghost ); 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; class Global { @@ -135,7 +132,6 @@ class Global static std::vector fields; public: static std::vector zones; - static BaseZoneList zone_names; static std::vector interfaces; public: static std::map faceMap; @@ -146,12 +142,16 @@ class Global static std::vector> donor_zones; static InterfaceTopo interfaceTopo; public: + static Scheme scheme; + static GoverningEquation governing_equation; static int nt; + static int iter; static int cell_dim; static int phys_dim; + static int nghost; + 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 ); }; - diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.cpp new file mode 100644 index 00000000..d977fd85 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.cpp @@ -0,0 +1,316 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void HeatField::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void HeatField::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void HeatField::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 HeatField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void HeatField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void HeatField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.h new file mode 100644 index 00000000..9d9be260 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/HeatField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.cpp new file mode 100644 index 00000000..de74ad71 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.cpp @@ -0,0 +1,592 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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(); + std::ifstream f("../cfd.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + + this->nghost = 1; + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + int kkk = 1; + + //this->nghost = 3; + Global::nghost = this->nghost; + + this->gridfile = data[ "grid" ]; +} + +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::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) { + field = new WenoField(); + } + else { + field = new HeatField(); + } + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +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->RungeKutta( 1 ); + } +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.h new file mode 100644 index 00000000..af540e0e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Solver.h @@ -0,0 +1,44 @@ +#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: + int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.cpp new file mode 100644 index 00000000..2f95bb76 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.cpp @@ -0,0 +1,492 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.h new file mode 100644 index 00000000..c022da79 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/Weno.h @@ -0,0 +1,49 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int nt; + double dx, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfd.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfd.json new file mode 100644 index 00000000..b3549ebc --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfd.json @@ -0,0 +1,11 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfdbak.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfdbak.json new file mode 100644 index 00000000..507c8c93 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/cfdbak.json @@ -0,0 +1,10 @@ +{ + "total_time" : 1.0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01c/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.cpp new file mode 100644 index 00000000..c19943b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.cpp @@ -0,0 +1,235 @@ +#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( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void BurgersField::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 BurgersField::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 BurgersField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void BurgersField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void BurgersField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void BurgersField::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; + //} +} + +void BurgersField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.h new file mode 100644 index 00000000..bd63522c --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.cpp new file mode 100644 index 00000000..a8bba400 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.cpp @@ -0,0 +1,79 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.h new file mode 100644 index 00000000..d78638a5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Field.h @@ -0,0 +1,38 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & 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: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.cpp new file mode 100644 index 00000000..669eff84 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.cpp @@ -0,0 +1,376 @@ +#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::iviscous = 0; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 == "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 + { + 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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.h new file mode 100644 index 00000000..48bdeb5d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Global.h @@ -0,0 +1,158 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iviscous; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.cpp new file mode 100644 index 00000000..95656dcc --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.cpp @@ -0,0 +1,327 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void HeatField::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void HeatField::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::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 HeatField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void HeatField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void HeatField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.h new file mode 100644 index 00000000..c5ec4916 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/HeatField.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.cpp new file mode 100644 index 00000000..c1903455 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.cpp @@ -0,0 +1,592 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + //std::ifstream f("../burgers.json"); + std::ifstream f("../heat.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + + Global::iviscous = data[ "iviscous" ]; + + + this->nghost = 1; + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + int kkk = 1; + + //this->nghost = 3; + Global::nghost = this->nghost; + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +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->RungeKutta( 1 ); + } +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.h new file mode 100644 index 00000000..af540e0e --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Solver.h @@ -0,0 +1,44 @@ +#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: + int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Vec1d.h new file mode 100644 index 00000000..aece04b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/burgers.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/burgers.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/burgers.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/cfd.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat.json new file mode 100644 index 00000000..9db71579 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01d/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.cpp new file mode 100644 index 00000000..c4071e8f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.cpp @@ -0,0 +1,246 @@ +#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( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +//void BurgersField::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 BurgersField::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 BurgersField::Boundary( Region ®ion, int bcType ) +//{ +// if ( bcType == BCInflow ) +// { +// this->InflowBc( region ); +// } +// else if ( bcType == BCExtrapolate || bcType == BCOutflow ) +// { +// this->OutflowBc( region ); +// } +//} +// +//void BurgersField::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; +// if ( i == 1 ) +// { +// idir = -1; +// } +// int ib = i - 1; //index from 0 +// int in = ib - idir; +// +// int ig1 = ib + idir; +// this->u[ ib ] = 0.0; +// this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; +// +// if ( Global::nghost >= 2 ) +// { +// int ig2 = ig1 + idir; +// this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; +// if ( Global::nghost >= 3 ) +// { +// int ig3 = ig2 + idir; +// this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; +// } +// } +// } +//} +// +//void BurgersField::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; +// if ( i == 1 ) +// { +// idir = -1; +// } +// int ib = i - 1; //index from 0 +// int in = ib - idir; +// +// int ig1 = ib + idir; +// this->u[ ib ] = 0.0; +// this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; +// +// if ( Global::nghost >= 2 ) +// { +// int ig2 = ig1 + idir; +// this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; +// if ( Global::nghost >= 3 ) +// { +// int ig3 = ig2 + idir; +// this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; +// } +// } +// } +//} +// +//void BurgersField::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; +// //} +//} + +void BurgersField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.h new file mode 100644 index 00000000..48c97af2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx, total_time; + int ns; +public: + void Init( Grid * grid ); +//public: +// void PhysicalBoundary( Zone * zone ); +// void InterfaceBoundary( Zone * zone ); +// void Boundary( Region & region, int bcType ); +// void InflowBc( Region & region ); +// void OutflowBc( Region & region ); +// void InterfaceBc( Region & region ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.cpp new file mode 100644 index 00000000..a34af4fa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.cpp @@ -0,0 +1,212 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.h new file mode 100644 index 00000000..74f443ed --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Field.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & 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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.cpp new file mode 100644 index 00000000..954ccaa3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.cpp @@ -0,0 +1,384 @@ +#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::iviscous = 0; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 + { + 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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.h new file mode 100644 index 00000000..48bdeb5d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Global.h @@ -0,0 +1,158 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iviscous; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.cpp new file mode 100644 index 00000000..9d2bae11 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.cpp @@ -0,0 +1,294 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void HeatField::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +//void HeatField::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 HeatField::Boundary( Region ®ion, int bcType ) +//{ +// if ( bcType == BCInflow ) +// { +// this->InflowBc( region ); +// } +// else if ( bcType == BCExtrapolate || bcType == BCOutflow ) +// { +// this->OutflowBc( region ); +// } +//} +// +//void HeatField::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; +// if ( i == 1 ) +// { +// idir = -1; +// } +// int ib = i - 1; //index from 0 +// int ig = ib + idir; +// int in = ib - idir; +// this->u[ ib ] = 0.0; +// this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; +// } +//} +// +//void HeatField::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; +// if ( i == 1 ) +// { +// idir = -1; +// } +// int ib = i - 1; //index from 0 +// int ig = ib + idir; +// int in = ib - idir; +// this->u[ ib ] = 0.0; +// this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; +// } +//} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.h new file mode 100644 index 00000000..5991b620 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/HeatField.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + //void Boundary( Region & region, int bcType ); + //void InflowBc( Region & region ); + //void OutflowBc( Region & region ); + + //void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.cpp new file mode 100644 index 00000000..11785e1d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.cpp @@ -0,0 +1,593 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + //std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + + Global::iviscous = data[ "iviscous" ]; + + + this->nghost = 1; + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + int kkk = 1; + + //this->nghost = 3; + Global::nghost = this->nghost; + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +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() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.h new file mode 100644 index 00000000..f6ac1c4c --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Solver.h @@ -0,0 +1,44 @@ +#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: + int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Vec1d.h new file mode 100644 index 00000000..aece04b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/burgers.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/burgers.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/burgers.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/cfd.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat.json new file mode 100644 index 00000000..a6f5448d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heaticp.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heaticp.json new file mode 100644 index 00000000..ec6b89b0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heaticp.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heatplot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/heatplot.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01e/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.cpp new file mode 100644 index 00000000..ab67c163 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.cpp @@ -0,0 +1,126 @@ +#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( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + 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"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void BurgersField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + if ( Global::iconservation == 0 ) + { + for ( int i = 0; i < ni; ++ 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::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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 ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.h new file mode 100644 index 00000000..da4d14b8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/BurgersField.h @@ -0,0 +1,25 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; + int ns; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.cpp new file mode 100644 index 00000000..a34af4fa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.cpp @@ -0,0 +1,212 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.h new file mode 100644 index 00000000..df0b1cab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Field.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.cpp new file mode 100644 index 00000000..fcc52eec --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.cpp @@ -0,0 +1,388 @@ +#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::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +double Global::total_time = 0.0; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 + { + 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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.h new file mode 100644 index 00000000..87aaa934 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Global.h @@ -0,0 +1,162 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/HeatField.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/HeatField.cpp new file mode 100644 index 00000000..3166f314 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + 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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/HeatField.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.cpp new file mode 100644 index 00000000..194658f2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.cpp @@ -0,0 +1,649 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::total_time = data[ "total_time" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); + //std::string total_string = {}; + //std::fstream file; + //if ( Parallel::pid == Parallel::serverid ) + //{ + // std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + // 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->PostProcess( 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::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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Vec1d.h new file mode 100644 index 00000000..aece04b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers.json new file mode 100644 index 00000000..c3bdd565 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers1d1blocksv1.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers1d1blocksv1.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers_plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/burgers_plot.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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/cfd.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat_plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heaticp.json b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/2blocks/01f/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.cpp new file mode 100644 index 00000000..28f3838c --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.cpp @@ -0,0 +1,312 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + 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 FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/LogFile.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/LogFile.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/README.txt b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.cpp new file mode 100644 index 00000000..b9d8ff69 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.cpp @@ -0,0 +1,560 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + this->scheme = Scheme::ICP; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d4blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Vec1d.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/WenoPlot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/ZoneState.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heat1d4blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heatplot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/hxmath.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/hxmath.h b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/main.cpp b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/plot.py b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/multiblock/serial/4blocks/01/plotting2.jl b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/multiblock/serial/4blocks/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-heat-equation/icp/cpp/singleblock/01/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/singleblock/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/singleblock/01/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/singleblock/01/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/singleblock/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/Field.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Field.cpp new file mode 100644 index 00000000..99567946 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Field.cpp @@ -0,0 +1,323 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Field.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Global.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/singleblock/01/Global.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Grid.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/singleblock/01/Grid.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/singleblock/01/LogFile.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/LogFile.h b/example/1d-heat-equation/icp/cpp/singleblock/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/Parallel.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Parallel.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Post.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Post.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/README.txt b/example/1d-heat-equation/icp/cpp/singleblock/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/Solver.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Solver.cpp new file mode 100644 index 00000000..9a9317dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Solver.cpp @@ -0,0 +1,560 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + this->scheme = Scheme::ICP; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/singleblock/01/Solver.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Vec1d.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.h b/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/WenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/singleblock/01/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/ZoneState.h b/example/1d-heat-equation/icp/cpp/singleblock/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/singleblock/01/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/singleblock/01/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01/heatplot.py b/example/1d-heat-equation/icp/cpp/singleblock/01/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/singleblock/01/hxmath.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/hxmath.h b/example/1d-heat-equation/icp/cpp/singleblock/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/main.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/plot.py b/example/1d-heat-equation/icp/cpp/singleblock/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01/plotting2.jl b/example/1d-heat-equation/icp/cpp/singleblock/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/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-heat-equation/icp/cpp/singleblock/01a/CMakeLists.txt b/example/1d-heat-equation/icp/cpp/singleblock/01a/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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-heat-equation/icp/cpp/singleblock/01a/CgnsUtil.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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->x.Allocate( 0, nNodes - 1 ); + 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-heat-equation/icp/cpp/singleblock/01a/CgnsUtil.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/Field.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Field.cpp new file mode 100644 index 00000000..3ba8db6b --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Field.cpp @@ -0,0 +1,364 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + //this->nt = 1; + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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; + u_e.Allocate( ist, ied, 0 ); + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN_Old( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + 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 FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + //d[ 0 ] = 0; + //d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + + +//void FieldSub::ICP( Zone * zone ) +//{ +// double beta = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 ]; +// } +// +// //d[ 0 ] -= a[ 0 ] * u[ -1 ]; +// //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; +// +// +// 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 ] ); +// +// 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 FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int ig = ib + idir; + int in = ib - idir; + this->u[ ib ] = 0.0; + this->u[ ig ] = 2 * this->u[ ib ] - this->u[ in ]; + } +} + +void FieldSub::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void FieldSub::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Field.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Field.h new file mode 100644 index 00000000..4d9b8ba5 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Field.h @@ -0,0 +1,62 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN_Old( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +public: + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Global.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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-heat-equation/icp/cpp/singleblock/01a/Global.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Grid.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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-heat-equation/icp/cpp/singleblock/01a/Grid.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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-heat-equation/icp/cpp/singleblock/01a/LogFile.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/LogFile.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/MyCRWenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/MyWenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/Parallel.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Parallel.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/README.txt b/example/1d-heat-equation/icp/cpp/singleblock/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/Solver.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Solver.cpp new file mode 100644 index 00000000..9a9317dd --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Solver.cpp @@ -0,0 +1,560 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + this->scheme = Scheme::ICP; + this->nghost = 1; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + //this->scheme = Scheme::CRWENO; + //this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../heat1d1blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + //this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + //if ( ( Global::iter + 1 ) % 250 == 0 ) + //{ + // std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + // this->PostProcess(); + //} + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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 = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 = nghost + 1; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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-heat-equation/icp/cpp/singleblock/01a/Solver.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Vec1d.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/WenoPlot.py b/example/1d-heat-equation/icp/cpp/singleblock/01a/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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-heat-equation/icp/cpp/singleblock/01a/ZoneState.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/ZoneState.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/heat1d1blocks.cgns b/example/1d-heat-equation/icp/cpp/singleblock/01a/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/1d-heat-equation/icp/cpp/singleblock/01a/heat1d1blocks.cgns differ diff --git a/example/1d-heat-equation/icp/cpp/singleblock/01a/heatplot.py b/example/1d-heat-equation/icp/cpp/singleblock/01a/heatplot.py new file mode 100644 index 00000000..697f89ce --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/heatplot.py @@ -0,0 +1,112 @@ +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 ) +print("my_max_error = {0:.15f}".format(my_max_error)) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +# 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-heat-equation/icp/cpp/singleblock/01a/hxmath.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/hxmath.h b/example/1d-heat-equation/icp/cpp/singleblock/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/main.cpp b/example/1d-heat-equation/icp/cpp/singleblock/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/plot.py b/example/1d-heat-equation/icp/cpp/singleblock/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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-heat-equation/icp/cpp/singleblock/01a/plotting2.jl b/example/1d-heat-equation/icp/cpp/singleblock/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-heat-equation/icp/cpp/singleblock/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..64b5c39b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.cpp @@ -0,0 +1,306 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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 ] ) } ); + } + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + for ( int i = ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void BurgersField::LaxFriedrichs( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 i = 0; i < nx; ++ i ) + { + res[ i ] -= ( fL[ i + 1 ] - fL[ i ] ) / dx + ( fR[ i + 1 ] - fR[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + //Vec1d fL; + //fL.Allocate( 0, nx, 0 ); + + //Vec1d fR; + //fR.Allocate( 0, nx, 0 ); + + //Vec1d f, fP, fN; + + //int ist = 0 - Global::nghost; + //int ied = this->nx - 1 + Global::nghost; + + //f.Allocate( ist, ied, 0 ); + //fP.Allocate( ist, ied, 0 ); + //fN.Allocate( ist, ied, 0 ); + + //for ( int i = ist; i <= ied; ++ i ) + //{ + // f[ i ] = 0.5 * u[ i ] * u[ i ]; + //} + + //Vec1d ps; + //ps.Allocate( ist, ied, 0 ); + + //WaveSpeed( u, ps ); + + //// left and right side fluxes at the interface + //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.inviscid == to_int( BasicScheme::CRWENO ) ) + //{ + // crwenoL( nx, fP, fL ); + // crwenoR( nx, fN, fR ); + //} + //else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + //{ + // wenoL( nx, fP, fL ); + // wenoR( nx, fN, fR ); + //} + + //for ( int i = 0; i < nx; ++ i ) + //{ + // res[ i ] -= ( fL[ i + 1 ] - fL[ i ] ) / dx + ( fR[ i + 1 ] - fR[ i ] ) / dx; + //} +} + +void BurgersField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.h new file mode 100644 index 00000000..b65b83f7 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/BurgersField.h @@ -0,0 +1,29 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.cpp new file mode 100644 index 00000000..8ccc7c11 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.cpp @@ -0,0 +1,418 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.h new file mode 100644 index 00000000..3e970fed --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Global.h @@ -0,0 +1,167 @@ +#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, int nghost ); + 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 + LAX, //Lax-Friedrichs flux splitting + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/README.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.cpp new file mode 100644 index 00000000..16ac928c --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.cpp @@ -0,0 +1,615 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Vec1d.h new file mode 100644 index 00000000..687488b8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers.json new file mode 100644 index 00000000..38605b18 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/burgers_plot.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat1d1blocks.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat1d1blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.cpp new file mode 100644 index 00000000..b5653e1e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.cpp @@ -0,0 +1,422 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.h new file mode 100644 index 00000000..9df5799c --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Global.h @@ -0,0 +1,168 @@ +#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, int nghost ); + 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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Grid.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/HeatField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/LogFile.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/README.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.cpp new file mode 100644 index 00000000..16ac928c --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.cpp @@ -0,0 +1,615 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers.json new file mode 100644 index 00000000..bce0ca30 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/burgers_plot.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/cfd.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat1d1blocks.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat1d1blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heaticp.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/hxmath.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/main.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/01a/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..0ea39021 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.cpp @@ -0,0 +1,430 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..896ee20d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Global.h @@ -0,0 +1,168 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..cd0d6b5f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,617 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..5106e2b8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/burgers_plot.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..0ea39021 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.cpp @@ -0,0 +1,430 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..896ee20d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Global.h @@ -0,0 +1,168 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..cd0d6b5f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,617 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..be070588 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d4blocks.cgns b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d4blocks.cgns new file mode 100644 index 00000000..3585da45 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers1d4blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..fc1ef0bd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/burgers_plot.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: WENO5+Rusanov Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/01/rusanov.py b/example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/python/01/rusanov.py similarity index 100% rename from example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/01/rusanov.py rename to example/inviscid-burgers-equation/conservative-form/Riemann/Rusanov/python/01/rusanov.py diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..3d8507ba --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.cpp @@ -0,0 +1,213 @@ +#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( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + 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"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void BurgersField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + for ( int i = 0; i < ni; ++ 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( Vec1d & u, Vec1d & ps ) +{ + for ( int i = 0; i <= ni; ++ 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 ] ) } ); + } + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + for ( int i = ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = ni + 1; i <= ied; ++ i ) + { + ps[ i ] = ps[ ni ]; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, ni, 0 ); + + Vec1d fR; + fR.Allocate( 0, ni, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, fP, fL ); + crwenoR( ni, fN, fR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, fP, fL ); + wenoR( ni, fN, fR ); + } + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] -= ( fL[ i + 1 ] - fL[ i ] ) / dx + ( fR[ i + 1 ] - fR[ i ] ) / dx; + } +} + +void BurgersField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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 ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.h new file mode 100644 index 00000000..629ec23e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/BurgersField.h @@ -0,0 +1,28 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; + int ns; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.cpp new file mode 100644 index 00000000..a34af4fa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.cpp @@ -0,0 +1,212 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.h new file mode 100644 index 00000000..df0b1cab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Field.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.cpp new file mode 100644 index 00000000..897cf0c6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.cpp @@ -0,0 +1,396 @@ +#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::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +double Global::total_time = 0.0; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.h new file mode 100644 index 00000000..87aaa934 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Global.h @@ -0,0 +1,162 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/HeatField.cpp new file mode 100644 index 00000000..3166f314 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + 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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.cpp new file mode 100644 index 00000000..194658f2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.cpp @@ -0,0 +1,649 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::total_time = data[ "total_time" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); + //std::string total_string = {}; + //std::fstream file; + //if ( Parallel::pid == Parallel::serverid ) + //{ + // std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + // 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->PostProcess( 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::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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Vec1d.h new file mode 100644 index 00000000..687488b8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers.json new file mode 100644 index 00000000..a0b86df9 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/burgers_plot.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat1d1blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat1d1blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.cpp new file mode 100644 index 00000000..77b9d059 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.cpp @@ -0,0 +1,251 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 0, nx, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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 ] ) } ); + } + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + for ( int i = ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( fL[ i + 1 ] - fL[ i ] ) / dx + ( fR[ i + 1 ] - fR[ i ] ) / dx; + } +} + +void BurgersField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.h new file mode 100644 index 00000000..85d192bb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/BurgersField.h @@ -0,0 +1,27 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.cpp new file mode 100644 index 00000000..42c069b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.cpp @@ -0,0 +1,397 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.h new file mode 100644 index 00000000..9a1193cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Global.h @@ -0,0 +1,163 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.cpp new file mode 100644 index 00000000..2ed4165f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.cpp @@ -0,0 +1,615 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Vec1d.h new file mode 100644 index 00000000..687488b8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers.json new file mode 100644 index 00000000..11c36b2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers.json @@ -0,0 +1,16 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/burgers_plot.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat1d1blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat1d1blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/01a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/BurgersField.cpp new file mode 100644 index 00000000..b17d698d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/BurgersField.cpp @@ -0,0 +1,356 @@ +#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( 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 ) +{ + /* Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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( 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.cpp new file mode 100644 index 00000000..a3273711 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.cpp @@ -0,0 +1,306 @@ +#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::Init( 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 EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::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 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 ); + + 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 EulerField::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 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 + 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 EulerField::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 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( "{:.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.h new file mode 100644 index 00000000..78441d62 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( 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 & 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.h new file mode 100644 index 00000000..5012b508 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/HeatField.cpp new file mode 100644 index 00000000..0f5daf50 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/HeatField.cpp @@ -0,0 +1,203 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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(); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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( 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.cpp new file mode 100644 index 00000000..6dc7cda9 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../burgers.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Vec1d.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Vec1d.h new file mode 100644 index 00000000..47d23577 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Vec1d.h @@ -0,0 +1,67 @@ +#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(); } +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers.json new file mode 100644 index 00000000..fa185027 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/sod.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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( 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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( 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.cpp new file mode 100644 index 00000000..a3273711 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.cpp @@ -0,0 +1,306 @@ +#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::Init( 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 EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::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 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 ); + + 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 EulerField::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 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 + 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 EulerField::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 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( "{:.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.h new file mode 100644 index 00000000..78441d62 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( 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 & 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.h new file mode 100644 index 00000000..5012b508 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/HeatField.cpp new file mode 100644 index 00000000..0f5daf50 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/HeatField.cpp @@ -0,0 +1,203 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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(); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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( 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.cpp new file mode 100644 index 00000000..6dc7cda9 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../burgers.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Vec1d.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Vec1d.h new file mode 100644 index 00000000..47d23577 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Vec1d.h @@ -0,0 +1,67 @@ +#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(); } +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/sod.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/02a/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..0ea39021 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.cpp @@ -0,0 +1,430 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..896ee20d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Global.h @@ -0,0 +1,168 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..cd0d6b5f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,617 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..dab70028 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d4blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d4blocks.cgns new file mode 100644 index 00000000..3585da45 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers1d4blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..0ea39021 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.cpp @@ -0,0 +1,430 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..896ee20d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Global.h @@ -0,0 +1,168 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..cd0d6b5f --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,617 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..b2bf1213 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d4blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d4blocks.cgns new file mode 100644 index 00000000..3585da45 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers1d4blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.cpp new file mode 100644 index 00000000..8cdf6005 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.cpp @@ -0,0 +1,435 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.h new file mode 100644 index 00000000..95ff48e5 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Global.h @@ -0,0 +1,170 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.cpp new file mode 100644 index 00000000..c0354c0d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.cpp @@ -0,0 +1,656 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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( "../burgers.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + 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::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::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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers.json new file mode 100644 index 00000000..dab70028 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d4blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d4blocks.cgns new file mode 100644 index 00000000..3585da45 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers1d4blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/2blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/BurgersField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/BurgersField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.h new file mode 100644 index 00000000..1642fdb4 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Field.h @@ -0,0 +1,46 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.cpp new file mode 100644 index 00000000..8cdf6005 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.cpp @@ -0,0 +1,435 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.h new file mode 100644 index 00000000..95ff48e5 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Global.h @@ -0,0 +1,170 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Grid.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Grid.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/HeatField.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/HeatField.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/LogFile.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Parallel.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.cpp new file mode 100644 index 00000000..561fcd3d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->ni; + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->ni; + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/README.txt b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.cpp new file mode 100644 index 00000000..c0354c0d --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.cpp @@ -0,0 +1,656 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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( "../burgers.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + 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::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::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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Vec1d.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Vec1d.h new file mode 100644 index 00000000..79c53a35 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Vec1d.h @@ -0,0 +1,50 @@ +#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; + } +}; diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/ZoneState.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers.json new file mode 100644 index 00000000..b2bf1213 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d4blocks.cgns b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d4blocks.cgns new file mode 100644 index 00000000..3585da45 Binary files /dev/null and b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers1d4blocks.cgns differ diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers_ftcs.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/cfd.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heat.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heat_plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heaticp.json b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/hxmath.h b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/main.cpp b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/plot.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/plotting2.jl b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/cpp/parallel/4blocks/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/inviscid-burgers-equation/conservative-form/flux_splitting/01/flux_splitting.py b/example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/python/01/flux_splitting.py similarity index 100% rename from example/inviscid-burgers-equation/conservative-form/flux_splitting/01/flux_splitting.py rename to example/inviscid-burgers-equation/conservative-form/flux_splitting/lax/python/01/flux_splitting.py diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/main.cpp index 4111334e..0e984633 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/main.cpp +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01/main.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include @@ -9,13 +9,50 @@ auto SQR(Args... args) { return (... + (args * args)); } -void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); -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 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 ]; + } +} + +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 nx, std::vector & u, std::vector & f ); +void crwenoR( int nx, std::vector & u, std::vector & f ); void rhs( int nx, double dx, std::vector & u, std::vector & r ); void numerical( int nx, int ns, int nt, double dx, double dt, std::vector> & u ); +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); -double wcL( double v1, double v2, double v3, double v4, double v5 ) +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; @@ -25,26 +62,26 @@ double wcL( double v1, double v2, double v3, double v4, double v5 ) 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 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 ); - // 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 ); + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; - return f; + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; } -double wcR( double v1, double v2, double v3, double v4, double v5 ) +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; @@ -55,41 +92,37 @@ double wcR( double v1, double v2, double v3, double v4, double 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 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 ); - // 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 ); + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; - return f; + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; } -//----------------------------------------------------------------------------- -// 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 nx, std::vector & u, std::vector & f ) +void crwenoL( int nx, std::vector & u, std::vector & f ) { + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + int i; double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; i = 0; - v1 = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; - v2 = 2.0 * u[ i ] - u[ i + 1 ]; - v3 = u[ i ]; - v4 = u[ i + 1 ]; - v5 = u[ i + 2 ]; - f[ i ] = wcL( v1, v2, v3, v4, v5 ); + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; i = 1; v1 = 2.0 * u[ i - 1 ] - u[ i ]; @@ -97,7 +130,12 @@ void wenoL( int nx, std::vector & u, std::vector & f ) v3 = u[ i ]; v4 = u[ i + 1 ]; v5 = u[ i + 2 ]; - f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; for ( int i = 2; i < nx - 1; ++ i ) { @@ -106,35 +144,37 @@ void wenoL( int nx, std::vector & u, std::vector & f ) v3 = u[ i ]; v4 = u[ i + 1 ]; v5 = u[ i + 2 ]; - f[ i ] = wcL( v1, v2, v3, v4, v5 ); + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; } i = nx - 1; - v1 = u[ i - 2 ]; - v2 = u[ i - 1 ]; - v3 = u[ i ]; - v4 = u[ i + 1 ]; - v5 = 2.0 * u[ i + 1 ] - u[ i ]; - f[ i ] = wcL( v1, v2, v3, v4, v5 ); + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); } -//----------------------------------------------------------------------------- -// 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 nx, std::vector & u, std::vector & f ) +void crwenoR( int nx, std::vector & u, std::vector & f ) { + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + int i; double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; i = 1; - v1 = 2.0 * u[ i - 1 ] - u[ i ]; - v2 = u[ i - 1 ]; - v3 = u[ i ]; - v4 = u[ i + 1 ]; - v5 = u[ i + 2 ]; - f[ i ] = wcR( v1, v2, v3, v4, v5 ); + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + for ( int i = 2; i < nx - 1; ++ i ) { v1 = u[ i - 2 ]; @@ -142,7 +182,13 @@ void wenoR( int nx, std::vector & u, std::vector & f ) v3 = u[ i ]; v4 = u[ i + 1 ]; v5 = u[ i + 2 ]; - f[ i ] = wcR( v1, v2, v3, v4, v5 ); + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; } i = nx - 1; @@ -151,15 +197,19 @@ void wenoR( int nx, std::vector & u, std::vector & f ) v3 = u[ i ]; v4 = u[ i + 1 ]; v5 = 2.0 * u[ i + 1 ] - u[ i ]; - f[ i ] = wcR( v1, v2, v3, v4, v5 ); + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; i = nx; - v1 = u[ i - 2 ]; - v2 = u[ i - 1 ]; - v3 = u[ i ]; - v4 = 2.0 * u[ i ] - u[ i - 1 ]; - v5 = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; - f[ i ] = wcR( v1, v2, v3, v4, v5 ); + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); } //----------------------------------------------------------------------------- @@ -168,10 +218,10 @@ void wenoR( int nx, std::vector & u, std::vector & f ) void rhs( int nx, double dx, std::vector & u, std::vector & r ) { std::vector uL( nx, 0 ); - std::vector uR( nx + 1, 0 ); + std::vector uR( nx, 0 ); - wenoL( nx, u, uL ); - wenoR( nx, u, uR ); + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); for ( int i = 1; i < nx; ++ i ) { @@ -181,7 +231,7 @@ void rhs( int nx, double dx, std::vector & u, std::vector & r ) } else { - r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; } } } @@ -257,7 +307,7 @@ void numerical( int nx, int ns, int nt, double dx, double dt, std::vector &x, std::vector> &u ) { std::fstream file; - file.open(filename.c_str(), std::fstream::out); + file.open( filename.c_str(), std::fstream::out ); for ( int i = 0; i < u.size(); ++ i ) { std::string str = {}; @@ -303,6 +353,5 @@ int main( int argc, char ** argv ) } numerical( nx, ns, nt, dx, dt, u ); - return 0; } diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CMakeLists.txt new file mode 100644 index 00000000..8efec105 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CMakeLists.txt @@ -0,0 +1,57 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.cpp new file mode 100644 index 00000000..970f9b3d --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.cpp @@ -0,0 +1,281 @@ +#include "crweno.h" +#include "hxmath.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 ); + + 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 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 ); + + 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 crwenoL( int nx, std::vector & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 2; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, std::vector & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + i = nx; + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, std::vector & u, std::vector & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void mynumerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + std::vector> u( nx + 1 ); + for ( int i = 0; i < u.size(); ++ i ) + { + u[ i ].resize( ns + 1 ); + } + + std::vector x( nx + 1, 0 ); + std::vector un( nx + 1, 0 ); // numerical solsution at every time step + std::vector ut( nx + 1, 0 ); // temporary array during RK3 integration + std::vector r( nx, 0 ); + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + for ( int i = 0; i < nx + 1; ++ i ) + { + x[ i ] = dx * ( i ); + un[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + u[ i ][ k ] = un[ i ]; //store solution at t = 0; + } + + //dirichlet boundary condition + u[ 0 ][ k ] = 0.0; + u[ nx ][ k ] = 0.0; + + un[ 0 ] = 0.0; + un[ nx ] = 0.0; + + //dirichlet boundary condition for temporary array + ut[ 0 ] = 0.0; + ut[ nx ] = 0.0; + + for ( int j = 1; j < nt + 1; ++ j ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( j % freq == 0 ) + { + k = k + 1; + for ( int i = 0; i < nx + 1; ++ i ) + { + u[ i ][ k ] = un[ i ]; + } + std::print( "k={}, ns={}\n", k, ns ); + } + } + + DumpCsvFile( "field_final.csv", x, u ); +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.h new file mode 100644 index 00000000..e8884b87 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/crweno.h @@ -0,0 +1,15 @@ +#pragma once +#include +#include "hxmath.h" + +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 nx, std::vector & u, std::vector & f ); +void crwenoR( int nx, std::vector & u, std::vector & f ); +void rhs_crweno( int nx, double dx, std::vector & u, std::vector & r ); +void mynumerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/hxmath.h new file mode 100644 index 00000000..bd9304a2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/hxmath.h @@ -0,0 +1,15 @@ +#pragma once +#include + +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, std::vector &, std::vector &); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/main.cpp new file mode 100644 index 00000000..9b0a4faf --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + mynumerical( rhs ); + ///mynumerical( rhs_crweno ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.cpp new file mode 100644 index 00000000..649b4cdb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.cpp @@ -0,0 +1,25 @@ +#include "post.h" +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.h new file mode 100644 index 00000000..49d03e4a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/post.h @@ -0,0 +1,5 @@ +#pragma once +#include +#include + +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.cpp new file mode 100644 index 00000000..4eb86615 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.cpp @@ -0,0 +1,180 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, std::vector & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 0; + v1 = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + v2 = 2.0 * u[ i ] - u[ i + 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// 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 nx, std::vector & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + + i = nx; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = 2.0 * u[ i ] - u[ i - 1 ]; + v5 = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, std::vector & u, std::vector & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx + 1, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.h new file mode 100644 index 00000000..2fa4b9e2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01a/weno.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include + +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 nx, std::vector & u, std::vector & f ); +void wenoR( int nx, std::vector & u, std::vector & f ); +void rhs( int nx, double dx, std::vector & u, std::vector & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/MyCRWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/MyCRWenoPlot.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.cpp new file mode 100644 index 00000000..72ecb1ff --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.cpp @@ -0,0 +1,305 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 ); + + 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 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 ); + + 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 crwenoL( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 2; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + i = nx; + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.h new file mode 100644 index 00000000..ee637593 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/crweno.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/main.cpp new file mode 100644 index 00000000..a3d4eee4 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/main.cpp @@ -0,0 +1,9 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.cpp new file mode 100644 index 00000000..5b230250 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.cpp @@ -0,0 +1,180 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, std::vector & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 0; + v1 = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + v2 = 2.0 * u[ i ] - u[ i + 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// 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 nx, std::vector & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + + i = nx; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = 2.0 * u[ i ] - u[ i - 1 ]; + v5 = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, std::vector & u, std::vector & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.h new file mode 100644 index 00000000..2fa4b9e2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01b/weno.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include + +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 nx, std::vector & u, std::vector & f ); +void wenoR( int nx, std::vector & u, std::vector & f ); +void rhs( int nx, double dx, std::vector & u, std::vector & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.cpp new file mode 100644 index 00000000..b7c9043b --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.cpp @@ -0,0 +1,308 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 ); + + 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 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 ); + + 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 crwenoL( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 2; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + i = nx; + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.h new file mode 100644 index 00000000..ee637593 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/crweno.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.cpp new file mode 100644 index 00000000..cf727ce9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.cpp @@ -0,0 +1,180 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 0; + v1 = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + v2 = 2.0 * u[ i ] - u[ i + 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + + i = nx; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = 2.0 * u[ i ] - u[ i - 1 ]; + v5 = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01c/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.cpp new file mode 100644 index 00000000..b7c9043b --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.cpp @@ -0,0 +1,308 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 ); + + 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 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 ); + + 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 crwenoL( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; + + i = 1; + v1 = 2.0 * u[ i - 1 ] - u[ i ]; + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 2; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + + for ( int i = 2; i < nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = 2.0 * u[ i + 1 ] - u[ i ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + i = nx; + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.h new file mode 100644 index 00000000..ee637593 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/crweno.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.cpp new file mode 100644 index 00000000..25ab3985 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.cpp @@ -0,0 +1,133 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 1; i <= nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i - 1 ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01d/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.cpp new file mode 100644 index 00000000..78c3635d --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.cpp @@ -0,0 +1,320 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 ); + + //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 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 ); + + //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 crwenoL( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + //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 ); + //double rr = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + b[ i ] = 2.0 / 3.0; + c[ i ] = 1.0 / 3.0; + r[ i ] = ( u[ i ] + 5.0 * u[ i + 1 ] ) / 6.0; + + for ( int i = 1; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + b[ i - 1 ] = 2.0 / 3.0; + c[ i - 1 ] = 1.0 / 3.0; + r[ i - 1 ] = ( u[ i - 1 ] + 5.0 * u[ i ] ) / 6.0; + + for ( int i = 2; i <= nx - 1; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ i - 1 ] = a1; + b[ i - 1 ] = a2; + c[ i - 1 ] = a3; + r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx; + a[ i - 1 ] = 1.0 / 3.0; + b[ i - 1 ] = 2.0 / 3.0; + r[ i - 1 ] = ( 5.0 * u[ i - 1 ] + u[ i ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.cpp new file mode 100644 index 00000000..0c189ae6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.cpp @@ -0,0 +1,133 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01e/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.cpp new file mode 100644 index 00000000..a2c5901a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.cpp @@ -0,0 +1,318 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 1; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i, j; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + j = i - 1; + //crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + + //b[ j ] = 2.0 / 3.0; + //c[ j ] = 1.0 / 3.0; + //r[ j ] = ( u[ j ] + 5.0 * u[ j + 1 ] ) / 6.0; + + b[ j ] = 1.0 / 3.0; + c[ j ] = 2.0 / 3.0; + r[ j ] = ( 5.0 * u[ j ] + u[ j + 1 ] ) / 6.0; + + //double rr = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + int kkk = 1; + + //a[ i ] = a1; + //b[ i ] = a2; + //c[ i ] = a3; + //r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int j = 1; j < nx; ++ j ) + { + //j = i - 1; + i = j + 1; + v1 = u[ j - 1 ]; + v2 = u[ j ]; + v3 = u[ j + 1 ]; + v4 = u[ j + 2 ]; + v5 = u[ j + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ j ] = a1; + b[ j ] = a2; + c[ j ] = a3; + r[ j ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx; + j = i - 1; + a[ j ] = 1.0 / 3.0; + b[ j ] = 2.0 / 3.0; + r[ j ] = ( 5.0 * u[ j ] + u[ j + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.cpp new file mode 100644 index 00000000..0c189ae6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.cpp @@ -0,0 +1,133 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + int i; + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01f/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.cpp new file mode 100644 index 00000000..1d19c11a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.cpp @@ -0,0 +1,385 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 1; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, f ); +} + +//void crwenoR( int nx, Vec1d & u, std::vector & f ) +//{ +// std::vector a( nx ); +// std::vector b( nx ); +// std::vector c( nx ); +// std::vector r( nx ); +// +// int i, j; +// double v1, v2, v3, v4, v5; +// double a1, a2, a3, b1, b2, b3; +// +// i = 0; +// crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); +// +// a[ i ] = a1; +// b[ i ] = a2; +// c[ i ] = a3; +// r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; +// +// for ( int i = 1; i < nx - 1; ++ i ) +// { +// 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[ i ] = a1; +// b[ i ] = a2; +// c[ i ] = a3; +// r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; +// } +// +// i = nx - 1; +// crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); +// +// a[ i ] = a1; +// b[ i ] = a2; +// c[ i ] = a3; +// r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; +// +// thomas_algorithm( a, b, c, r, f ); +//} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i, j; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 1; + j = i - 1; + //crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + + //b[ j ] = 2.0 / 3.0; + //c[ j ] = 1.0 / 3.0; + //r[ j ] = ( u[ j ] + 5.0 * u[ j + 1 ] ) / 6.0; + + b[ j ] = 1.0 / 3.0; + c[ j ] = 2.0 / 3.0; + r[ j ] = ( 5.0 * u[ j ] + u[ j + 1 ] ) / 6.0; + + //for ( int i = 2; i <= nx; ++ i ) + //{ + // v1 = u[ i - 2 ]; + // v2 = u[ i - 1 ]; + // v3 = u[ i ]; + // v4 = u[ i + 1 ]; + // v5 = u[ i + 2 ]; + + // crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + // a[ i - 1 ] = a1; + // b[ i - 1 ] = a2; + // c[ i - 1 ] = a3; + // r[ i - 1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + //} + + //for ( int i = 2; i <= nx - 1; ++ i ) + //{ + // v1 = u[ i - 2 ]; + // v2 = u[ i - 1 ]; + // v3 = u[ i ]; + // v4 = u[ i + 1 ]; + // v5 = u[ i + 2 ]; + + // crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + // a[ i-1 ] = a1; + // b[ i-1 ] = a2; + // c[ i-1 ] = a3; + // r[ i-1 ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + //} + + for ( int i = 1; i <= nx - 2; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = nx - 1; + a[ i ] = 1.0 / 3.0; + b[ i ] = 2.0 / 3.0; + r[ i ] = ( 5.0 * u[ i ] + u[ i + 1 ] ) / 6.0; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.cpp new file mode 100644 index 00000000..9e7ac63e --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01g/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.cpp new file mode 100644 index 00000000..87decf84 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.cpp @@ -0,0 +1,305 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 1; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = nx - 1; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx ); + std::vector b( nx ); + std::vector c( nx ); + std::vector r( nx ); + + int i, j; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + i = 0; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 1; i < nx - 1; ++ i ) + { + 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[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = nx - 1; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ i ] = a1; + b[ i ] = a2; + c[ i ] = a3; + r[ i ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.cpp new file mode 100644 index 00000000..9e7ac63e --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/01h/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.cpp new file mode 100644 index 00000000..dc842598 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.cpp @@ -0,0 +1,314 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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 <= nx - 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 = nx; + 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, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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 <= nx - 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 = nx; + 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.cpp new file mode 100644 index 00000000..9e7ac63e --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + for ( int i = 0; i < nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx, 0 ); + std::vector uR( nx, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i ] - uL[ i - 1 ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i ] - uR[ i - 1 ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.cpp new file mode 100644 index 00000000..dc842598 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.cpp @@ -0,0 +1,314 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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 <= nx - 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 = nx; + 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, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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 <= nx - 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 = nx; + 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + //std::vector x( nx + 1, 0 ); + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d r; + r.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + ulist[ 0 ] = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, r ); + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = un[ i ] + dt * r[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * r[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, r ); + + for ( int i = 1; i < nx; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * r[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + ulist[ k ] = un; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.cpp new file mode 100644 index 00000000..e9969afa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.cpp @@ -0,0 +1,135 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + int ist = -1; + for ( int i = ist; i <= nx; ++ i ) + { + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 nx, Vec1d & u, std::vector & f ) +{ + double v1, v2, v3, v4, v5; + + int ist = -1; + for ( int i = ist; i <= nx; ++ i ) + { + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + + for ( int i = 1; i < nx; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02a/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.cpp new file mode 100644 index 00000000..5d1d210b --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.cpp @@ -0,0 +1,307 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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 nx, Vec1d & u, std::vector & f ) +{ + int ni = nx + 1; + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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, f ); +} + +void crwenoR( int nx, Vec1d & u, std::vector & f ) +{ + int ni = nx + 1; + std::vector a( nx + 2 ); + std::vector b( nx + 2 ); + std::vector c( nx + 2 ); + std::vector r( nx + 2 ); + + 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + int ni = nx + 1; + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int nx, Vec1d & u ) +{ + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = nx; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( nx, ut ); + un = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, res ); + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = un[ i ] + dt * res[ i ]; + } + + boundary( nx, ut ); + rhs( nx, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * res[ i ]; + } + boundary( nx, ut ); + rhs( nx, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * res[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.h new file mode 100644 index 00000000..3c5cebfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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 nx, Vec1d & u, std::vector & f ); +void crwenoR( int nx, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.cpp similarity index 77% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.cpp rename to example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.cpp index c153be32..4d4e3d12 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.cpp +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.cpp @@ -1,5 +1,11 @@ -#include "Weno.h" +#include "weno.h" +#include "hxmath.h" +#include "post.h" #include +#include +#include +#include +#include double wcL( double v1, double v2, double v3, double v4, double v5 ) { @@ -64,23 +70,18 @@ double wcR( double v1, double v2, double v3, double v4, double v5 ) // 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, std::vector & u, std::vector & f ) +void wenoL( int nx, Vec1d & u, std::vector & f ) { - int igL = 2; - int igR = 2; - int ist = igL; - int ied = ist + N - 1; - //for ( int i = ist + 1; i <= ied; ++ i ) - //{ - // int ii = i - ist - 1; - for ( int i = ist; i <= ied - 1; ++ i ) + int ni = nx + 1; + int ist = -1; + for ( int i = ist; i < ni; ++ i ) { - int ii = i - ist; double v1 = u[ i - 2 ]; double v2 = u[ i - 1 ]; double v3 = u[ i ]; double v4 = u[ i + 1 ]; double v5 = u[ i + 2 ]; + int ii = i - ist; f[ ii ] = wcL( v1, v2, v3, v4, v5 ); } } @@ -90,20 +91,19 @@ void wenoL( int N, std::vector & u, std::vector & f ) // 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, std::vector & u, std::vector & f ) +void wenoR( int nx, Vec1d & u, std::vector & f ) { - int igL = 2; - int igR = 2; - int ist = igL; - int ied = ist + N - 1; - for ( int i = ist + 1; i <= ied; ++ i ) + int ni = nx + 1; + + int ist = -1; + for ( int i = ist; i < ni; ++ i ) { - int ii = i - ist - 1; - double v1 = u[ i - 2 ]; - double v2 = u[ i - 1 ]; - double v3 = u[ i ]; - double v4 = u[ i + 1 ]; - double v5 = u[ i + 2 ]; + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; f[ ii ] = wcR( v1, v2, v3, v4, v5 ); } } @@ -111,23 +111,16 @@ void wenoR( int N, std::vector & u, std::vector & f ) //----------------------------------------------------------------------------- // Calculate right hand term of the inviscid Burgers equation //----------------------------------------------------------------------------- -void WenoRhs( int N, double dx, std::vector & u, std::vector & r ) +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) { - std::vector uL( N - 1, 0 ); - std::vector uR( N - 1, 0 ); - - wenoL( N, u, uL ); - wenoR( N, u, uR ); + int ni = nx + 1; + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); - int igL = 2; - int igR = 2; - int ist = igL; - int ied = ist + N - 1; + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); - //1~N-2:3~N - //ist+1->ied-1 - - for ( int i = ist + 1; i <= ied - 1; ++ i ) + for ( int i = 0; i < ni; ++ i ) { if ( u[ i ] >= 0.0 ) { @@ -138,4 +131,5 @@ void WenoRhs( int N, double dx, std::vector & u, std::vector & r r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; } } -} \ No newline at end of file +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.h new file mode 100644 index 00000000..2f462eb6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02b/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 nx, Vec1d & u, std::vector & f ); +void wenoR( int nx, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.cpp new file mode 100644 index 00000000..e38f40c2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.cpp @@ -0,0 +1,313 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +void crwenoR( int ni, Vec1d & u, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + int ni = nx + 1; + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int ni, Vec1d & u ) +{ +// x=0 ui+1/2,L x=L +// o o o o o o ... * * * | * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 +// +// x=0 ui+1/2,R x=L +// o o o o o o ... * * | * * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 + + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = ni - 1; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int nx = 200; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / nx; + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "nx={}\n", nx ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ni = nx + 1; + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( ni, ut ); + un = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( nx, dx, un, res ); + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = un[ i ] + dt * res[ i ]; + } + + boundary( ni, ut ); + rhs( nx, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * res[ i ]; + } + boundary( ni, ut ); + rhs( nx, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * res[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.h new file mode 100644 index 00000000..43dc74ad --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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, std::vector & f ); +void crwenoR( int ni, Vec1d & u, std::vector & f ); +void rhs_crweno( int nx, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.cpp new file mode 100644 index 00000000..c157b65d --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.cpp @@ -0,0 +1,132 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 2 ]; + double v2 = u[ i - 1 ]; + double v3 = u[ i ]; + double v4 = u[ i + 1 ]; + double v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ) +{ + int ni = nx + 1; + std::vector uL( nx + 2, 0 ); + std::vector uR( nx + 2, 0 ); + + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.h new file mode 100644 index 00000000..65d37f40 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02c/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 ni, Vec1d & u, std::vector & f ); +void wenoR( int ni, Vec1d & u, std::vector & f ); +void rhs( int nx, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.cpp new file mode 100644 index 00000000..44d2c887 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.cpp @@ -0,0 +1,310 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +void crwenoR( int ni, Vec1d & u, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int ni, Vec1d & u ) +{ +// x=0 ui+1/2,L x=L +// o o o o o o ... * * * | * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 +// +// x=0 ui+1/2,R x=L +// o o o o o o ... * * | * * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 + + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = ni - 1; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int ni = 201; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / ( ni - 1 ); + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d ut; + ut.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + ut[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( ni, ut ); + un = ut; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( ni, dx, un, res ); + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = un[ i ] + dt * res[ i ]; + } + + boundary( ni, ut ); + rhs( ni, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + ut[ i ] = 0.75 * un[ i ] + 0.25 * ut[ i ] + 0.25 * dt * res[ i ]; + } + boundary( ni, ut ); + rhs( ni, dx, ut, res ); + + for ( int i = 0; i < ni; ++ i ) + { + un[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * ut[ i ] + ( 2.0 / 3.0 ) * dt * res[ i ]; + } + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.h new file mode 100644 index 00000000..3f22cb2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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, std::vector & f ); +void crwenoR( int ni, Vec1d & u, std::vector & f ); +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.cpp new file mode 100644 index 00000000..cb0542b0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 2 ]; + double v2 = u[ i - 1 ]; + double v3 = u[ i ]; + double v4 = u[ i + 1 ]; + double v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.h new file mode 100644 index 00000000..e95f4651 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02d/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 ni, Vec1d & u, std::vector & f ); +void wenoR( int ni, Vec1d & u, std::vector & f ); +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.cpp new file mode 100644 index 00000000..ba15dbd1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.cpp @@ -0,0 +1,311 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +void crwenoR( int ni, Vec1d & u, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int ni, Vec1d & u ) +{ +// x=0 ui+1/2,L x=L +// o o o o o o ... * * * | * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 +// +// x=0 ui+1/2,R x=L +// o o o o o o ... * * | * * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 + + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = ni - 1; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void numerical( RhsPtr rhs ) +{ + int ni = 201; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / ( ni - 1 ); + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d u; + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( ni, u ); + un = u; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + rhs( ni, dx, un, res ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + + boundary( ni, u ); + rhs( ni, dx, u, res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + boundary( ni, u ); + rhs( ni, dx, u, res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * u[ i ] + ( 2.0 / 3.0 ) * dt * res[ i ]; + } + un = u; + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.h new file mode 100644 index 00000000..3f22cb2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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, std::vector & f ); +void crwenoR( int ni, Vec1d & u, std::vector & f ); +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/main.cpp new file mode 100644 index 00000000..f66ae7db --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + numerical( rhs_crweno ); + //numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.cpp new file mode 100644 index 00000000..cb0542b0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 2 ]; + double v2 = u[ i - 1 ]; + double v3 = u[ i ]; + double v4 = u[ i + 1 ]; + double v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.h new file mode 100644 index 00000000..e95f4651 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02e/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 ni, Vec1d & u, std::vector & f ); +void wenoR( int ni, Vec1d & u, std::vector & f ); +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.cpp new file mode 100644 index 00000000..c209e828 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.cpp @@ -0,0 +1,326 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +void crwenoR( int ni, Vec1d & u, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int ni, Vec1d & u ) +{ +// x=0 ui+1/2,L x=L +// o o o o o o ... * * * | * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 +// +// x=0 ui+1/2,R x=L +// o o o o o o ... * * | * * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 + + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = ni - 1; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void runge_kutta_stage1( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void runge_kutta_stage2( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void runge_kutta_stage3( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = ( 1.0 / 3.0 ) * un[ i ] + ( 2.0 / 3.0 ) * u[ i ] + ( 2.0 / 3.0 ) * dt * res[ i ]; + } +} + +void numerical( RhsPtr rhs ) +{ + int ni = 201; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / ( ni - 1 ); + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d u; + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( ni, u ); + un = u; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + runge_kutta_stage1( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + runge_kutta_stage2( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + runge_kutta_stage3( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + un = u; + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.h new file mode 100644 index 00000000..3f22cb2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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, std::vector & f ); +void crwenoR( int ni, Vec1d & u, std::vector & f ); +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.cpp new file mode 100644 index 00000000..cb0542b0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 2 ]; + double v2 = u[ i - 1 ]; + double v3 = u[ i ]; + double v4 = u[ i + 1 ]; + double v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.h new file mode 100644 index 00000000..e95f4651 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02f/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 ni, Vec1d & u, std::vector & f ); +void wenoR( int ni, Vec1d & u, std::vector & f ); +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CMakeLists.txt new file mode 100644 index 00000000..ed88efa2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CMakeLists.txt @@ -0,0 +1,58 @@ +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}" ) + +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 + hxmath.h hxmath.cpp + weno.h weno.cpp + crweno.h crweno.cpp + post.h post.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CRWenoPlot.py new file mode 100644 index 00000000..8154e6b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/CRWenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/MyCRWenoPlot.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/MyCRWenoPlot.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.cpp new file mode 100644 index 00000000..76c5dc03 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.cpp @@ -0,0 +1,330 @@ +#include "crweno.h" +#include "hxmath.h" +#include "vec1d.h" +#include "post.h" +#include +#include +#include +#include +#include + +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, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +void crwenoR( int ni, Vec1d & u, std::vector & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( 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, f ); +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + +void boundary( int ni, Vec1d & u ) +{ +// x=0 ui+1/2,L x=L +// o o o o o o ... * * * | * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 +// +// x=0 ui+1/2,R x=L +// o o o o o o ... * * | * * * ... o o o o +//-3 -2 -1 i=0 1 2 i-2 i-1 i | i+1 i+2 i+3 i=N-1 N N+1 N+2 + + //left bc + int i = 0; + u[ i ] = 0.0; + u[ i - 1 ] = 2.0 * u[ i ] - u[ i + 1 ]; + u[ i - 2 ] = 3.0 * u[ i ] - 2.0 * u[ i + 1 ]; + u[ i - 3 ] = 4.0 * u[ i ] - 3.0 * u[ i + 1 ]; + + //right bc + i = ni - 1; + u[ i ] = 0.0; + u[ i + 1 ] = 2.0 * u[ i ] - u[ i - 1 ]; + u[ i + 2 ] = 3.0 * u[ i ] - 2.0 * u[ i - 1 ]; + u[ i + 3 ] = 4.0 * u[ i ] - 3.0 * u[ i - 1 ]; +} + +void runge_kutta_stage1( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void runge_kutta_stage2( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void runge_kutta_stage3( RhsPtr rhs, int ni, Vec1d & u, Vec1d & un, Vec1d & res, double dx, double dt ) +{ + rhs( ni, dx, u, res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void numerical( RhsPtr rhs ) +{ + int ni = 201; + int ns = 10; + double dt = 0.0001; + double tm = 0.25; + + double dx = 1.0 / ( ni - 1 ); + int nt = std::round( tm / dt ); + double ds = tm / ns; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "tm={}\n", tm ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + + int ighost = 3; + int ist = 0 - ighost; + int ied = ni - 1 + ighost; + + Vec1d un; + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + + Vec1d u; + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + + Vec1d res; + res.Allocate( 0, ni, 0 ); //N+1 + + Vec1d x; + x.Allocate( 0, ni - 1, 0 ); // npoints = N = nx + 1 + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = dx * ( i ); + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int k = 0; // record index + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + + boundary( ni, u ); + un = u; + + int iter = 0; + DumpField( iter, x, un ); + + for ( int it = 0; it < nt; ++ it ) + { + runge_kutta_stage1( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + runge_kutta_stage2( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + runge_kutta_stage3( rhs, ni, u, un, res, dx, dt ); + boundary( ni, u ); + un = u; + + if ( ( it + 1 ) % freq == 0 ) + { + k = k + 1; + std::print( "k={}, ns={}\n", k, ns ); + DumpField( it + 1, x, un ); + } + } +} + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.h new file mode 100644 index 00000000..3f22cb2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/crweno.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "hxmath.h" +#include "vec1d.h" + +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, std::vector & f ); +void crwenoR( int ni, Vec1d & u, std::vector & f ); +void rhs_crweno( int ni, double dx, Vec1d & u, Vec1d & r ); +void numerical( RhsPtr rhs ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/main.cpp new file mode 100644 index 00000000..5b8936e6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/main.cpp @@ -0,0 +1,10 @@ +#include "weno.h" +#include "crweno.h" + +int main( int argc, char ** argv ) +{ + //numerical( rhs_crweno ); + numerical( rhs ); + + return 0; +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.cpp new file mode 100644 index 00000000..b039dbb7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.cpp @@ -0,0 +1,49 @@ +#include "post.h" +#include "Vec1d.h" +#include +#include + +void DumpCsvFile( const std::string &filename, std::vector &x, std::vector> &u ) +{ + std::fstream file; + file.open( filename.c_str(), std::fstream::out ); + for ( int i = 0; i < u.size(); ++ i ) + { + std::string str = {}; + str += std::format( "{:.16f} ", x[ i ] ); + int nj = u[ i ].size(); + for ( int j = 0; j < nj; ++ j ) + { + double value = u[ i ][ j ]; + str += std::format( "{:.16f}", value ); + if ( j != nj - 1 ) + { + str += " "; + } + } + std::format_to(std::ostream_iterator(file), "{}\n", str ); + } + file.close(); +} + +void DumpField( int iter, Vec1d & x, Vec1d & u ) +{ + std::string total_string = {}; + std::fstream file; + { + std::string filename = std::format( "field_final{}.csv", iter ); + file.open( filename.c_str(), std::fstream::out ); + } + std::string file_string = {}; + + for ( int i = 0; i < x.size(); ++ i ) + { + file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } + + total_string += file_string; + + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.h new file mode 100644 index 00000000..a9bec8ce --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/post.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include + +class Vec1d; +void DumpCsvFile( const std::string & filename, std::vector & x, std::vector> & u ); +void DumpField( int iter, Vec1d & x, Vec1d & u ); \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.cpp new file mode 100644 index 00000000..cb0542b0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.cpp @@ -0,0 +1,131 @@ +#include "weno.h" +#include "hxmath.h" +#include "post.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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 2 ]; + double v2 = u[ i - 1 ]; + double v3 = u[ i ]; + double v4 = u[ i + 1 ]; + double v5 = u[ i + 2 ]; + int ii = i - ist; + f[ ii ] = wcL( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// 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 ni, Vec1d & u, std::vector & f ) +{ + int ist = -1; + for ( int i = ist; i < ni; ++ i ) + { + double v1 = u[ i - 1 ]; + double v2 = u[ i ]; + double v3 = u[ i + 1 ]; + double v4 = u[ i + 2 ]; + double v5 = u[ i + 3 ]; + int ii = i - ist; + f[ ii ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +//----------------------------------------------------------------------------- +// Calculate right hand term of the inviscid Burgers equation +//----------------------------------------------------------------------------- +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ) +{ + std::vector uL( ni + 1, 0 ); + std::vector uR( ni + 1, 0 ); + + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + + for ( int i = 0; i < ni; ++ i ) + { + if ( u[ i ] >= 0.0 ) + { + r[ i ] = - u[ i ] * ( uL[ i + 1 ] - uL[ i ] ) / dx; + } + else + { + r[ i ] = - u[ i ] * ( uR[ i + 1 ] - uR[ i ] ) / dx; + } + } +} + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.h new file mode 100644 index 00000000..e95f4651 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/02g/weno.h @@ -0,0 +1,11 @@ +#pragma once +#include +#include + +class Vec1d; + +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 ni, Vec1d & u, std::vector & f ); +void wenoR( int ni, Vec1d & u, std::vector & f ); +void rhs( int ni, double dx, Vec1d & u, Vec1d & r ); diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CgnsUtil.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..31180100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.cpp @@ -0,0 +1,283 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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 nghost = 2; + int ni_total = ni + nghost; + + int N = this->ni; + + int ighost = 1; + int iist = 0 - ighost; + int iied = N - 1 + ighost; + u_e.Allocate( iist, iied ); + u.Allocate( iist, iied ); + un.Allocate( iist, iied ); + res.Allocate( 0, N, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.h similarity index 50% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.h rename to example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.h index a7dc4658..d0479a13 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.h +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Field.h @@ -1,44 +1,57 @@ #pragma once #include -#include "global.h" -#include "cgnslib.h" +#include "Vec1d.h" class Zone; class Grid; +class Region; class Field { public: - std::vector u_e; - std::vector u, un, u1; - std::vector r; - std::vector error; + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ public: int ni; int nt; - double dx, dt, t; + double dx, dt, total_time; double alpha, beta; public: void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); public: void FTCS( Zone * zone ); void CN( Zone * zone ); void ICP( Zone * zone ); - void WENO5( Zone * zone ); void RungeKutta( Zone * zone, int istage ); void RungeKutta3Stage0( Zone * zone ); void RungeKutta3Stage1( Zone * zone ); void RungeKutta3Stage2( Zone * zone ); public: - void Rhs( std::vector & u, std::vector & r ); + void Rhs( Vec1d & u, Vec1d & r ); void Boundary( Region & region, int bcType ); void InflowBc( Region & region ); void OutflowBc( Region & region ); void PhysicalBoundary( Zone * zone ); - - void PostProcess( Grid * grid ); void UpdateOldField(); - void UpdateRungeKuttaOldField( int istage = 0 ); }; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.cpp similarity index 88% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.cpp rename to example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.cpp index df1e6bae..2a6f4570 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/global.cpp +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.cpp @@ -1,5 +1,5 @@ -#include "global.h" -#include "CgnsGrid.h" +#include "Global.h" +#include "Grid.h" #include "ZoneState.h" #include "Parallel.h" #include @@ -7,12 +7,15 @@ std::vector Global::grids; std::vector Global::fields; +Scheme Global::scheme = Scheme::FTCS; int Global::nt = -1; +int Global::iter = -1; int Global::cell_dim = -1; int Global::phys_dim = -1; +int Global::nghost = -1; +std::string Global::file_string=""; std::vector Global::zones; -BaseZoneList Global::zone_names; std::vector Global::interfaces; std::map Global::faceMap; @@ -190,7 +193,7 @@ void InterfaceTopo::SwapNeighborDonorfaces() } -void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid, int nghost ) { int ist = start[ 0 ]; int ied = end[ 0 ]; @@ -223,16 +226,20 @@ void Interface::CalcInterface( Transform * transform, std::vector & start, int nSize = Global::facePairList.size(); this->proc_global_faceids.push_back( nSize - 1 ); - int i_ghost_cell = i + 1; - int i_local_donor_cell = i - 1; - - if ( i == 1 ) - { - i_ghost_cell = i - 1; - i_local_donor_cell = i + 1; + if ( i == 1 ) { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } } - ijk_ghosts.push_back( i_ghost_cell ); - ijk_donors.push_back( i_local_donor_cell ); icount ++; } @@ -254,9 +261,13 @@ void Interface::SendGeom( int zone, std::vector & donorfaces ) { int global_faceid = donorfaces[ i ]; int local_faceid = interface->global_local_face_map[ global_faceid ]; - int ijkpos = index_dim * local_faceid; - int i_donor_cell = interface->ijk_donors[ ijkpos + 0 ]; - sub_donorijk.push_back( i_donor_cell ); + int ijkpos = index_dim * local_faceid * Global::nghost; + + for ( int ig = 0; ig < Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } int kkk = 1; } @@ -297,4 +308,3 @@ void Global::AddFacePairList( std::vector & a, std::vector & a.push_back( b[ i ] ); } } - diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/LogFile.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/LogFile.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..c842409e --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,542 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->nghost = 1; + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + this->scheme = Scheme::CRWENO; + this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + //this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../burgers1d1blocksv1.cgns"; + std::string fileName = "../burgers1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + if ( ( Global::iter + 1 ) % 250 == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->PostProcess(); + } + + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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(); +} + +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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 ijkpos = index_dim * local_faceid * nghost; + int data_pos = local_faceid * nghost; + int donor_data_pos = i * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + for ( int ig = 0; ig < nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + + double donor_value = interface->data_recv[ data_pos + ig ]; + field->u[ ig_cell ] = donor_value; + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int nData = nInterfaces * Global::nghost; + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..358305b9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,518 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..b09b944c --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/Weno.h @@ -0,0 +1,52 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/ZoneState.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/ZoneState.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CgnsUtil.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CgnsUtil.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.cpp new file mode 100644 index 00000000..31180100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.cpp @@ -0,0 +1,283 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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 nghost = 2; + int ni_total = ni + nghost; + + int N = this->ni; + + int ighost = 1; + int iist = 0 - ighost; + int iied = N - 1 + ighost; + u_e.Allocate( iist, iied ); + u.Allocate( iist, iied ); + un.Allocate( iist, iied ); + res.Allocate( 0, N, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.h new file mode 100644 index 00000000..05d0d94f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Field.h @@ -0,0 +1,58 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +}; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.cpp new file mode 100644 index 00000000..2a6f4570 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.cpp @@ -0,0 +1,310 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 ) { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * Global::nghost; + + for ( int ig = 0; ig < Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/LogFile.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/LogFile.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Plot9.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Plot9.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Plot9.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.cpp new file mode 100644 index 00000000..b8ae619f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.cpp @@ -0,0 +1,548 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->nghost = 1; + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + this->scheme = Scheme::CRWENO; + this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + //this->PostProcess(); +} + +void Solver::ReadGrid() +{ + //std::string fileName = "../burgers1d1blocksv1.cgns"; + std::string fileName = "../burgers1d2blocks.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + if ( ( Global::iter + 1 ) % 250 == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->PostProcess(); + } + + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 ijkpos = index_dim * local_faceid * nghost; + int data_pos = local_faceid * nghost; + int donor_data_pos = i * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + for ( int ig = 0; ig < nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + + double donor_value = interface->data_recv[ data_pos + ig ]; + field->u[ ig_cell ] = donor_value; + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int nData = nInterfaces * Global::nghost; + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.cpp new file mode 100644 index 00000000..a389d000 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + } +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/ZoneState.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/ZoneState.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01a/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CgnsUtil.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CgnsUtil.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.cpp new file mode 100644 index 00000000..31180100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.cpp @@ -0,0 +1,283 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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 nghost = 2; + int ni_total = ni + nghost; + + int N = this->ni; + + int ighost = 1; + int iist = 0 - ighost; + int iied = N - 1 + ighost; + u_e.Allocate( iist, iied ); + u.Allocate( iist, iied ); + un.Allocate( iist, iied ); + res.Allocate( 0, N, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.h new file mode 100644 index 00000000..05d0d94f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Field.h @@ -0,0 +1,58 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void InterfaceBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +}; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.cpp new file mode 100644 index 00000000..6b6114e7 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.cpp @@ -0,0 +1,314 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/LogFile.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/LogFile.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Plot9.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Plot9.py new file mode 100644 index 00000000..5bb12c00 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Plot9.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: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.cpp similarity index 56% rename from example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.cpp rename to example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.cpp index e7b5134e..c1d3832f 100644 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.cpp +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.cpp @@ -1,55 +1,29 @@ #include "Solver.h" +#include "CgnsUtil.h" #include "Parallel.h" +#include "Post.h" +#include "Weno.h" #include "ZoneState.h" #include "global.h" -#include "Weno.h" #include #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; -} - Solver::Solver() { Parallel::Init(); + //this->nghost = 1; //this->scheme = Scheme::FTCS; //this->scheme = Scheme::RungeKutta; //this->scheme = Scheme::CN; //this->scheme = Scheme::ICP; - this->scheme = Scheme::WENO5; - - //std::cout << sum(1, 2, 3, 4, 5) << std::endl; // 15 - //std::cout << SQR( 1, 1 ) << std::endl; - //std::cout << SQR( 2 ) << std::endl; - //std::cout << SQR( 2, 3 ) << std::endl; - int kkk = 1; + this->scheme = Scheme::CRWENO; + this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; } Solver::~Solver() @@ -57,186 +31,37 @@ Solver::~Solver() Parallel::Finalize(); } - void Solver::Run() { this->ReadGrid(); this->InitTopo(); this->InitFields(); this->SolveFields(); - this->PostProcess(); + //this->PostProcess(); } void Solver::ReadGrid() { - std::string fileName = "../heat1d1block.cgns"; + //std::string fileName = "../burgers1d1blocksv1.cgns"; + std::string fileName = "../burgers1d2blocks.cgns"; ReadCgnsGridBaseZone( fileName ); ReadCgnsGrid( fileName ); } -void Solver::InitTopo() +void Solver::InitFields() { std::cout << "Parallel::pid = " << Parallel::pid << " "; - std::cout << "Solver::InitTopo() " << "\n"; - - Global::donor_zone_sets.resize( LocalZone::nZones ); - Global::donor_zones.resize( LocalZone::nZones ); + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; 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(); - interface->data_recv.resize( nInterfaces ); - interface->data_send.resize( nInterfaces ); - } - - for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) - { - int nSize = -1; - if ( iProc == Parallel::pid ) - { - nSize = Global::facePairList.size(); + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); } - 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 { + field = new FieldSub(); } - 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(); - - int kkk = 1; -} - -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 ) - { - Field * field = new Field(); Global::fields.push_back( field ); } @@ -251,11 +76,18 @@ void Solver::InitFields() this->UpdateOldField(); } +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + void Solver::SolveFields() { + this->DumpInitialFields(); for ( int it = 0; it < Global::nt; ++ it ) { - switch (scheme) { + Global::iter = it; + switch ( scheme ) { case Scheme::FTCS: this->FTCS(); break; @@ -265,15 +97,24 @@ void Solver::SolveFields() case Scheme::ICP: this->ICP(); break; - case Scheme::WENO5: - this->WENO5(); + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); break; case Scheme::RungeKutta: this->RungeKutta(); break; default: this->FTCS(); - } + } + if ( ( Global::iter + 1 ) % 250 == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->PostProcess(); + } + } } @@ -316,25 +157,13 @@ void Solver::ICP() this->UpdateOldField(); } -void Solver::WENO5() -{ - for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) - { - Field * field = Global::fields[ iZone ]; - Zone * zone = Global::zones[ iZone ]; - zone->zoneIndex = iZone; - field->WENO5( zone ); - } - this->Boundary(); - this->UpdateOldField(); -} - void Solver::RungeKutta() { for ( int istage = 0; istage < 3; ++ istage ) { this->RungeKutta( istage ); } + this->UpdateOldField(); } void Solver::RungeKutta( int istage ) @@ -347,7 +176,6 @@ void Solver::RungeKutta( int istage ) field->RungeKutta( zone, istage ); } this->Boundary(); - this->UpdateRungeKuttaOldField( istage ); } void Solver::Boundary() @@ -359,25 +187,21 @@ void Solver::Boundary() field->PhysicalBoundary( zone ); } ExchangeInterfaceField(); -} - -void Solver::UpdateOldField() -{ for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) { Field * field = Global::fields[ iZone ]; Zone * zone = Global::zones[ iZone ]; - field->UpdateOldField(); + field->InterfaceBoundary( zone ); } } -void Solver::UpdateRungeKuttaOldField( int istage ) +void Solver::UpdateOldField() { for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) { Field * field = Global::fields[ iZone ]; Zone * zone = Global::zones[ iZone ]; - field->UpdateRungeKuttaOldField( istage ); + field->UpdateOldField(); } } @@ -387,29 +211,29 @@ void Solver::UploadInterfaceField() { Interface * interface = Global::interfaces[ iZone ]; - std::vector & send_to_zones = interface->send_to_zones; - int nsend_zones = send_to_zones.size(); - - std::vector> & donorfaces_for_send = interface->donorfaces_for_send; - std::vector> & donorijk_for_send = interface->donorijk_for_send; - std::vector> & donordata_for_send = interface->donordata_for_send; - 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 = send_to_zones[ iSend ]; - std::vector & donorfaces = donorfaces_for_send[ iSend ]; - std::vector & donorijks = donorijk_for_send[ iSend ]; - std::vector & donordatas = donordata_for_send[ 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 nface = donorfaces.size(); + int nInterFaces = donorfaces_for_send.size(); int index_dim = 1; - for ( int i = 0; i < nface; ++ i ) + int ngsize = nghost + 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) { - int ijkpos = index_dim * i; - int i_donor_cell = donorijks[ ijkpos + 0 ]; - donordatas[ i ] = field->u[ i_donor_cell ]; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->u[ id_cell ]; + } } } } @@ -464,8 +288,18 @@ void Solver::UpdateInterfaceField() for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) { int local_faceid = sub_local_faceids[ i ]; - double donor_value = donordata[ i ]; - donor_interface->data_recv[ local_faceid ] = donor_value; + + int index_dim = 1; + int ngsize = nghost + 1; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = donor_value; + } } } } @@ -479,16 +313,29 @@ void Solver::DownloadInterfaceField() Interface * interface = Global::interfaces[ iZone ]; Field * field = Global::fields[ iZone ]; - int nInterFaces = interface->data_recv.size(); + int nInterFaces = interface->zoneList.size(); int index_dim = 1; for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) { - int ijkpos = index_dim * iFace; - int i_ghost_cell = interface->ijk_ghosts[ ijkpos + 0 ]; - - double donor_value = interface->data_recv[ iFace ]; - field->u[ i_ghost_cell ] = donor_value; + int ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + //for ( int ig = 0; ig <= nghost; ++ ig ) + for ( int ig = 0; ig <= nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->u[ ig_cell ] = donor_value; + } + + } } } } @@ -502,8 +349,41 @@ void Solver::ExchangeInterfaceField() void Solver::PostProcess() { - Post post; - post.Process(); + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::PrintField( std::vector &f ) @@ -522,252 +402,158 @@ void Solver::PrintField( std::vector &f ) std::cout << "\n"; } - -void Post::Process() +void Solver::InitTopo() { - this->ReorderZones(); - this->GatherField(); - this->DumpField(); -} + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; -void Post::ReorderZones() -{ - std::vector xmin_list; - std::vector xmax_list; - for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) { - if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; - double xmin = 0.0; - double xmax = 0.0; + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } - if ( ZoneState::IsValid( iZone ) ) - { - int local_zoneid = ZoneState::g2lzoneids[ iZone ]; - Grid * grid = Global::grids[ local_zoneid ]; - int ni = grid->x.size(); - xmin = grid->x[ 0 ]; - xmax = grid->x[ 0 ]; - int imin = 0; - int imax = 0; - for ( int i = 0; i < ni; ++ i ) - { - if ( xmin > grid->x[ i ] ) - { - xmin = grid->x[ i ]; - imin = i; - } - if ( xmax < grid->x[ i ] ) - { - xmax = grid->x[ i ]; - imax = i; - } - } - } + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; - HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); - HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; - if ( Parallel::IsServer() ) + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) { - xmin_list.push_back( xmin ); - xmax_list.push_back( xmax ); + 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, this->nghost ); } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); } - if ( Parallel::IsServer() ) + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) { - std::vector> pairs; - int nSize = xmin_list.size(); - for ( int i = 0; i < nSize; ++ i ) + int nSize = -1; + if ( iProc == Parallel::pid ) { - pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + nSize = Global::facePairList.size(); } - - std::sort( pairs.begin(), pairs.end() ); - - for ( int i = 0; i < nSize; ++ i ) + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) { - this->zoneids.push_back( pairs[ i ].second ); + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); } - } - - int kkk = 1; -} - -bool IsLastZone( int iZone ); -bool IsLastZone( int iZone ) -{ - return iZone == ZoneState::nZones - 1; -} -void Post::AddVector( std::vector & a, std::vector & b ) -{ - for ( int i = 0; i < b.size(); ++ i ) - { - a.push_back( b[ i ] ); + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); } -} -void Post::GatherField() -{ - this->zoneids.resize( ZoneState::nZones ); - HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); - std::cout << "Parallel::pid = " << Parallel::pid << " "; - std::cout << "Post::GatherField() this->zoneids = \n"; - for ( int i = 0; i < this->zoneids.size(); ++ i ) + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) { - std::cout << this->zoneids[ i ] << " "; + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); } - std::cout << "\n"; - for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) { - int zoneid = this->zoneids[ iZone ]; - - if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; - - int nSize = -1; - std::vector local_x; - std::vector local_u_e; - std::vector local_un; - std::vector local_u; + Zone * zone = Global::zones[ iZone ]; - if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) { - int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; - Grid * grid = Global::grids[ local_zoneid ]; - Field * field = Global::fields[ local_zoneid ]; - int ni = grid->x.size(); - - int ist = 1; - int ied = ni; + 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 ) ); + } + } - int dir = 1; - if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + 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 ); + } - if ( dir == 1 ) - { - if ( IsLastZone( iZone ) ) - { - for ( int i = ist; i <= ied; ++ i ) - { - double xm = grid->x[ i - ist ]; - local_x.push_back( xm ); - local_u_e.push_back( field->u_e[ i ] ); - local_un.push_back( field->un[ i ] ); - local_u.push_back( field->u[ i ] ); - } - } - else - { - for ( int i = ist; i <= ied - 1; ++ i ) - { - double xm = grid->x[ i - ist ]; - local_x.push_back( xm ); - local_u_e.push_back( field->u_e[ i ] ); - local_un.push_back( field->un[ i ] ); - local_u.push_back( field->u[ i ] ); - } - } - } - else - { - if ( IsLastZone( iZone ) ) - { - for ( int i = ied; i >= ist; -- i ) - { - double xm = grid->x[ i - ist ]; - local_x.push_back( xm ); - local_u_e.push_back( field->u_e[ i ] ); - local_un.push_back( field->un[ i ] ); - local_u.push_back( field->u[ i ] ); - } - } - else - { - for ( int i = ied; i >= ist + 1; -- i ) - { - double xm = grid->x[ i - ist ]; - local_x.push_back( xm ); - local_u_e.push_back( field->u_e[ i ] ); - local_un.push_back( field->un[ i ] ); - local_u.push_back( field->u[ i ] ); - } - } - } - nSize = local_x.size(); + 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 ); } - int send_pid = ZoneState::pids[ zoneid ]; + interface->neighbor_donor_zones = donor_zones; - HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + std::unordered_map donor_zonelocal; - if ( Parallel::IsServer() ) + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) { - local_x.resize( nSize ); - local_u_e.resize( nSize ); - local_un.resize( nSize ); - local_u.resize( nSize ); + 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 ); - HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); - HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); - HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); - HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); - if ( Parallel::IsServer() ) + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) { - this->AddVector( this->x, local_x ); - this->AddVector( this->u_e, local_u_e ); - this->AddVector( this->un, local_un ); - this->AddVector( this->u, local_u ); - } - } -} + 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 ]; -void Post::DumpField() -{ - if ( !Parallel::IsServer() ) return; - int ni_total = this->x.size(); - std::cout << " DumpField x.size() = " << x.size() << "\n"; - //compute L2 norm of the error - std::vector u_error( ni_total ); - for ( int i = 0; i < ni_total; ++ i ) - { - u_error[ i ] = un[ i ] - u_e[ i ]; + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } } - this->DumpErrorDetails( u_error ); - - std::string csvname = "field_final.csv"; - this->DumpCsvFile( csvname, x, u_e, un, u_error ); -} - -void Post::DumpErrorDetails( std::vector &u_error ) -{ - int ni = u_error.size(); - double rms_error = compute_l2norm( ni, u_error ); - double max_error = compute_max_error( ni, u_error ); - std::cout << "Parallel::pid = " << Parallel::pid << " "; - std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; - //create output file for L2-norm - std::fstream file; - file.open("output.txt", std::fstream::out); - std::format_to(std::ostream_iterator(file), "Error details: \n"); - std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); - std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); - file.close(); -} - -void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) -{ - std::fstream file; - file.open(filename.c_str(), std::fstream::out); - std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); - for ( int i = 0; i < x.size(); ++ i ) - { - std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); - } - file.close(); -} + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.cpp new file mode 100644 index 00000000..5a29119d --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.cpp @@ -0,0 +1,547 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + //std::cout << "InterfaceBoundary nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + //} +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.h new file mode 100644 index 00000000..e249c0a8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/Weno.h @@ -0,0 +1,54 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/ZoneState.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/ZoneState.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d2blocks.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d2blocks.cgns new file mode 100644 index 00000000..51518b5c Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/burgers1d2blocks.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/2blocks/01b/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CMakeLists.txt new file mode 100644 index 00000000..e715c1e5 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CMakeLists.txt @@ -0,0 +1,97 @@ +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 ( 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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CgnsUtil.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.cpp new file mode 100644 index 00000000..b01b45d5 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.cpp @@ -0,0 +1,312 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +//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 ]; +// } +//} + +void FieldSub::Init( Grid * grid ) +{ + this->InitHeatEquation( grid ); +} + +void FieldSub::InitHeatEquation( Grid * grid ) +{ + this->ni = grid->x.size(); + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->total_time = 1.0; + this->nt = std::round( total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\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 nghost = 2; + int ni_total = ni + nghost; + + int N = this->ni; + + int ighost = 1; + int iist = 0 - ighost; + int iied = N - 1 + ighost; + u_e.Allocate( iist, iied ); + u.Allocate( iist, iied ); + un.Allocate( iist, iied ); + res.Allocate( 0, N, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + double xm = x[ i ]; + u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution + u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 + } + int kkk = 1; +} + +void FieldSub::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 ] = - 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 ]; + } + + a[ 0 ] = 0; + c[ ni - 1 ] = 0; + + d[ 0 ] -= ( - rr ) * u[ 0 ]; + d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::ICP( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + 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 - rr; + b[ i ] = 10.0 / 12.0 + 2.0 * rr; + c[ i ] = 1.0 / 12.0 - rr; + } + + a[ 0 ] = 0; + b[ 0 ] = 1; + c[ 0 ] = 0; + + a[ ni - 1 ] = 0; + b[ ni - 1 ] = 1; + c[ ni - 1 ] = 0; + + for ( int i = 0; i < ni; ++ i ) + { + double aa = 1.0 / 12.0 + rr; + double bb = 10.0 / 12.0 - 2.0 * rr; + double cc = 1.0 / 12.0 + rr; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + d[ 0 ] = 0; + d[ ni - 1 ] = 0; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } +} + +void FieldSub::RungeKutta( 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 FieldSub::UpdateOldField() +{ + this->un = this->u; +} + +void FieldSub::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void FieldSub::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void FieldSub::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void FieldSub::Rhs( Vec1d & u, Vec1d & r ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} + +void FieldSub::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 FieldSub::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + int kkk = 1; + } +} + +void FieldSub::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; + if ( i == 1 ) + { + idir = -1; + } + int ii = i - 1; //index from 0 + int ighost = ii + idir; + int iinner = ii - idir; + //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; + this->u[ ighost ] = - this->u[ iinner ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.h new file mode 100644 index 00000000..d0479a13 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Field.h @@ -0,0 +1,57 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CN( Zone * zone ) {} + virtual void ICP( Zone * zone ) {} + virtual void RungeKutta( Zone * zone, int istage ) {} + virtual void PhysicalBoundary( Zone * zone ) {} + virtual void PostProcess( Grid * grid ) {} +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; +}; + +class FieldSub : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + double alpha, beta; +public: + void Init( Grid * grid ); + void InitHeatEquation( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & r ); + + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + + void PhysicalBoundary( Zone * zone ); + void UpdateOldField(); +}; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.cpp new file mode 100644 index 00000000..2a6f4570 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.cpp @@ -0,0 +1,310 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme = Scheme::FTCS; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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; + +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 nghost ) +{ + 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 ) { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + for ( int ig = 1; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * Global::nghost; + + for ( int ig = 0; ig < Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.h new file mode 100644 index 00000000..647851d0 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Global.h @@ -0,0 +1,119 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include + +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, int nghost ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class Scheme +{ + FTCS = 0, + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, + RungeKutta +}; + +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 int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/LogFile.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/LogFile.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/README.txt b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.cpp new file mode 100644 index 00000000..6bcf101a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.cpp @@ -0,0 +1,541 @@ +#include "Solver.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 + +Solver::Solver() +{ + Parallel::Init(); + //this->nghost = 1; + //this->scheme = Scheme::FTCS; + //this->scheme = Scheme::RungeKutta; + //this->scheme = Scheme::CN; + //this->scheme = Scheme::ICP; + this->scheme = Scheme::CRWENO; + this->nghost = 3; + Global::nghost = this->nghost; + Global::scheme = this->scheme; +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Run() +{ + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + //this->PostProcess(); +} + +void Solver::ReadGrid() +{ + std::string fileName = "../burgers1d1blocksv1.cgns"; + ReadCgnsGridBaseZone( fileName ); + ReadCgnsGrid( fileName ); +} + +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 ) + { + Field * field = nullptr; + if ( scheme == Scheme::WENO || + scheme == Scheme::CRWENO ) { + field = new WenoField(); + } + else { + field = new FieldSub(); + } + Global::fields.push_back( field ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::DumpInitialFields() +{ + this->PostProcess(); +} + +void Solver::SolveFields() +{ + this->DumpInitialFields(); + for ( int it = 0; it < Global::nt; ++ it ) + { + Global::iter = it; + switch ( scheme ) { + case Scheme::FTCS: + this->FTCS(); + break; + case Scheme::CN: + this->CN(); + break; + case Scheme::ICP: + this->ICP(); + break; + case Scheme::WENO: + this->RungeKutta(); + break; + case Scheme::CRWENO: + this->RungeKutta(); + break; + case Scheme::RungeKutta: + this->RungeKutta(); + break; + default: + this->FTCS(); + } + if ( ( Global::iter + 1 ) % 250 == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->PostProcess(); + } + + } +} + +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::CN() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CN( 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() +{ + for ( int istage = 0; istage < 3; ++ istage ) + { + this->RungeKutta( istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( 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, 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(); +} + +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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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 ijkpos = index_dim * local_faceid * nghost; + int data_pos = local_faceid * nghost; + int donor_data_pos = i * nghost; + + for ( int ig = 0; ig < nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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 ijkpos = index_dim * iFace * nghost; + int data_pos = iFace * nghost; + for ( int ig = 0; ig < nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + + double donor_value = interface->data_recv[ data_pos + ig ]; + field->u[ ig_cell ] = donor_value; + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::PostProcess() +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + 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->PostProcess( 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::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, this->nghost ); + } + int nInterfaces = interface->zoneList.size(); + int nData = nInterfaces * Global::nghost; + 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.h new file mode 100644 index 00000000..3100de30 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Solver.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" +#include "Field.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +//enum class Scheme +//{ +// FTCS = 0, +// CN, //CrankCNicolson +// ICP, //Implicit Compact Pade (ICP) Scheme +// WENO, //Weighted Essentially Non-oscillatory +// CRWENO, +// RungeKutta +//}; + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + Scheme scheme; + int nghost; +public: + void Run(); + void ReadGrid(); + void InitFields(); + void InitTopo(); + void SolveFields(); + void DumpInitialFields(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); +public: + void FTCS(); + void CN(); + void ICP(); + void RungeKutta(); + void RungeKutta( int istage ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Vec1d.h new file mode 100644 index 00000000..ce6ed7c1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Vec1d.h @@ -0,0 +1,38 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.cpp new file mode 100644 index 00000000..358305b9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.cpp @@ -0,0 +1,518 @@ +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void WenoField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->total_time = 0.25; + this->nt = std::round( total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n",ni ); + std::print( "ns={}\n", ns ); + std::print( "dt={}\n", dt ); + std::print( "total_time={}\n", total_time ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->total_time = " << this->total_time << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ighost = 3; + int ist = 0 - ighost; + int ied = this->ni - 1 + ighost; + + std::vector ulist( ns + 1 ); + + for ( int i = 0; i < ulist.size(); ++ i ) + { + ulist[ i ].Allocate( ist, ied, 0 ); + } + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void WenoField::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 WenoField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::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; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + int ig2 = ig1 + idir; + int ig3 = ig2 + idir; + + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } +} + +void WenoField::RungeKutta( 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 WenoField::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void WenoField::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } +} + +void WenoField::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 i = 0; i < ni; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } +} + +void WenoField::Rhs( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + if ( Global::scheme == Scheme::CRWENO ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + + for ( int i = 0; i < ni; ++ 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 WenoField::UpdateOldField() +{ + this->un = this->u; +} + +void WenoField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void WenoField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} + +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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.h new file mode 100644 index 00000000..b09b944c --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/Weno.h @@ -0,0 +1,52 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class WenoField : public Field +{ +public: + int ni; + int nt; + double dx, dt, total_time; + int ns; +public: + void Init( Grid * grid ); +public: + void PhysicalBoundary( Zone * zone ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +public: + void RungeKutta( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); + void Rhs( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + +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 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 ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/WenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/WenoPlot.py new file mode 100644 index 00000000..84340f68 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/WenoPlot.py @@ -0,0 +1,49 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + headers = next(readCSV) + num_columns = len(headers) + print(f'num_columns = {num_columns}') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount + 1 +print("ni=",ni) + +ns = num_columns - 2 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + #print(f"row={row}\n") + x[i] = float(row[0]) + for j in range(1,num_columns): + u[i][j-1] = float(row[j]) + i += 1 + + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") + +#x = np.linspace(0,1, num=ni) + +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(x, 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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/ZoneState.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/ZoneState.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/plot.py b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/crweno5/cpp/oneblock/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..fc1442f1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.cpp @@ -0,0 +1,136 @@ +#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( Grid * grid ) +{ + this->ni = grid->x.size(); + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + this->ns = 10; + + std::print( "ni={}\n", ni ); + std::print( "ns={}\n", ns ); + 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"; + + int freq = std::round( nt / ns ); + std::print( "freq = {}\n", freq ); + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + + int kkk = 1; +} + +void BurgersField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, ni, 0 ); + + Vec1d uR; + uR.Allocate( 0, ni, 0 ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( ni, u, uL ); + crwenoR( ni, u, uR ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) ) + { + wenoL( ni, u, uL ); + wenoR( ni, u, uR ); + } + else + { + //wenoL( ni, u, uL ); + //wenoR( ni, u, uR ); + } + + if ( Global::iconservation == 0 ) + { + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + for ( int i = 0; i < ni; ++ 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::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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 ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void BurgersField::DumpField( Vec1d & x, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.h new file mode 100644 index 00000000..da4d14b8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/BurgersField.h @@ -0,0 +1,25 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; + int ns; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CMakeLists.txt b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..b134f5f8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CMakeLists.txt @@ -0,0 +1,103 @@ +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 + CgnsUtil.h CgnsUtil.cpp + Field.h Field.cpp + HeatField.h HeatField.cpp + BurgersField.h BurgersField.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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CgnsUtil.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..3bcbd100 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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->x.Allocate( 0, nNodes - 1 ); + 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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CgnsUtil.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.cpp new file mode 100644 index 00000000..a34af4fa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.cpp @@ -0,0 +1,212 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + if ( i == 1 ) + { + idir = -1; + } + int ib = i - 1; //index from 0 + int in = ib - idir; + + int ig1 = ib + idir; + this->u[ ib ] = 0.0; + this->u[ ig1 ] = 2.0 * u[ ib ] - 1.0 * u[ in ]; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * u[ ib ] - 2.0 * u[ in ]; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * u[ ib ] - 3.0 * u[ in ]; + } + } + } +} + +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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.h new file mode 100644 index 00000000..df0b1cab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Field.h @@ -0,0 +1,45 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni; + double dt; +}; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.cpp new file mode 100644 index 00000000..897cf0c6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.cpp @@ -0,0 +1,396 @@ +#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::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +double Global::total_time = 0.0; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + 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 == "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_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 nghost ) +{ + 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 + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i - ig ); + ijk_donors.push_back( i + ig ); + } + } + else { + //ig = 0: interface value + //ig=1,2,... ghost cell value + for ( int ig = 0; ig <= nghost; ++ ig ) + { + ijk_ghosts.push_back( i + ig ); + ijk_donors.push_back( i - ig ); + } + } + + 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; + 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 * ( Global::nghost + 1 ); + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int i_donor_cell = interface->ijk_donors[ ijkpos + ig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.h new file mode 100644 index 00000000..87aaa934 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Global.h @@ -0,0 +1,162 @@ +#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, int nghost ); + 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, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + Burgers +}; + +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; +public: + void read( const json & j ); + void set_inviscid_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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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 ); +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.cpp new file mode 100644 index 00000000..993ea5f9 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.cpp @@ -0,0 +1,274 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.h new file mode 100644 index 00000000..b92a53ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Grid.h @@ -0,0 +1,110 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + Vec1d x; +}; + +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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/HeatField.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/HeatField.cpp new file mode 100644 index 00000000..3166f314 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->x.size(); + 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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/HeatField.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/LogFile.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/LogFile.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/MyCRWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/MyWenoPlot.py b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.cpp new file mode 100644 index 00000000..d3ee1dfa --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.cpp @@ -0,0 +1,106 @@ +#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 HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +//{ +// if ( send_pid == recv_pid ) return; +// int nsize = -1; +// if ( Parallel::pid == send_pid ) +// { +// nsize = str.size(); +// } +// HXSendRecvData( &nsize, 1, send_pid, recv_pid, tag ); +// if ( Parallel::pid == recv_pid ) +// { +// str.resize( nsize ); +// } +// HXSendRecvData( str.data(), nsize, send_pid, recv_pid, tag ); +//} +// diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.h new file mode 100644 index 00000000..c104bca8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Parallel.h @@ -0,0 +1,81 @@ +#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 +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.cpp new file mode 100644 index 00000000..ef482e1f --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.cpp @@ -0,0 +1,284 @@ +#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; +} + +void Post::Process() +{ + this->ReorderZones(); + this->GatherField(); + this->DumpField(); +} + +void Post::ReorderZones() +{ + std::vector xmin_list; + std::vector xmax_list; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( !ZoneState::IsValid( iZone ) && !Parallel::IsServer() ) continue; + + double xmin = 0.0; + double xmax = 0.0; + + if ( ZoneState::IsValid( iZone ) ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Grid * grid = Global::grids[ local_zoneid ]; + int ni = grid->x.size(); + xmin = grid->x[ 0 ]; + xmax = grid->x[ 0 ]; + int imin = 0; + int imax = 0; + for ( int i = 0; i < ni; ++ i ) + { + if ( xmin > grid->x[ i ] ) + { + xmin = grid->x[ i ]; + imin = i; + } + if ( xmax < grid->x[ i ] ) + { + xmax = grid->x[ i ]; + imax = i; + } + } + } + + HXSendRecvData( &xmin, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + HXSendRecvData( &xmax, 1, ZoneState::pids[ iZone ], Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + xmin_list.push_back( xmin ); + xmax_list.push_back( xmax ); + } + } + + if ( Parallel::IsServer() ) + { + std::vector> pairs; + int nSize = xmin_list.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pairs.push_back( std::make_pair( xmin_list[ i ], i ) ); + } + + std::sort( pairs.begin(), pairs.end() ); + + for ( int i = 0; i < nSize; ++ i ) + { + this->zoneids.push_back( pairs[ i ].second ); + } + } + + int kkk = 1; +} + +bool IsLastZone( int iZone ); +bool IsLastZone( int iZone ) +{ + return iZone == ZoneState::nZones - 1; +} + +void Post::AddVector( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} + +void Post::GatherField() +{ + this->zoneids.resize( ZoneState::nZones ); + HXBcastData( this->zoneids.data(), this->zoneids.size(), Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Post::GatherField() this->zoneids = \n"; + for ( int i = 0; i < this->zoneids.size(); ++ i ) + { + std::cout << this->zoneids[ i ] << " "; + } + std::cout << "\n"; + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zoneid = this->zoneids[ iZone ]; + + if ( !ZoneState::IsValid( zoneid ) && !Parallel::IsServer() ) continue; + + int nSize = -1; + std::vector local_x; + std::vector local_u_e; + std::vector local_un; + std::vector local_u; + + if ( Parallel::pid == ZoneState::pids[ zoneid ] ) + { + int local_zoneid = ZoneState::g2lzoneids[ zoneid ]; + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + int ni = grid->x.size(); + + int dir = 1; + if ( grid->x[ 0 ] > grid->x[ 1 ] ) dir = -1; + + if ( dir == 1 ) + { + if ( IsLastZone( iZone ) ) + { + for ( int i = 0; i < ni; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = 0; i < ni - 1; ++ i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + else + { + if ( IsLastZone( iZone ) ) + { + for ( int i = ni - 1; i >= 0; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + else + { + for ( int i = ni - 1; i >= 1; -- i ) + { + double xm = grid->x[ i ]; + local_x.push_back( xm ); + local_u_e.push_back( field->u_e[ i ] ); + local_un.push_back( field->un[ i ] ); + local_u.push_back( field->u[ i ] ); + } + } + } + nSize = local_x.size(); + } + + int send_pid = ZoneState::pids[ zoneid ]; + + HXSendRecvData( &nSize, 1, send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + local_x.resize( nSize ); + local_u_e.resize( nSize ); + local_un.resize( nSize ); + local_u.resize( nSize ); + } + + HXSendRecvData( local_x.data(), local_x.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u_e.data(), local_u_e.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_un.data(), local_un.size(), send_pid, Parallel::serverid ); + HXSendRecvData( local_u.data(), local_u.size(), send_pid, Parallel::serverid ); + + if ( Parallel::IsServer() ) + { + this->AddVector( this->x, local_x ); + this->AddVector( this->u_e, local_u_e ); + this->AddVector( this->un, local_un ); + this->AddVector( this->u, local_u ); + } + } +} + +void Post::DumpField() +{ + if ( !Parallel::IsServer() ) return; + int ni = this->x.size(); + std::cout << " DumpField x.size() = " << x.size() << "\n"; + //compute L2 norm of the error + std::vector u_error( ni ); + for ( int i = 0; i < ni; ++ i ) + { + u_error[ i ] = un[ i ] - u_e[ i ]; + } + + this->DumpErrorDetails( u_error ); + + std::string csvname = "field_final.csv"; + this->DumpCsvFile( csvname, x, u_e, un, u_error ); +} + +void Post::DumpErrorDetails( std::vector &u_error ) +{ + int ni = u_error.size(); + double rms_error = compute_l2norm( ni, u_error ); + double max_error = compute_max_error( ni, u_error ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "max_error = " << std::setprecision(15) << max_error << "\n"; + //create output file for L2-norm + std::fstream file; + file.open("output.txt", std::fstream::out); + std::format_to(std::ostream_iterator(file), "Error details: \n"); + std::format_to(std::ostream_iterator(file), "L-2 Norm = {0}\n", rms_error); + std::format_to(std::ostream_iterator(file), "Maximum Norm = {0}\n", max_error); + file.close(); +} + +void Post::DumpCsvFile( const std::string &filename, std::vector &x, std::vector &ue, std::vector &un, std::vector &uerror ) +{ + std::fstream file; + file.open(filename.c_str(), std::fstream::out); + std::format_to(std::ostream_iterator(file), "x ue un uerror\n"); + for ( int i = 0; i < x.size(); ++ i ) + { + std::format_to(std::ostream_iterator(file), "{:.20f} {:.20f} {:.20f} {:.20f}\n", x[i], ue[i], un[i], uerror[i] ); + } + file.close(); +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.h new file mode 100644 index 00000000..6ad0d3b6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Post.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Post +{ +public: + std::vector zoneids; + std::vector x; + std::vector u_e; + std::vector un; + std::vector u; +public: + void Process(); + void ReorderZones(); + void GatherField(); +public: + void AddVector( std::vector & a, std::vector & b ); + void DumpField(); + void DumpErrorDetails( std::vector & u_error ); + void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); +}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/README.txt b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.cpp new file mode 100644 index 00000000..194658f2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.cpp @@ -0,0 +1,649 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "BurgersField.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(); + //std::ifstream f("../cfd.json"); + std::ifstream f("../burgers.json"); + //std::ifstream f("../heat.json"); + //std::ifstream f("../heaticp.json"); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else + { + Global::governing_equation = GoverningEquation::Burgers; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::total_time = data[ "total_time" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.inviscid == to_int( BasicScheme::WENO ) || + Global::scheme.inviscid == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; +} + +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 + { + field = new BurgersField(); + } + 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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int id_cell = donorijk_for_send[ ijkpos + ig ] - 1; + donordata_for_send[ data_pos + ig ] = field->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; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize; + int donor_data_pos = i * ngsize; + + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + double donor_value = donordata[ donor_data_pos + ig ]; + donor_interface->data_recv[ data_pos + ig ] = 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; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize; + for ( int ig = 0; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos + ig ] - 1; + double donor_value = interface->data_recv[ data_pos + ig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); + //std::string total_string = {}; + //std::fstream file; + //if ( Parallel::pid == Parallel::serverid ) + //{ + // std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + // 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->PostProcess( 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::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, Global::nghost ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1; + int nData = nInterfaces * ngsize; + 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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Vec1d.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Vec1d.h new file mode 100644 index 00000000..aece04b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Vec1d.h @@ -0,0 +1,47 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + } + 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; + + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i) + { + data[ i ] = value; + } + return * this; + } +}; diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/ZoneState.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/ZoneState.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers.json b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers.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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers1d1blocksv1.cgns b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers1d1blocksv1.cgns new file mode 100644 index 00000000..36f2b180 Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers1d1blocksv1.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers_ftcs.json b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers_plot.py b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers_plot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/burgers_plot.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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/cfd.json b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat.json b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat1d1blocks.cgns b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat1d1blocks.cgns new file mode 100644 index 00000000..b7d4954a Binary files /dev/null and b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat1d1blocks.cgns differ diff --git a/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat_plot.py b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heaticp.json b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/hxmath.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/hxmath.h b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/main.cpp b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/plot.py b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/plotting2.jl b/example/inviscid-burgers-equation/non-conservative-form/ftcs/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/inviscid-burgers-equation/non-conservative-form/ftcs/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/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.cpp b/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.cpp deleted file mode 100644 index a248515a..00000000 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Field.cpp +++ /dev/null @@ -1,422 +0,0 @@ -#include "Field.h" -#include "CgnsGrid.h" -#include -#include - -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 ]; - } -} - -void Field::Init( Grid * grid ) -{ - this->ni = grid->x.size(); - std::cout << "ni = " << ni << "\n"; - - std::vector & x = grid->x; - this->dx = std::abs( x[ 1 ] - x[ 0 ] ); - this->dt = dx / 10.0; - this->t = 1.0; - this->nt = std::round( t / dt ); - - double total_time = nt * dt; - - std::cout << "this->dt = " << this->dt << "\n"; - std::cout << "this->t = " << this->t << "\n"; - std::cout << "this->nt = " << this->nt << "\n"; - std::cout << "this->ni = " << this->ni << "\n"; - std::cout << "total_time = " << total_time << "\n"; - - Global::nt = nt; - - this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); - this->beta = this->alpha * dt / ( dx * dx ); - - int nghost = 2; - int ni_total = ni + nghost; - - u_e.resize( ni_total ); - u.resize( ni_total ); - un.resize( ni_total ); - u1.resize( ni_total ); - r.resize( ni_total ); - - // 0 1 2 ... ni-1 ni ni+1 - int ist = 1; - int ied = ni; - - for ( int i = ist; i <= ied; ++ i ) - { - double xm = x[ i - ist ]; - u_e[ i ] = - std::exp( -total_time ) * std::sin( std::numbers::pi * xm ); //theory solution - u[ i ] = - std::sin( std::numbers::pi * xm ); //initial condition @ t=0 - } - int kkk = 1; -} - -void Field::FTCS( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - this->Rhs( this->un, this->r ); - - for ( int i = ist; i <= ied; ++ i ) - { - u[ i ] = un[ i ] + dt * r[ i ]; - } -} - -void Field::CN( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - double rr = 0.5 * this->alpha * dt / ( dx * dx ); - 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 ] = - rr; - b[ i ] = 1.0 + 2.0 * rr; - c[ i ] = - rr; - } - - for ( int i = ist; i <= ied; ++ i ) - { - int ii = i - 1; - d[ ii ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; - } - - a[ 0 ] = 0; - c[ ni - 1 ] = 0; - - d[ 0 ] -= ( - rr ) * u[ 0 ]; - d[ ni - 1 ] -= ( - rr ) * u[ ni + 1 ]; - - std::vector values( d.size() ); - - thomas_algorithm( a, b, c, d, values ); - - for ( int i = ist; i <= ied; ++ i ) - { - int ii = i - 1; - u[ i ] = values[ ii ]; - } -} - -void Field::ICP( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - double rr = 0.5 * this->alpha * dt / ( dx * dx ); - 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 - rr; - b[ i ] = 10.0 / 12.0 + 2.0 * rr; - c[ i ] = 1.0 / 12.0 - rr; - } - - a[ 0 ] = 0; - b[ 0 ] = 1; - c[ 0 ] = 0; - - a[ ni - 1 ] = 0; - b[ ni - 1 ] = 1; - c[ ni - 1 ] = 0; - - for ( int i = ist; i <= ied; ++ i ) - { - double aa = 1.0 / 12.0 + rr; - double bb = 10.0 / 12.0 - 2.0 * rr; - double cc = 1.0 / 12.0 + rr; - int ii = i - 1; - d[ ii ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; - } - - d[ 0 ] = 0; - d[ ni - 1 ] = 0; - - std::vector values( d.size() ); - - thomas_algorithm( a, b, c, d, values ); - - for ( int i = ist; i <= ied; ++ i ) - { - int ii = i - 1; - u[ i ] = values[ ii ]; - } -} - -void Field::WENO5( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - double rr = 0.5 * this->alpha * dt / ( dx * dx ); - 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 - rr; - b[ i ] = 10.0 / 12.0 + 2.0 * rr; - c[ i ] = 1.0 / 12.0 - rr; - } - - a[ 0 ] = 0; - b[ 0 ] = 1; - c[ 0 ] = 0; - - a[ ni - 1 ] = 0; - b[ ni - 1 ] = 1; - c[ ni - 1 ] = 0; - - for ( int i = ist; i <= ied; ++ i ) - { - double aa = 1.0 / 12.0 + rr; - double bb = 10.0 / 12.0 - 2.0 * rr; - double cc = 1.0 / 12.0 + rr; - int ii = i - 1; - d[ ii ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; - } - - d[ 0 ] = 0; - d[ ni - 1 ] = 0; - - std::vector values( d.size() ); - - thomas_algorithm( a, b, c, d, values ); - - for ( int i = ist; i <= ied; ++ i ) - { - int ii = i - 1; - u[ i ] = values[ ii ]; - } -} - -void Field::RungeKutta( 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 ) -{ - int ist = 1; - int ied = ni; - - this->Rhs( this->un, this->r ); - - for ( int i = ist; i <= ied; ++ i ) - { - u[ i ] = un[ i ] + dt * r[ i ]; - } -} - -void Field::UpdateOldField() -{ - for ( int i = 0; i < this->u.size(); ++ i ) - { - this->un[ i ] = this->u[ i ]; - } -} - -void Field::UpdateRungeKuttaOldField( int istage ) -{ - if ( istage == 0 ) - { - for ( int i = 0; i < this->u.size(); ++ i ) - { - this->u1[ i ] = this->u[ i ]; - } - return; - } - - if ( istage == 1 ) - { - return; - } - - if ( istage == 2 ) - { - for ( int i = 0; i < this->u.size(); ++ i ) - { - this->un[ i ] = this->u[ i ]; - } - return; - } -} - -void Field::RungeKutta3Stage1( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - this->Rhs( this->u1, this->r ); - - for ( int i = ist; i <= ied; ++ i ) - { - u[ i ] = 0.75 * un[ i ] + 0.25 * u1[ i ] + 0.25 * dt * r[ i ]; - } -} - -void Field::RungeKutta3Stage2( Zone * zone ) -{ - int ist = 1; - int ied = ni; - - this->Rhs( this->u, this->r ); - - double c1 = 1.0 / 3.0; - double c2 = 2.0 / 3.0; - double c3 = 2.0 / 3.0; - - for ( int i = ist; i <= ied; ++ i ) - { - u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * r[ i ]; - } -} - - -void Field::Rhs( std::vector & u, std::vector & r ) -{ - int ist = 1; - int ied = ni; - - double coef = this->alpha / ( dx * dx ); - - for ( int i = ist; i <= ied; ++ i ) - { - r[ i ] = coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); - } -} - -void Field::PhysicalBoundary( Zone * zone ) -{ - int nbccos = zone->bccos.size(); - for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) - { - ZoneBc * zonebc = zone->bccos[ ibcco ]; - //std::cout << "zonebc->bcType = " << zonebc->bcType << "\n"; - Region region; - region.SetRegion( zonebc->pnts ); - //region.Print(); - Boundary( region, zonebc->bcType ); - } -} - -void Field::Boundary( Region ®ion, int bcType ) -{ - if ( bcType == BCInflow ) - { - this->InflowBc( region ); - } - else if ( bcType == BCExtrapolate || bcType == BCOutflow ) - { - this->OutflowBc( region ); - } -} - -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 ]; - for ( int i = st; i <= ed; ++ i ) - { - int idir = 1; - if ( i == 1 ) - { - idir = -1; - } - int ighost = i + idir; - int iinner = i - idir; - //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; - this->u[ ighost ] = - this->u[ iinner ]; - int kkk = 1; - } -} - -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 ]; - for ( int i = st; i <= ed; ++ i ) - { - int idir = 1; - if ( i == 1 ) - { - idir = -1; - } - int ighost = i + idir; - int iinner = i - idir; - //this->u[ ighost ] = 2 * this->u[ i ] - this->u[ iinner ]; - this->u[ ighost ] = - this->u[ iinner ]; - } -} - - -void Field::PostProcess( Grid * grid ) -{ - std::vector & x = grid->x; - //compute L2 norm of the error - std::vector u_error( ni ); - for ( int i = 0; i < ni; ++ i ) - { - u_error[ i ] = un[ i ] - u_e[ i ]; - } -} diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.cpp b/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.cpp deleted file mode 100644 index 0bce1a60..00000000 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Parallel.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#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 -} - diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.h b/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.h deleted file mode 100644 index ebf64f09..00000000 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Solver.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include -#include "global.h" -#include "CgnsGrid.h" -#include "Field.h" - -double compute_l2norm( int ni, std::vector & r ); -double compute_max_error( int ni, std::vector & u_error ); - -enum class Scheme -{ - FTCS = 0, - CN, //CrankCNicolson - ICP, //Implicit Compact Pade (ICP) Scheme - WENO5, //Weighted Essentially Non-Oscillatory (WENO) Schemes - RungeKutta -}; - -class Solver -{ -public: - Solver(); - ~Solver(); -public: - Scheme scheme; -public: - void Run(); - void ReadGrid(); - void InitFields(); - void InitTopo(); - void SolveFields(); -public: - void Boundary(); - void UpdateOldField(); - void UpdateRungeKuttaOldField( int istage ); - void UploadInterfaceField(); - void UpdateInterfaceField(); - void DownloadInterfaceField(); - void ExchangeInterfaceField(); - void PrintField( std::vector & f ); -public: - void PostProcess(); -public: - void FTCS(); - void CN(); - void ICP(); - void WENO5(); - void RungeKutta(); - void RungeKutta( int istage ); -}; - -class Post -{ -public: - std::vector zoneids; - std::vector x; - std::vector u_e; - std::vector un; - std::vector u; -public: - void Process(); - void ReorderZones(); - void GatherField(); -public: - void AddVector( std::vector & a, std::vector & b ); - void DumpField(); - void DumpErrorDetails( std::vector & u_error ); - void DumpCsvFile( const std::string & filename, std::vector & x, std::vector & ue, std::vector & un, std::vector & uerror ); -}; \ No newline at end of file diff --git a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.h b/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.h deleted file mode 100644 index 18ee0faf..00000000 --- a/example/inviscid-burgers-equation/non-conservative-form/weno5/cpp/020000000/Weno.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - -template -auto sum(Args... args) { - return (... + args); -} - -template -auto SQR(Args... args) { - return (... + (args * args)); // ʹ۵ʽƽ -} - -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, std::vector & u, std::vector & f ); -void wenoR( int N, std::vector & u, std::vector & f ); -void WenoRhs( int N, double dx, std::vector & u, std::vector & r ); - diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/CMakeLists.txt b/example/partition/struct/1d-shock-tube/1to2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..74ceea7d --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.30) + +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 ) + +find_package(Eigen3 CONFIG REQUIRED) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +#list ( APPEND PRJ_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR} ) +list ( APPEND PRJ_LIBRARIES Eigen3::Eigen ) +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() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Partition.h Partition.cpp + CgnsGrid.h CgnsGrid.cpp + SplitZone.h SplitZone.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/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.cpp b/example/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.cpp new file mode 100644 index 00000000..dfe750bd --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.cpp @@ -0,0 +1,349 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include + +Grid::Grid() +{ + ; +} + +Grid::~Grid() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } +} + +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"; +} + +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 ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ + delete this->patch; +} + + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +ZoneBcPatch::ZoneBcPatch() +{ + ; +} + +ZoneBcPatch::~ZoneBcPatch() +{ +} + +std::vector Global::zones; +BaseZoneList Global::zone_names; +int Global::cell_dim = -1; +int Global::phys_dim = -1; + +Global::Global() +{ + ; +} + +Global::~Global() +{ +} + +void Global::FreeData() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } + zones.resize( 0 ); +} + + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + BaseZone baseZone; + //baseZone.baseId = baseId; + baseZone.zone_name = zonename; + + Global::zone_names.AddBaseZone( baseZone ); + } + } + cg_close( fileId ); +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + Zone * zone = new Zone(); + Global::zones.push_back( zone ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + + BaseZone baseZone; + baseZone.zone_name = zonename; + int gZoneId = Global::zone_names.FindBaseZone( baseZone ); + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + std::vector irmin( index_dim ); + std::vector irmax( index_dim ); + int nNodes = 1; + 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 ]; + zone->nijk.push_back( isize[ m ] ); + } + std::cout << "nNodes = " << nNodes << "\n"; + + ZoneType_t zoneType; + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[zoneType] << "\n"; + int ncoords = -1; + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + std::cout << "coordname = " << coordname << "\n"; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[dataType] << "\n"; + std::vector coord( nNodes * sizeof(double) ); + + Coor * coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord.resize( nNodes * sizeof( double ) ); + + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coor->coord.data() ); + coor->DumpCoor(); + } + + int nbocos = -1; + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + + ZoneBc * zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + std::vector normalIndex( index_dim, -1 ); + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + zonebc->bcType = bocotype; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[bocotype] << "\n"; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "ndataset = " << ndataset << "\n"; + + std::vector normalList( nNodes * iphysdim * sizeof( double ) ); + + std::vector pnts( npnts * index_dim ); + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + zonebc->pnts.push_back( pnts[ i ] ); + } + std::cout << "\n"; + + double * normal_d = reinterpret_cast( const_cast( normalList.data() ) ); + } + + int n1to1 = -1; + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + std::cout << "n1to1 = " << n1to1 << "\n"; + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + ZoneBc1To1 * zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range( npnts * index_dim ); + std::vector donor_range( npnts * index_dim ); + std::vector transform( index_dim ); + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + std::cout << "connectname = " << connectname << "\n"; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "range = \n"; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "donor_range = \n"; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + BaseZone baseZone; + baseZone.zone_name = donorname; + int gDonorZoneId = Global::zone_names.FindBaseZone( baseZone ); + + 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 ] ); + } + + int kkk = 1; + } + } + int kkk = 1; + } + int kkk = 1; + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.h b/example/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.h new file mode 100644 index 00000000..053c467b --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/CgnsGrid.h @@ -0,0 +1,140 @@ +#pragma once +#include +#include +#include + +class Grid; + +class Zone; + +class Grid +{ +public: + Grid(); + ~Grid(); +public: + int nZone; + std::vector x; + std::vector zones; +}; + + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); +}; + +class ZoneBc; +class ZoneBc1To1; + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class ZoneBcPatch; +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; + ZoneBcPatch * patch = nullptr; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + +class ZoneBcPatch +{ +public: + ZoneBcPatch(); + ~ZoneBcPatch(); +public: + int donor_zoneid; + std::vector transform; + std::vector donor_pnts; +}; + +class BaseZone +{ +public: + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + 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; + } +}; + +class Global +{ +public: + Global(); + ~Global(); +public: + static int cell_dim; + static int phys_dim; + static std::vector zones; + static BaseZoneList zone_names; +public: + static void FreeData(); +}; + +void ReadCgnsGrid( const std::string & filename ); +void ReadCgnsGridBaseZone( const std::string & filename ); \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.cpp b/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.cpp new file mode 100644 index 00000000..a6e7faa0 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.cpp @@ -0,0 +1,619 @@ +#include "Partition.h" +#include "CgnsGrid.h" +#include "SplitZone.h" +#include "cgnslib.h" +#include + +bool CmpSplitZone::operator() ( SplitZone * a, SplitZone * b ) const +{ + return a->zoneIndex < b->zoneIndex; +}; + + +double CalSumOfProcSpeed( std::vector & procSpeed ); +double CalSumOfProcSpeed( std::vector & procSpeed ) +{ + int nProc = procSpeed.size(); + double sumOfProcSpeed = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + sumOfProcSpeed += procSpeed[ iProc ]; + } + return sumOfProcSpeed; +} + +Partition::Partition() +{ + this->nProc = 2; + this->inputName = "../sodshocktube1d1blocksv1.cgns"; + this->outName = std::format( "../sodshocktube1d{}blocks.cgns", this->nProc ); +} + +Partition::~Partition() +{ + ; +} + +int Partition::GetMinValueIndex( double * data, int numberOfData ) +{ + double minValue = data[ 0 ]; + int minimumValueIndex = 0; + + for ( int iData = 1; iData < numberOfData; ++ iData ) + { + if ( minValue > data[ iData ] ) + { + minValue = data[ iData ]; + minimumValueIndex = iData; + } + } + return minimumValueIndex; +} + +int Partition::GetMinLoadProc() +{ + return this->GetMinValueIndex( this->timeProc.data(), this->nProc ); +} + +SplitZone * Partition::GetLargestZone() +{ + SplitZone * largestZone = 0; + + double nMaxCell = 0.0; + + for ( std::set< SplitZone * >::iterator iter = unsignedZoneGroup.begin(); iter != unsignedZoneGroup.end(); ++ iter ) + { + double nSize = ( * iter )->GetNCell(); + if ( nMaxCell < nSize ) + { + nMaxCell = nSize; + largestZone = * iter; + } + } + + return largestZone; +} + +void Partition::Solve() +{ + std::cout << "Partition::Split()\n"; + this->ReadGrid(); + this->Split(); + this->DumpPartitionedGridFile(); + this->FreeAllZones(); +} + +void Partition::ReadGrid() +{ + ReadCgnsGridBaseZone( this->inputName ); + ReadCgnsGrid( this->inputName ); + + this->nOriZone = ::Global::zones.size(); + Dim::dim = Global::cell_dim; + + std::cout << "numberOfBlocks = " << nOriZone << "\n"; + + this->refZone.resize( nOriZone ); + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = new SplitZone(); + refZone[ iZone ] = splitZone; + + splitZone->SetZoneIndex( iZone ); + splitZone->SetProcId( 0 ); + splitZone->SetParentAndChild( 0 ); + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + Zone * zone = ::Global::zones[ iZone ]; + + splitZone->dimInfo.dimList = zone->nijk; + + int nbccos = zone->bccos.size(); + std::cout << "nbccos = " << nbccos << "\n"; + + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zoneBc = zone->bccos[ ibcco ]; + + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + splitZone->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->bcType = zoneBc->bcType; + physicalSplitBc->SetRegion( zoneBc->pnts ); + physicalSplitBc->splitZone = splitZone; + } + + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * zoneBc1To1 = zone->bc1to1s[ ibc1to1 ]; + + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + splitZone->interfaceSplitBcList.push_back( interfaceSplitBc ); + interfaceSplitBc->zone = splitZone; + interfaceSplitBc->region.SetRegion( zoneBc1To1->pnts ); + + interfaceSplitBc->transform = zoneBc1To1->transform; + interfaceSplitBc->CalcTransformMatrix(); + + interfaceSplitBc->donor_zone = refZone[ zoneBc1To1->donor_zoneid ]; + interfaceSplitBc->donor_region.SetRegion( zoneBc1To1->donor_pnts ); + } + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + int nbc1to1s = splitZone->interfaceSplitBcList.size(); + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + InterfaceSplitBc * interfaceSplitBc = splitZone->interfaceSplitBcList[ ibc1to1 ]; + InterfaceInfo interfaceInfo; + interfaceSplitBc->donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + } +} + +void Partition::Split() +{ + this->InitSplit(); + this->BinarySplit(); + this->ModifyZoneIndex(); + int kkk = 1; +} + +void Partition::InitSplit() +{ + //nZone is the number of zones in the original grid + //nProc is not the number of blocks in the end, but the number of processes that need to be divided. + //This difference occurs because the structure grid can have many blocks per process. + + //this->nProc = nProc; + //this->nPhyBlocks = referenceBlock.size(); + //this->nZone = this->nPhyBlocks; + + //tj Computation time on processor j + //Nk Number of internal grid-cells for zone j + //aveFloatOp: Number of Real operations per gridcell + //Gj The set of blocks allocated to process j + //Pj Real operations per second for process j + + //The Greedy Load Balancing Algorithm + //1.Compute an "ideal" uniprocessor time, Tuni = sum ( Nk * aveFloatOp )/ sum( Pj ). + //2.Set the group of unassigned blocks, Gu, to contain all blocks. The number of blocks in Nu=M, where M is the total number of blocks in the mesh. + //3.Start all processors with a very small fictitious zone to get a start tj=delt aveFloatOp/Pj, where delt<<1 is the size of the very small fictious zone. + //This is used to find the fastest processor in a heterogeneous system, tj could otherwise be set to 0 in the homogeneous case. + this->aveFloatOp = 1.0; + this->delta = 1.0e-5; + this->procSpeed.resize( nProc ); + this->timeProc.resize( nProc ); + + this->nTZone = this->nOriZone; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + procSpeed[ iProc ] = 1.0; + } + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + timeProc[ iProc ] = delta * aveFloatOp / procSpeed[ iProc ]; + } + + double sumProcSpeed = CalSumOfProcSpeed( procSpeed ); + + double sumProcOp = 0.0; + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + sumProcOp += refZone[ iZone ]->GetNCell() * aveFloatOp; + } + + this->idealUniProcTime = sumProcOp / sumProcSpeed; + + this->eps = 0.05; + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + unsignedZoneGroup.insert( refZone[ iZone ] ); + } + + //Init zoneStorage + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + zoneStorage.insert( refZone[ iZone ] ); + } + + //Assign procSplitZone to each process + procSplitZone.resize( nProc ); + + this->minNumberCell = 1; + for ( int m = 0; m < Dim::dim; ++ m ) + { + this->minNumberCell *= 1; + } + + int kkk = 1; + +} + +void Partition::FreeAllZones() +{ + int iCount = 0; + for ( std::set < SplitZone * >::iterator iter = zoneStorage.begin(); iter != zoneStorage.end(); ++ iter ) + { + //cout << "iCount = " << iCount << "\n"; + ++ iCount; + delete * iter; + } +} + +int Partition::GetNZones( int iProc ) +{ + return this->procSplitZone[ iProc ].size(); +} + +SplitZone * Partition::GetSplitZone( int iProc, int zoneId ) +{ + return this->procSplitZone[ iProc ][ zoneId ]; +} + +void Partition::AddZoneToUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.insert( zone ); +} + +void Partition::RemoveZoneFromUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.erase( zone ); +} + +void Partition::AddZoneToProcess( int iProc, SplitZone * zone ) +{ + this->procSplitZone[ iProc ].push_back( zone ); +} + +void Partition::AddNewZone( SplitZone * zone ) +{ + zone->SetZoneIndex( nTZone ++ ); + + this->AddZoneToUnsignedGroup( zone ); + + this->zoneStorage.insert( zone ); +} + +SplitZone * Partition::Split( SplitZone * zone, double nCell ) +{ + SplitZone * zoneL = new SplitZone(); + zoneL->SetParentAndChild( zone ); + + SplitZone * zoneR = new SplitZone(); + zoneR->SetParentAndChild( zone ); + + //Remove the original block from the UnsignedGroup + this->RemoveZoneFromUnsignedGroup( zone ); + + this->AddNewZone( zoneL ); + this->AddNewZone( zoneR ); + + zone->Split( zoneL, zoneR, nCell ); + + return zoneL; +} + +void Partition::BinarySplit() +{ + while ( ! unsignedZoneGroup.empty() ) + { + std::cout << "number of unsigned zone = " << unsignedZoneGroup.size() << "\n"; + int iProc = this->GetMinLoadProc(); + + //Get the block with the largest number of grids and its size + SplitZone * largestZone = this->GetLargestZone(); + + double nMaxCell = largestZone->GetNCell(); + + double aveFloatOp = this->aveFloatOp; + double tau = timeProc[ iProc ] + nMaxCell * aveFloatOp / procSpeed[ iProc ]; + + //It seems that EPS is still necessary + //The idea here is as follows. For the candidate blocks which can be divided into blocks, + //if the difference between the target blocks and the candidate blocks is too wide, + //the binarySplit method is adopted. The binarySplit blocks do not directly join the process, + //but enter the next round of screening. + + if ( tau > idealUniProcTime * ( 1.0 + eps ) ) + { + double nRest = ( tau - idealUniProcTime ) * procSpeed[ iProc ] / aveFloatOp; + + double nTarget = nMaxCell - nRest; + if ( nRest > this->minNumberCell && nTarget > this->minNumberCell ) + { + //It is necessary to divide blocks only when a certain number of points are satisfied. + double nHalf = nMaxCell / 2.0; + nMaxCell = nTarget; + double ratio = nMaxCell / nRest; + double oRatio = 1.0 / ratio; + + if ( std::max( ratio, oRatio ) < 3.0 ) + { + int kkk = 1; + largestZone = this->Split( largestZone, nMaxCell ); + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + else + { + this->Split( largestZone, nHalf ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } +} + +void Partition::ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ) +{ + SplitZone * rootSplitZone = splitZone->GetRootZone(); + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + coord.resize( nNodes * sizeof(double) ); + + int index_dim = splitZone->dimInfo.dimList.size(); + Coor * coor = zone->coors[ icoord ]; + + double * xlocal = reinterpret_cast( const_cast( coord.data() ) ); + double * xglobal = reinterpret_cast( const_cast( coor->coord.data() ) ); + if ( index_dim == 1 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ i ]; + } + } + else if ( index_dim == 2 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + int jmin = splitZone->dimInfo.rmin[ 1 ] - 1; + int jmax = splitZone->dimInfo.rmax[ 1 ]; + int ni = rootSplitZone->dimInfo.dimList[ 0 ]; + int nj = rootSplitZone->dimInfo.dimList[ 1 ]; + for ( int j = jmin; j < jmax; ++ j ) + { + int jstride = j * ni; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ jstride + i ]; + } + } + } +} + +void Partition::DumpBc( SplitZone * splitZone ) +{ +} + +void Partition::DumpPartitionedGridFile() +{ + std::cout << "\n"; + std::cout << "DumpPartitionedGridFile -------------------------------" << "\n"; + std::cout << "\n"; + int fileId = -1; + std::string filename = this->outName; + int ierr = cg_open( filename.c_str(), CG_MODE_WRITE, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + + std::vector coordnames; + coordnames.push_back( "CoordinateX" ); + coordnames.push_back( "CoordinateY" ); + coordnames.push_back( "CoordinateZ" ); + + std::string basename = "Base"; + int baseId = -1; + int icelldim = Global::cell_dim; + int iphysdim = Global::phys_dim; + cg_base_write( fileId, basename.c_str(), icelldim, iphysdim, &baseId ); + + std::cout << "baseId = " << baseId << "\n"; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + int nZones = this->GetNZones( iProc ); + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + ZoneType_t zoneType = Structured; + + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + + int index_dim = splitZone->dimInfo.dimList.size(); + std::cout << "index_dim = " << index_dim << "\n"; + + splitZone->dimInfo.ComputeISize(); + + int isize_dim = index_dim * 3; + + std::vector isize( index_dim * 3, 0 ); + for ( int m = 0; m < isize_dim; ++ m ) + { + isize[ m ] = splitZone->dimInfo.isize[ m ]; + } + + int zoneId = -1; + + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + + std::string zonename = "Zone" + std::to_string( splitZone->newIndex ); + + cg_zone_write( fileId, baseId, zonename.c_str(), isize.data(), zoneType, &zoneId ); + + std::cout << "zoneId = " << zoneId << "\n"; + std::cout << "zonename = " << zonename << "\n"; + + splitZone->ComputeRminmax(); + + SplitZone * rootSplitZone = splitZone->GetRootZone(); + + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int ncoords = zone->coors.size(); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = -1; + DataType_t dataType = RealDouble; + std::string coordname = coordnames[ icoord ]; + Coor * coor = zone->coors[ icoord ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + std::vector coord; + ComputeCoor( splitZone, icoord, coord ); + + cg_coord_write( fileId, baseId, zoneId, dataType, coordname.c_str(), coord.data(), &coorId ); + + std::cout << "fileId = " << fileId << " baseId = " << baseId << " zoneId = " << zoneId << " coorId = " << coorId << "\n"; + } + + std::vector< PhysicalSplitBc * > &bccoList = splitZone->physicalSplitBcList; + + int nbocos = bccoList.size(); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = -1; + GridLocation_t location = Vertex; + + std::string boconame = "BC" + std::to_string( iboco + 1 ); + + PhysicalSplitBc * physicalSplitBc = bccoList[ iboco ]; + BCType_t bocotype = static_cast( physicalSplitBc->bcType ); + PointSetType_t ptset_type = PointRange; + cgsize_t npnts = 2; + std::vector pnts; + int nSize = physicalSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.end[ i ] ); + } + + cg_boco_write( fileId, baseId, zoneId, boconame.c_str(), bocotype, ptset_type, npnts, pnts.data(), & bccoId ); + } + + //std::vector< InterfaceSplitBc * > & bc1to1List = splitZone->interfaceSplitBcList; + std::vector< InterfaceSplitBc * > bc1to1List; + splitZone->GetLeafInterfaceBc( bc1to1List ); + + int n1to1 = bc1to1List.size(); + std::cout << "n1to1 = " << n1to1 << "\n"; + + std::vector itranfrm( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + itranfrm[ m ] = m + 1; + } + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int index_conn = -1; + + InterfaceSplitBc * interfaceSplitBc = bc1to1List[ i1to1 ]; + + std::vector pnts; + std::vector pntsdonor; + int nSize = interfaceSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.end[ i ] ); + } + + int nPatchSize = interfaceSplitBc->donor_region.start.size(); + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.start[ i ] ); + } + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.end[ i ] ); + } + int id = interfaceSplitBc->donor_zone->newIndex; + int oldZoneIndex = interfaceSplitBc->donor_zone->zoneIndex; + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + std::cout << "donor zone id = " << id << "\n"; + std::cout << "donor zone oldZoneIndex = " << oldZoneIndex << "\n"; + std::string donorname = "Zone" + std::to_string( id ); + std::string connectname = "Interface" + std::to_string( i1to1 ); + + std::cout << "donorname = " << donorname << "\n"; + std::cout << "connectname = " << connectname << "\n"; + + std::vector & itranfrm = interfaceSplitBc->transform; + + cg_1to1_write( fileId, baseId, zoneId, connectname.c_str(), donorname.c_str(), pnts.data(), pntsdonor.data(), itranfrm.data(), &index_conn ); + std::cout << "index_conn = " << index_conn << "\n"; + } + } + } + cg_close( fileId ); +} + +void Partition::ModifyZoneIndex() +{ + std::cout << "ModifyZoneIndex +++++++++++++++++++++++++ " << "\n"; + int globalZoneId = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + std::cout << "iProc = " << iProc << "\n"; + int nZones = this->GetNZones( iProc ); + std::cout << "nZones in Proc " << iProc << " = " << nZones << "\n"; + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + //splitZone->SetZoneIndex( globalZoneId++ ); + splitZone->newIndex = ( globalZoneId++ ); + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + } + } +} \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.h b/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.h new file mode 100644 index 00000000..8a4a9731 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/Partition.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include +#include + +class SplitZone; + +struct CmpSplitZone +{ + bool operator() ( SplitZone * a, SplitZone * b ) const; +}; + +class Partition +{ +public: + Partition(); + ~Partition(); +protected: + std::set < SplitZone * > zoneStorage; + std::set < SplitZone *, CmpSplitZone > unsignedZoneGroup; + std::vector< SplitZone * > refZone; + std::vector< std::vector< SplitZone * > > procSplitZone; + std::vector procSpeed; + std::vector timeProc; + double aveFloatOp, delta; + double idealUniProcTime, eps; + int minNumberCell; + int nTZone; + int nOriZone; + int nProc; +public: + std::string inputName; + std::string outName; +public: + void Solve(); + void ReadGrid(); + void Split(); + void InitSplit(); + void BinarySplit(); + //void GreedySplit(); +public: + void AddNewZone( SplitZone * zone ); + void AddZoneToUnsignedGroup( SplitZone * zone ); + void RemoveZoneFromUnsignedGroup( SplitZone * zone ); + void AddZoneToProcess( int iProc, SplitZone * zone ); + void DumpPartitionedGridFile(); + void ModifyZoneIndex(); + void FreeAllZones(); + int GetNZones( int iProc ); + SplitZone * GetSplitZone( int iProc, int zoneId ); + void ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ); + void DumpBc( SplitZone * splitZone ); +private: + int GetMinValueIndex( double * data, int numberOfData ); + int GetMinLoadProc(); + SplitZone * GetLargestZone(); + SplitZone * Split( SplitZone * zone, double nCell ); +}; + diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/README.txt b/example/partition/struct/1d-shock-tube/1to2blocks/01/README.txt new file mode 100644 index 00000000..13dc2f91 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/README.txt @@ -0,0 +1 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.cpp b/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.cpp new file mode 100644 index 00000000..aef70754 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.cpp @@ -0,0 +1,1091 @@ +#include "SplitZone.h" +#include "cgnslib.h" +#include + +int Dim::dim = -1; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ) +{ + domainBox.start = zoneBox.start; + domainBox.end = zoneBox.end; + + int axis = iDomain / 2; + int direction = iDomain % 2; + + if ( direction == 0 ) + { + domainBox.end[ axis ] = domainBox.start[ axis ]; + } + else if ( direction == 1 ) + { + domainBox.start[ axis ] = domainBox.end[ axis ]; + } +} + +DimInfo::DimInfo() +{ + this->Init( 1 ); +} + +DimInfo::~DimInfo() +{ +} + +void DimInfo::Init( int dim ) +{ + this->dim = dim; + dimList.resize( this->dim, 1 ); + oriPoint.resize( this->dim, 0 ); +} + +DimInfo & DimInfo::operator = ( const DimInfo & rhs ) +{ + if ( this == & rhs ) return * this; + + this->dim = rhs.dim; + this->dimList = rhs.dimList; + this->oriPoint = rhs.oriPoint; + + return * this; +} + +int DimInfo::ComputeNumNodes() +{ + int nNodes = 1; + for ( int m = 0; m < this->dimList.size(); ++ m ) + { + nNodes *= this->dimList[ m ]; + } + return nNodes; +} + +void DimInfo::ComputeISize() +{ + int index_dim = this->dimList.size(); + this->isize.resize( index_dim * 3, 0 ); + for ( int m = 0; m < index_dim; ++ m ) + { + isize[ m ] = this->dimList[ m ]; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 1; + isize[ start + m ] = this->dimList[ m ] - 1; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 2; + isize[ start + m ] = 0; + } + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } +} + +void DimInfo::ComputeRminmax( std::vector & ref ) +{ + int index_dim = this->dimList.size(); + this->rmin.resize( index_dim ); + this->rmax.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + rmin[ m ] = ref[ m ] + 1; + rmax[ m ] = ref[ m ] + this->dimList[ m ]; + } + + std::cout << "rmin, rmax = \n"; + for ( int m = 0; m < index_dim; ++ m ) + { + std::cout << rmin[ m ] << " " << rmax[ m ] << "\n"; + } +} + +void DimInfo::Init( std::vector & dimList ) +{ + this->dim = dimList.size(); + this->dimList = dimList; + std::vector zero( dimList.size(), 0 ); + this->oriPoint = zero; +} + +void DimInfo::SetNewDimension( int axis, int newStart, int newWidth ) +{ + this->oriPoint[ axis ] = newStart; + this->dimList [ axis ] = newWidth; +} + +void DimInfo::GetZoneGlobalBox( RangeRegion &zoneBox ) +{ + int index_dim = this->dimList.size(); + zoneBox.start.resize( index_dim ); + zoneBox.end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + zoneBox.start[ m ] = this->oriPoint[ m ] + 1; + zoneBox.end[ m ] = this->oriPoint[ m ] + this->dimList[ m ]; + } +} + +void DimInfo::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + int index_dim = this->dimList.size(); + localBox.start.resize( index_dim ); + localBox.end.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + localBox.start[ m ] = globalBox.start[ m ] - this->oriPoint[ m ]; + localBox.end[ m ] = globalBox.end[ m ] - this->oriPoint[ m ]; + } +} + +RangeRegion::RangeRegion( int nSize ) +{ + this->Init( nSize ); +} + +RangeRegion::~RangeRegion() +{ +} + +void RangeRegion::Init( int nSize ) +{ + this->start.resize( nSize ); + this->end.resize( nSize ); +} + +RangeRegion & RangeRegion::operator = ( const RangeRegion & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +bool RangeRegion::operator == ( const RangeRegion & rhs ) const +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( this->start[ m ] != rhs.start[ m ] || + this->end [ m ] != rhs.end [ m ] ) + { + return false; + } + } + return true; +} + +void RangeRegion::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +bool RangeRegion::InRegion( const RangeRegion & region ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( ( this->start[ m ] < region.start[ m ] ) || ( this->end[ m ] > region.end[ m ] ) ) + { + return false; + } + } + return true; +} + +void RangeRegion::Normalize() +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + int minv = std::min( this->start[ m ], this->end[ m ] ); + int maxv = std::max( this->start[ m ], this->end[ m ] ); + this->start[ m ] = minv; + this->end[ m ] = maxv; + } +} + +void RangeRegion::Localize( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::ToGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] += oriPoint[ m ]; + this->end[ m ] += oriPoint[ m ]; + } +} + +void RangeRegion::ToLocal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::PrintGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + std::cout << "global start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "global end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +void RangeRegion::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"; +} + +bool CheckOverLapping( RangeRegion & overlapRegion ); + +bool ComputeOverlapRegion( RangeRegion & region1, RangeRegion & region2, RangeRegion & overlapRegion ) +{ + int index_dim = region1.start.size(); + overlapRegion.Init( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + int ijkmin1 = std::min( region1.start[ m ], region1.end[ m ] ); + int ijkmax1 = std::max( region1.start[ m ], region1.end[ m ] ); + int ijkmin2 = std::min( region2.start[ m ], region2.end[ m ] ); + int ijkmax2 = std::max( region2.start[ m ], region2.end[ m ] ); + if ( ( ijkmax1 < ijkmin2 ) || ( ijkmin1 > ijkmax2 ) ) + { + return false; + } + + int ijkmin = std::max( ijkmin1, ijkmin2 ); + int ijkmax = std::min( ijkmax1, ijkmax2 ); + + overlapRegion.start[ m ] = ijkmin; + overlapRegion.end [ m ] = ijkmax; + } + + return CheckOverLapping( overlapRegion ); +} + +bool CheckOverLapping( RangeRegion & overlapRegion ) +{ + int index_dim = overlapRegion.start.size(); + int iCount = 0; + for ( int m = 0; m < index_dim; ++ m ) + { + if ( overlapRegion.start[ m ] == overlapRegion.end[ m ] ) + { + ++ iCount; + } + } + + return ( iCount == 1 ); +} + +bool GetInterfaceRegion( RangeRegion & zoneBoxL, RangeRegion & zoneBoxR, RangeRegion & interfaceRegion ) +{ + int index_dim = zoneBoxL.start.size(); + int nDomains = 2 * index_dim; + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegionL; + GetDomainRegion( zoneBoxL, iDomain, domainRegionL ); + + for ( int jDomain = 0; jDomain < nDomains; ++ jDomain ) + { + RangeRegion domainRegionR; + GetDomainRegion( zoneBoxR, jDomain, domainRegionR ); + + if ( domainRegionL == domainRegionR ) + { + interfaceRegion = domainRegionL; + return true; + } + } + } + return false; +} + +void CreateInterfaceBc( SplitZone * zoneL, SplitZone * zoneR ) +{ + RangeRegion globalBoxL, globalBoxR, globalInterfaceRegion; + + zoneL->GetZoneGlobalBox( globalBoxL ); + zoneR->GetZoneGlobalBox( globalBoxR ); + + if ( ! GetInterfaceRegion( globalBoxL, globalBoxR, globalInterfaceRegion ) ) + { + return; + } + + RangeRegion localInterfaceRegionL, localInterfaceRegionR; + + zoneL->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionL ); + zoneR->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionR ); + + int kkk = 1; + + InterfaceSplitBc * interfaceSplitBcL = new InterfaceSplitBc(); + zoneL->interfaceSplitBcList.push_back( interfaceSplitBcL ); + interfaceSplitBcL->zone = zoneL; + interfaceSplitBcL->region = localInterfaceRegionL; + + int nSize = localInterfaceRegionL.start.size(); + + std::vector transform; + + for ( int m = 0; m < nSize; ++ m ) + { + transform.push_back( m + 1 ); + } + + interfaceSplitBcL->transform = transform; + interfaceSplitBcL->CalcTransformMatrix(); + + interfaceSplitBcL->donor_zone = zoneR; + interfaceSplitBcL->donor_region = localInterfaceRegionR; + + InterfaceSplitBc * interfaceSplitBcR = new InterfaceSplitBc(); + zoneR->interfaceSplitBcList.push_back( interfaceSplitBcR ); + + interfaceSplitBcR->zone = zoneR; + interfaceSplitBcR->region = localInterfaceRegionR; + + interfaceSplitBcR->transform = transform; + interfaceSplitBcR->CalcTransformMatrix(); + + interfaceSplitBcR->donor_zone = zoneL; + interfaceSplitBcR->donor_region = localInterfaceRegionL; +} + + +PhysicalSplitBc::PhysicalSplitBc() +{ + this->region.Init( Dim::dim ); +} + +PhysicalSplitBc::~PhysicalSplitBc() +{ +} + +void PhysicalSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void PhysicalSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +void PhysicalSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = splitZone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +BasicSplitBc::BasicSplitBc() +{ + this->region.Init( Dim::dim ); +} + +BasicSplitBc::~BasicSplitBc() +{ + ; +} + +void BasicSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void BasicSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +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; + } +} + +InterfaceInfo::InterfaceInfo() +{ + this->donor_region.Init( Dim::dim ); +} + +InterfaceInfo::~InterfaceInfo() +{ +} + +InterfaceSplitBc::InterfaceSplitBc() +{ + this->region.Init( Dim::dim ); + this->donor_region.Init( Dim::dim ); +} + +InterfaceSplitBc::~InterfaceSplitBc() +{ +} + +void InterfaceSplitBc::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nChild = this->child.size(); + if ( nChild == 0 ) + { + leafInterfaceBcList.push_back( this ); + } + else + { + for ( int iChild = 0; iChild < nChild; ++ iChild ) + { + InterfaceSplitBc * interfaceSplitBc = this->child[ iChild ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } + } +} + +void InterfaceSplitBc::CopyMatrix( InterfaceSplitBc * interfaceSplitBc ) +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = interfaceSplitBc->Mt[ i ][ j ]; + } + } +} + +void InterfaceSplitBc::CalcTransformMatrix() +{ + 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 InterfaceSplitBc::mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ) +{ + int dim = Dim::dim; + std::vector diff( dim ); + for ( int m = 0; m < dim; ++ m ) + { + diff[ m ] = index1[ m ] - begin1[ m ]; + } + + std::vector mul( dim ); + + Multiply( Mt, diff, mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = mul[ m ] + begin2[ m ]; + } +} + +void InterfaceSplitBc::Multiply( int Mt[][3], std::vector & a, std::vector & b ) +{ + int dim = Dim::dim; + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += Mt[ i ][ j ] * a[ j ]; + } + } +} + +void InterfaceSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = this->zone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +void InterfaceSplitBc::CalcSubDonorRegion( RangeRegion &subRegion, RangeRegion &subDonorRegion ) +{ + std::vector begin1 = this->region.start; + std::vector end1 = this->region.end; + std::vector begin2 = this->donor_region.start; + std::vector end2 = this->donor_region.end; + + std::vector new_begin1 = subRegion.start; + std::vector new_end1 = subRegion.end; + + int dim = Dim::dim; + std::vector new_begin2( dim ); + std::vector new_end2( dim ); + + mapindex( begin1, begin2, new_begin1, new_begin2 ); + mapindex( begin1, begin2, new_end1, new_end2 ); + + subDonorRegion.start = new_begin2; + subDonorRegion.end = new_end2; +} + +SplitZone::SplitZone() +{ + this->parent = 0; + this->zoneIndex = 0; + this->iProc = 0; + dimInfo.Init( Dim::dim ); + int kk = 1; +} + +SplitZone::~SplitZone() +{ + ; +} + +void SplitZone::GetZoneGlobalBox( RangeRegion & zoneBox ) +{ + this->dimInfo.GetZoneGlobalBox( zoneBox ); +} + +void SplitZone::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + this->dimInfo.GetZoneLocalBox( globalBox, localBox ); +} + + +void SplitZone::ComputeRminmax() +{ + int index_dim = this->dimInfo.dimList.size(); + std::vector ref( index_dim, 0 ); + + SplitZone * rootSplitZone = 0; + this->GetRootInfo( rootSplitZone, ref ); + + this->dimInfo.ComputeRminmax( ref ); +} + +SplitZone * SplitZone::GetRootZone() +{ + SplitZone * root = this; + + while ( true ) + { + if ( root->parent ) + { + root = root->parent; + } + else + { + return root; + } + }; +} + +void SplitZone::GetRootInfo( SplitZone *& root, std::vector & ref ) +{ + for ( int i = 0; i < this->dimInfo.dimList.size(); ++ i ) + { + ref[ i ] += this->dimInfo.oriPoint[ i ]; + } + + if ( this->parent ) + { + this->parent->GetRootInfo( root, ref ); + } + else + { + root = this; + } +} + +void SplitZone::SetParentAndChild( SplitZone * parent ) +{ + this->parent = parent; + if ( parent ) + { + parent->child.push_back( this ); + } +} + +void SplitZone::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nInterfaceBcs = this->interfaceSplitBcList.size(); + for ( int i = 0; i < nInterfaceBcs; ++ i ) + { + InterfaceSplitBc * interfaceSplitBc = this->interfaceSplitBcList[ i ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } +} + +int SplitZone::GetNCell() +{ + int numberOfCells = 1; + for ( int i = 0; i < this->dimInfo.dim; ++ i ) + { + numberOfCells *= std::max( 1, ( this->dimInfo.dimList[ i ] - 1 ) ); + } + + return numberOfCells; +} + +void SplitZone::SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int leftStart = 0; + int leftWidth = iSplit - 0; + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, leftStart , leftWidth ); +} + +void SplitZone::SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int rightStart = iSplit - 1; + int rightWidth = dimList[ axisNeedSplit ] - ( iSplit - 1 ); + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, rightStart, rightWidth ); +} + +void SplitZone::Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ) +{ + //Find the longest axis + int axisNeedSplit = this->FindAxisNeedSplit(); + int iSplit = this->FindSplitPosition( axisNeedSplit, nCell ); + + zoneL->SetLeftDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + zoneR->SetRightDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + + zoneL->CreateBcFromParent(); + zoneR->CreateBcFromParent(); + + CreateInterfaceBc( zoneL, zoneR ); +} + +void SplitZone::CreateBcFromParent() +{ + this->CreatePhysicalBcFromParent(); + this->CreateInterfaceBcFromParent(); +} + +void SplitZone::CreatePhysicalBcFromParent() +{ + int nParentPhysicalBcs = this->parent->physicalSplitBcList.size(); + + for ( int iParentPhysicalBcs = 0; iParentPhysicalBcs < nParentPhysicalBcs; ++ iParentPhysicalBcs ) + { + PhysicalSplitBc * parentPhysicalSplitBc = this->parent->physicalSplitBcList[ iParentPhysicalBcs ]; + + this->CreatePhysicalBcFromParent( parentPhysicalSplitBc ); + } +} + +void SplitZone::CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentPhysicalSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreatePhysicalBc( overlapRegion, parentPhysicalSplitBc->bcType ); + + int kkk = 1; + } +} + +void SplitZone::CreateInterfaceBcFromParent() +{ + int nInterfaceSplitBcs = this->parent->interfaceSplitBcList.size(); + + for ( int iInterfaceSplitBcs = 0; iInterfaceSplitBcs < nInterfaceSplitBcs; ++ iInterfaceSplitBcs ) + { + InterfaceSplitBc * parentInterfaceSplitBc = this->parent->interfaceSplitBcList[ iInterfaceSplitBcs ]; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc ); + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentInterfaceSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc, overlapRegion ); + + int kkk = 1; + } +} + +void SplitZone::FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ) +{ + RangeRegion donor_region = interfaceSplitBc->donor_region; + donor_region.Normalize(); + interfaceInfo.donor_zone = this; + for ( int iInterface = 0; iInterface < interfaceSplitBcList.size(); ++ iInterface ) + { + InterfaceSplitBc * candidateDonorBc = interfaceSplitBcList[ iInterface ]; + bool flag = donor_region.InRegion( candidateDonorBc->region ); + if ( flag ) + { + if ( donor_region == candidateDonorBc->region ) + { + interfaceInfo.donor_interface = candidateDonorBc; + return; + } + else + { + InterfaceSplitBc * donorBc = new InterfaceSplitBc(); + candidateDonorBc->child.push_back( donorBc ); + donorBc->region = donor_region; + donorBc->zone = candidateDonorBc->zone; + donorBc->donor_zone = interfaceSplitBc->zone; + donorBc->transform = candidateDonorBc->transform; + donorBc->CopyMatrix( candidateDonorBc ); + RangeRegion subDonorRegion( Dim::dim ); + candidateDonorBc->CalcSubDonorRegion( donorBc->region, subDonorRegion ); + std::vector & oriPoint = interfaceSplitBc->zone->dimInfo.oriPoint; + subDonorRegion.Localize( oriPoint ); + donorBc->donor_region = subDonorRegion; + donorBc->donor_bc = interfaceSplitBc; + interfaceInfo.donor_interface = donorBc; + return; + } + } + } + return; +} + +void SplitZone::GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ) +{ + std::cout << "subDonorRegion = \n"; + //subDonorRegion.Print(); + RangeRegion normalizedDonorRegion = subDonorRegion; + normalizedDonorRegion.Normalize(); + int nChild = this->child.size(); + for ( int ichild = 0; ichild < nChild; ++ ichild ) + { + std::cout << " iChild = " << ichild << " nChild = " << nChild << "\n"; + SplitZone * sub_zone = this->child[ ichild ]; + std::cout << " zoneIndex = " << sub_zone->zoneIndex << "\n"; + int nInters = sub_zone->interfaceSplitBcList.size(); + for ( int iInter = 0; iInter < nInters; ++ iInter ) + { + std::cout << " iInter = " << iInter << "\n"; + InterfaceSplitBc * interfaceSplitBc = sub_zone->interfaceSplitBcList[ iInter ]; + std::cout << "interfaceSplitBc local = \n"; + interfaceSplitBc->region.Print(); + std::cout << "interfaceSplitBc global = \n"; + interfaceSplitBc->region.PrintGlobal( sub_zone->dimInfo.oriPoint ); + RangeRegion g_region = interfaceSplitBc->region; + g_region.ToGlobal( sub_zone->dimInfo.oriPoint ); + if ( g_region == normalizedDonorRegion ) + { + RangeRegion donorRegion = subDonorRegion; + donorRegion.ToLocal( sub_zone->dimInfo.oriPoint ); + + interfaceInfo.donor_zone = sub_zone; + interfaceInfo.donor_interface = interfaceSplitBc; + interfaceInfo.donor_region = donorRegion; + return; + } + } + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ) +{ + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + this->interfaceSplitBcList.push_back( interfaceSplitBc ); + + interfaceSplitBc->region = overlapRegion; + interfaceSplitBc->zone = this; + interfaceSplitBc->transform = parentInterfaceSplitBc->transform; + interfaceSplitBc->CopyMatrix( parentInterfaceSplitBc ); + RangeRegion subDonorRegion( Dim::dim ); + parentInterfaceSplitBc->CalcSubDonorRegion( overlapRegion, subDonorRegion ); + interfaceSplitBc->ChangeRegionToLocalCoordinate(); + interfaceSplitBc->donor_region = subDonorRegion; + SplitZone * parent_donor_zone = parentInterfaceSplitBc->donor_zone; + std::cout << " parentInterfaceSplitBc->zone->zoneIndex " << parentInterfaceSplitBc->zone->zoneIndex << "\n"; + std::cout << " parentInterfaceSplitBc->donor_zone->zoneIndex " << parent_donor_zone->zoneIndex << "\n"; + if ( parent_donor_zone->child.size() > 0 ) + { + InterfaceInfo interfaceInfo; + parent_donor_zone->GetChildDonorRegion( subDonorRegion, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + interfaceSplitBc->donor_region = interfaceInfo.donor_region; + //compatibility + InterfaceSplitBc * donor_bc = interfaceSplitBc->donor_bc; + SplitZone * donor_zone = interfaceSplitBc->donor_zone; + if ( interfaceSplitBc->zone != donor_bc->donor_zone ) + { + if ( interfaceSplitBc->zone->parent == donor_bc->donor_zone ) + { + RangeRegion d_region = donor_bc->donor_region; + d_region.ToLocal( interfaceSplitBc->zone->dimInfo.oriPoint ); + donor_bc->donor_region = d_region; + } + donor_bc->donor_zone = interfaceSplitBc->zone; + + int kkk = 1; + } + int kkk = 1; + } + else + { + InterfaceInfo interfaceInfo; + parent_donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + + int kkk = 1; +} + +void SplitZone::CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ) +{ + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + this->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->SetRegion( overlapRegion ); + physicalSplitBc->bcType = bcType; + physicalSplitBc->splitZone = this; + physicalSplitBc->ChangeRegionToLocalCoordinate(); +} + +int SplitZone::FindAxisNeedSplit() +{ + //Find the longest axis + int axisNeedSplit = 0; + int maxN = this->dimInfo.dimList[ 0 ]; + + for ( int m = 1; m < this->dimInfo.dimList.size(); ++ m ) + { + if ( this->IsPoleBc( m ) ) + { + continue; + } + int Nm = this->dimInfo.dimList[ m ]; + if ( maxN < Nm ) + { + maxN = Nm; + axisNeedSplit = m; + } + } + + return axisNeedSplit; +} + +int SplitZone::GetCrossSection( int axis ) +{ + int nDim = this->dimInfo.dimList.size(); + int crossSection = 1; + int N = nDim - 1; + for ( int m = 0; m < N; ++ m ) + { + int mm = ( axis + 1 ) % nDim; + int nLineElements = std::max( 1, ( this->dimInfo.dimList[ mm ] - 1 ) ); + crossSection *= nLineElements; + } + return crossSection; +} + +int SplitZone::FindSplitPosition( int axisNeedSplit, double nCell ) +{ + int nDim = this->dimInfo.dimList.size(); + std::vector crossSections( nDim ); + for ( int m = 0; m < nDim; ++ m ) + { + crossSections[ m ] = this->GetCrossSection( m ); + } + + //guess the value + double dSplit = nCell / crossSections[ axisNeedSplit ]; + int iSplit = 1 + static_cast< int >( std::floor( dSplit + 0.5 ) ); + return iSplit; +} + + +bool SplitZone::IsPoleBc( int splitDirection ) +{ + return false; +} + diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.h b/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.h new file mode 100644 index 00000000..ffe1e306 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/SplitZone.h @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include + +class Dim +{ +public: + static int dim; +}; + +class SplitZone; +class RangeRegion; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ); + +class DimInfo +{ +public: + DimInfo(); + ~DimInfo(); +public: + int dim; + std::vector dimList; + std::vector oriPoint; + std::vector isize; + std::vector rmin; + std::vector rmax; +public: + int GetSize() const { return dim; } + DimInfo & operator = ( const DimInfo & rhs ); +public: + int ComputeNumNodes(); + void ComputeISize(); + void ComputeRminmax( std::vector & ref ); + void Init( int dim ); + void Init( std::vector & dimList ); + void SetNewDimension( int axis, int newStart, int newWidth ); + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); +}; + +class SplitZone; +class SplitBcPatch; + +class RangeRegion +{ +public: + RangeRegion( int nSize = 1 ); + ~RangeRegion(); +public: + std::vector start; + std::vector end; +public: + void Init( int nSize ); + RangeRegion & operator = ( const RangeRegion & rhs ); + bool operator == ( const RangeRegion & rhs ) const; + bool InRegion( const RangeRegion & region ); + void SetRegion( std::vector &pnts ); + void Normalize(); + void Localize( std::vector & oriPoint ); + void ToGlobal( std::vector & oriPoint ); + void ToLocal( std::vector & oriPoint ); + void PrintGlobal( std::vector & oriPoint ); + void Print(); +}; + +class PhysicalSplitBc +{ +public: + PhysicalSplitBc(); + ~PhysicalSplitBc(); +public: + int bcType; + RangeRegion region; +public: + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector &pnts ); + void SetRegion( RangeRegion ®ion ); + void ChangeRegionToLocalCoordinate(); +}; + +class BasicSplitBc +{ +public: + BasicSplitBc(); + ~BasicSplitBc(); +public: + RangeRegion region; + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector & pnts ); + void SetRegion( RangeRegion & region ); +}; + +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 InterfaceSplitBc; +class SplitZone; + +class InterfaceInfo +{ +public: + InterfaceInfo(); + ~InterfaceInfo(); +public: + InterfaceSplitBc * donor_interface = nullptr; + SplitZone * donor_zone = nullptr; + RangeRegion donor_region; +}; + +class InterfaceSplitBc +{ +public: + InterfaceSplitBc(); + ~InterfaceSplitBc(); +public: + std::vector transform; + int Mt[ 3 ][ 3 ]; + RangeRegion region; + SplitZone * zone = nullptr; + RangeRegion donor_region; + SplitZone * donor_zone = nullptr; + InterfaceSplitBc * donor_bc = nullptr; +public: + std::vector child; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + void CopyMatrix( InterfaceSplitBc * interfaceSplitBc ); + void CalcTransformMatrix(); + void CalcSubDonorRegion( RangeRegion & subRegion, RangeRegion & subDonorRegion ); + void mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ); + void Multiply( int Mt[][ 3 ], std::vector & a, std::vector & b ); + void ChangeRegionToLocalCoordinate(); +}; + +class SplitZone +{ +public: + SplitZone(); + ~SplitZone(); +public: + DimInfo dimInfo; + int zoneIndex, iProc; + int newIndex; +protected: + SplitZone * parent; + std::vector child; +public: + std::vector< PhysicalSplitBc * > physicalSplitBcList; + std::vector< InterfaceSplitBc * > interfaceSplitBcList; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + int GetNCell(); + void ComputeRminmax(); + void GetRootInfo( SplitZone *& root, std::vector & ref ); + void SetZoneIndex( int zoneIndex ) { this->zoneIndex = zoneIndex; } + int GetZoneIndex() { return zoneIndex; } + void SetProcId( int iProc ) { this->iProc = iProc; } + void SetParent( SplitZone * parent ) { this->parent = parent; }; + void SetParentAndChild( SplitZone * parent ); + void FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ); + void GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ); +public: + void CreateBcFromParent(); + void CreatePhysicalBcFromParent(); + void CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ); + void CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ); + void CreateInterfaceBcFromParent(); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ); + + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); + SplitZone * GetRootZone(); +public: + void Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ); + void SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); + void SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); +private: + int FindAxisNeedSplit(); + int FindSplitPosition( int axisNeedSplit, double nCell ); + bool IsPoleBc( int splitDirection ); + int GetCrossSection( int axis ); +}; + diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/main.cpp b/example/partition/struct/1d-shock-tube/1to2blocks/01/main.cpp new file mode 100644 index 00000000..5da1de7c --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to2blocks/01/main.cpp @@ -0,0 +1,18 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include "Partition.h" +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + Partition * partition = new Partition(); + partition->Solve(); + delete partition; + + return 0; +} diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d1blocksv1.cgns b/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d2blocks.cgns b/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/partition/struct/1d-shock-tube/1to2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/CMakeLists.txt b/example/partition/struct/1d-shock-tube/1to4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..74ceea7d --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.30) + +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 ) + +find_package(Eigen3 CONFIG REQUIRED) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +#list ( APPEND PRJ_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR} ) +list ( APPEND PRJ_LIBRARIES Eigen3::Eigen ) +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() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Partition.h Partition.cpp + CgnsGrid.h CgnsGrid.cpp + SplitZone.h SplitZone.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/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.cpp b/example/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.cpp new file mode 100644 index 00000000..dfe750bd --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.cpp @@ -0,0 +1,349 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include + +Grid::Grid() +{ + ; +} + +Grid::~Grid() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } +} + +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"; +} + +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 ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ + delete this->patch; +} + + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +ZoneBcPatch::ZoneBcPatch() +{ + ; +} + +ZoneBcPatch::~ZoneBcPatch() +{ +} + +std::vector Global::zones; +BaseZoneList Global::zone_names; +int Global::cell_dim = -1; +int Global::phys_dim = -1; + +Global::Global() +{ + ; +} + +Global::~Global() +{ +} + +void Global::FreeData() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } + zones.resize( 0 ); +} + + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + BaseZone baseZone; + //baseZone.baseId = baseId; + baseZone.zone_name = zonename; + + Global::zone_names.AddBaseZone( baseZone ); + } + } + cg_close( fileId ); +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + Zone * zone = new Zone(); + Global::zones.push_back( zone ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + + BaseZone baseZone; + baseZone.zone_name = zonename; + int gZoneId = Global::zone_names.FindBaseZone( baseZone ); + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + std::vector irmin( index_dim ); + std::vector irmax( index_dim ); + int nNodes = 1; + 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 ]; + zone->nijk.push_back( isize[ m ] ); + } + std::cout << "nNodes = " << nNodes << "\n"; + + ZoneType_t zoneType; + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[zoneType] << "\n"; + int ncoords = -1; + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + std::cout << "coordname = " << coordname << "\n"; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[dataType] << "\n"; + std::vector coord( nNodes * sizeof(double) ); + + Coor * coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord.resize( nNodes * sizeof( double ) ); + + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coor->coord.data() ); + coor->DumpCoor(); + } + + int nbocos = -1; + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + + ZoneBc * zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + std::vector normalIndex( index_dim, -1 ); + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + zonebc->bcType = bocotype; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[bocotype] << "\n"; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "ndataset = " << ndataset << "\n"; + + std::vector normalList( nNodes * iphysdim * sizeof( double ) ); + + std::vector pnts( npnts * index_dim ); + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + zonebc->pnts.push_back( pnts[ i ] ); + } + std::cout << "\n"; + + double * normal_d = reinterpret_cast( const_cast( normalList.data() ) ); + } + + int n1to1 = -1; + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + std::cout << "n1to1 = " << n1to1 << "\n"; + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + ZoneBc1To1 * zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range( npnts * index_dim ); + std::vector donor_range( npnts * index_dim ); + std::vector transform( index_dim ); + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + std::cout << "connectname = " << connectname << "\n"; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "range = \n"; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "donor_range = \n"; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + BaseZone baseZone; + baseZone.zone_name = donorname; + int gDonorZoneId = Global::zone_names.FindBaseZone( baseZone ); + + 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 ] ); + } + + int kkk = 1; + } + } + int kkk = 1; + } + int kkk = 1; + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.h b/example/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.h new file mode 100644 index 00000000..053c467b --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/CgnsGrid.h @@ -0,0 +1,140 @@ +#pragma once +#include +#include +#include + +class Grid; + +class Zone; + +class Grid +{ +public: + Grid(); + ~Grid(); +public: + int nZone; + std::vector x; + std::vector zones; +}; + + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); +}; + +class ZoneBc; +class ZoneBc1To1; + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class ZoneBcPatch; +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; + ZoneBcPatch * patch = nullptr; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + +class ZoneBcPatch +{ +public: + ZoneBcPatch(); + ~ZoneBcPatch(); +public: + int donor_zoneid; + std::vector transform; + std::vector donor_pnts; +}; + +class BaseZone +{ +public: + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + 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; + } +}; + +class Global +{ +public: + Global(); + ~Global(); +public: + static int cell_dim; + static int phys_dim; + static std::vector zones; + static BaseZoneList zone_names; +public: + static void FreeData(); +}; + +void ReadCgnsGrid( const std::string & filename ); +void ReadCgnsGridBaseZone( const std::string & filename ); \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.cpp b/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.cpp new file mode 100644 index 00000000..88f528b0 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.cpp @@ -0,0 +1,619 @@ +#include "Partition.h" +#include "CgnsGrid.h" +#include "SplitZone.h" +#include "cgnslib.h" +#include + +bool CmpSplitZone::operator() ( SplitZone * a, SplitZone * b ) const +{ + return a->zoneIndex < b->zoneIndex; +}; + + +double CalSumOfProcSpeed( std::vector & procSpeed ); +double CalSumOfProcSpeed( std::vector & procSpeed ) +{ + int nProc = procSpeed.size(); + double sumOfProcSpeed = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + sumOfProcSpeed += procSpeed[ iProc ]; + } + return sumOfProcSpeed; +} + +Partition::Partition() +{ + this->nProc = 4; + this->inputName = "../sodshocktube1d1blocksv1.cgns"; + this->outName = std::format( "../sodshocktube1d{}blocks.cgns", this->nProc ); +} + +Partition::~Partition() +{ + ; +} + +int Partition::GetMinValueIndex( double * data, int numberOfData ) +{ + double minValue = data[ 0 ]; + int minimumValueIndex = 0; + + for ( int iData = 1; iData < numberOfData; ++ iData ) + { + if ( minValue > data[ iData ] ) + { + minValue = data[ iData ]; + minimumValueIndex = iData; + } + } + return minimumValueIndex; +} + +int Partition::GetMinLoadProc() +{ + return this->GetMinValueIndex( this->timeProc.data(), this->nProc ); +} + +SplitZone * Partition::GetLargestZone() +{ + SplitZone * largestZone = 0; + + double nMaxCell = 0.0; + + for ( std::set< SplitZone * >::iterator iter = unsignedZoneGroup.begin(); iter != unsignedZoneGroup.end(); ++ iter ) + { + double nSize = ( * iter )->GetNCell(); + if ( nMaxCell < nSize ) + { + nMaxCell = nSize; + largestZone = * iter; + } + } + + return largestZone; +} + +void Partition::Solve() +{ + std::cout << "Partition::Split()\n"; + this->ReadGrid(); + this->Split(); + this->DumpPartitionedGridFile(); + this->FreeAllZones(); +} + +void Partition::ReadGrid() +{ + ReadCgnsGridBaseZone( this->inputName ); + ReadCgnsGrid( this->inputName ); + + this->nOriZone = ::Global::zones.size(); + Dim::dim = Global::cell_dim; + + std::cout << "numberOfBlocks = " << nOriZone << "\n"; + + this->refZone.resize( nOriZone ); + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = new SplitZone(); + refZone[ iZone ] = splitZone; + + splitZone->SetZoneIndex( iZone ); + splitZone->SetProcId( 0 ); + splitZone->SetParentAndChild( 0 ); + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + Zone * zone = ::Global::zones[ iZone ]; + + splitZone->dimInfo.dimList = zone->nijk; + + int nbccos = zone->bccos.size(); + std::cout << "nbccos = " << nbccos << "\n"; + + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zoneBc = zone->bccos[ ibcco ]; + + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + splitZone->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->bcType = zoneBc->bcType; + physicalSplitBc->SetRegion( zoneBc->pnts ); + physicalSplitBc->splitZone = splitZone; + } + + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * zoneBc1To1 = zone->bc1to1s[ ibc1to1 ]; + + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + splitZone->interfaceSplitBcList.push_back( interfaceSplitBc ); + interfaceSplitBc->zone = splitZone; + interfaceSplitBc->region.SetRegion( zoneBc1To1->pnts ); + + interfaceSplitBc->transform = zoneBc1To1->transform; + interfaceSplitBc->CalcTransformMatrix(); + + interfaceSplitBc->donor_zone = refZone[ zoneBc1To1->donor_zoneid ]; + interfaceSplitBc->donor_region.SetRegion( zoneBc1To1->donor_pnts ); + } + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + int nbc1to1s = splitZone->interfaceSplitBcList.size(); + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + InterfaceSplitBc * interfaceSplitBc = splitZone->interfaceSplitBcList[ ibc1to1 ]; + InterfaceInfo interfaceInfo; + interfaceSplitBc->donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + } +} + +void Partition::Split() +{ + this->InitSplit(); + this->BinarySplit(); + this->ModifyZoneIndex(); + int kkk = 1; +} + +void Partition::InitSplit() +{ + //nZone is the number of zones in the original grid + //nProc is not the number of blocks in the end, but the number of processes that need to be divided. + //This difference occurs because the structure grid can have many blocks per process. + + //this->nProc = nProc; + //this->nPhyBlocks = referenceBlock.size(); + //this->nZone = this->nPhyBlocks; + + //tj Computation time on processor j + //Nk Number of internal grid-cells for zone j + //aveFloatOp: Number of Real operations per gridcell + //Gj The set of blocks allocated to process j + //Pj Real operations per second for process j + + //The Greedy Load Balancing Algorithm + //1.Compute an "ideal" uniprocessor time, Tuni = sum ( Nk * aveFloatOp )/ sum( Pj ). + //2.Set the group of unassigned blocks, Gu, to contain all blocks. The number of blocks in Nu=M, where M is the total number of blocks in the mesh. + //3.Start all processors with a very small fictitious zone to get a start tj=delt aveFloatOp/Pj, where delt<<1 is the size of the very small fictious zone. + //This is used to find the fastest processor in a heterogeneous system, tj could otherwise be set to 0 in the homogeneous case. + this->aveFloatOp = 1.0; + this->delta = 1.0e-5; + this->procSpeed.resize( nProc ); + this->timeProc.resize( nProc ); + + this->nTZone = this->nOriZone; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + procSpeed[ iProc ] = 1.0; + } + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + timeProc[ iProc ] = delta * aveFloatOp / procSpeed[ iProc ]; + } + + double sumProcSpeed = CalSumOfProcSpeed( procSpeed ); + + double sumProcOp = 0.0; + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + sumProcOp += refZone[ iZone ]->GetNCell() * aveFloatOp; + } + + this->idealUniProcTime = sumProcOp / sumProcSpeed; + + this->eps = 0.05; + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + unsignedZoneGroup.insert( refZone[ iZone ] ); + } + + //Init zoneStorage + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + zoneStorage.insert( refZone[ iZone ] ); + } + + //Assign procSplitZone to each process + procSplitZone.resize( nProc ); + + this->minNumberCell = 1; + for ( int m = 0; m < Dim::dim; ++ m ) + { + this->minNumberCell *= 1; + } + + int kkk = 1; + +} + +void Partition::FreeAllZones() +{ + int iCount = 0; + for ( std::set < SplitZone * >::iterator iter = zoneStorage.begin(); iter != zoneStorage.end(); ++ iter ) + { + //cout << "iCount = " << iCount << "\n"; + ++ iCount; + delete * iter; + } +} + +int Partition::GetNZones( int iProc ) +{ + return this->procSplitZone[ iProc ].size(); +} + +SplitZone * Partition::GetSplitZone( int iProc, int zoneId ) +{ + return this->procSplitZone[ iProc ][ zoneId ]; +} + +void Partition::AddZoneToUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.insert( zone ); +} + +void Partition::RemoveZoneFromUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.erase( zone ); +} + +void Partition::AddZoneToProcess( int iProc, SplitZone * zone ) +{ + this->procSplitZone[ iProc ].push_back( zone ); +} + +void Partition::AddNewZone( SplitZone * zone ) +{ + zone->SetZoneIndex( nTZone ++ ); + + this->AddZoneToUnsignedGroup( zone ); + + this->zoneStorage.insert( zone ); +} + +SplitZone * Partition::Split( SplitZone * zone, double nCell ) +{ + SplitZone * zoneL = new SplitZone(); + zoneL->SetParentAndChild( zone ); + + SplitZone * zoneR = new SplitZone(); + zoneR->SetParentAndChild( zone ); + + //Remove the original block from the UnsignedGroup + this->RemoveZoneFromUnsignedGroup( zone ); + + this->AddNewZone( zoneL ); + this->AddNewZone( zoneR ); + + zone->Split( zoneL, zoneR, nCell ); + + return zoneL; +} + +void Partition::BinarySplit() +{ + while ( ! unsignedZoneGroup.empty() ) + { + std::cout << "number of unsigned zone = " << unsignedZoneGroup.size() << "\n"; + int iProc = this->GetMinLoadProc(); + + //Get the block with the largest number of grids and its size + SplitZone * largestZone = this->GetLargestZone(); + + double nMaxCell = largestZone->GetNCell(); + + double aveFloatOp = this->aveFloatOp; + double tau = timeProc[ iProc ] + nMaxCell * aveFloatOp / procSpeed[ iProc ]; + + //It seems that EPS is still necessary + //The idea here is as follows. For the candidate blocks which can be divided into blocks, + //if the difference between the target blocks and the candidate blocks is too wide, + //the binarySplit method is adopted. The binarySplit blocks do not directly join the process, + //but enter the next round of screening. + + if ( tau > idealUniProcTime * ( 1.0 + eps ) ) + { + double nRest = ( tau - idealUniProcTime ) * procSpeed[ iProc ] / aveFloatOp; + + double nTarget = nMaxCell - nRest; + if ( nRest > this->minNumberCell && nTarget > this->minNumberCell ) + { + //It is necessary to divide blocks only when a certain number of points are satisfied. + double nHalf = nMaxCell / 2.0; + nMaxCell = nTarget; + double ratio = nMaxCell / nRest; + double oRatio = 1.0 / ratio; + + if ( std::max( ratio, oRatio ) < 3.0 ) + { + int kkk = 1; + largestZone = this->Split( largestZone, nMaxCell ); + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + else + { + this->Split( largestZone, nHalf ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } +} + +void Partition::ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ) +{ + SplitZone * rootSplitZone = splitZone->GetRootZone(); + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + coord.resize( nNodes * sizeof(double) ); + + int index_dim = splitZone->dimInfo.dimList.size(); + Coor * coor = zone->coors[ icoord ]; + + double * xlocal = reinterpret_cast( const_cast( coord.data() ) ); + double * xglobal = reinterpret_cast( const_cast( coor->coord.data() ) ); + if ( index_dim == 1 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ i ]; + } + } + else if ( index_dim == 2 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + int jmin = splitZone->dimInfo.rmin[ 1 ] - 1; + int jmax = splitZone->dimInfo.rmax[ 1 ]; + int ni = rootSplitZone->dimInfo.dimList[ 0 ]; + int nj = rootSplitZone->dimInfo.dimList[ 1 ]; + for ( int j = jmin; j < jmax; ++ j ) + { + int jstride = j * ni; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ jstride + i ]; + } + } + } +} + +void Partition::DumpBc( SplitZone * splitZone ) +{ +} + +void Partition::DumpPartitionedGridFile() +{ + std::cout << "\n"; + std::cout << "DumpPartitionedGridFile -------------------------------" << "\n"; + std::cout << "\n"; + int fileId = -1; + std::string filename = this->outName; + int ierr = cg_open( filename.c_str(), CG_MODE_WRITE, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + + std::vector coordnames; + coordnames.push_back( "CoordinateX" ); + coordnames.push_back( "CoordinateY" ); + coordnames.push_back( "CoordinateZ" ); + + std::string basename = "Base"; + int baseId = -1; + int icelldim = Global::cell_dim; + int iphysdim = Global::phys_dim; + cg_base_write( fileId, basename.c_str(), icelldim, iphysdim, &baseId ); + + std::cout << "baseId = " << baseId << "\n"; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + int nZones = this->GetNZones( iProc ); + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + ZoneType_t zoneType = Structured; + + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + + int index_dim = splitZone->dimInfo.dimList.size(); + std::cout << "index_dim = " << index_dim << "\n"; + + splitZone->dimInfo.ComputeISize(); + + int isize_dim = index_dim * 3; + + std::vector isize( index_dim * 3, 0 ); + for ( int m = 0; m < isize_dim; ++ m ) + { + isize[ m ] = splitZone->dimInfo.isize[ m ]; + } + + int zoneId = -1; + + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + + std::string zonename = "Zone" + std::to_string( splitZone->newIndex ); + + cg_zone_write( fileId, baseId, zonename.c_str(), isize.data(), zoneType, &zoneId ); + + std::cout << "zoneId = " << zoneId << "\n"; + std::cout << "zonename = " << zonename << "\n"; + + splitZone->ComputeRminmax(); + + SplitZone * rootSplitZone = splitZone->GetRootZone(); + + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int ncoords = zone->coors.size(); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = -1; + DataType_t dataType = RealDouble; + std::string coordname = coordnames[ icoord ]; + Coor * coor = zone->coors[ icoord ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + std::vector coord; + ComputeCoor( splitZone, icoord, coord ); + + cg_coord_write( fileId, baseId, zoneId, dataType, coordname.c_str(), coord.data(), &coorId ); + + std::cout << "fileId = " << fileId << " baseId = " << baseId << " zoneId = " << zoneId << " coorId = " << coorId << "\n"; + } + + std::vector< PhysicalSplitBc * > &bccoList = splitZone->physicalSplitBcList; + + int nbocos = bccoList.size(); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = -1; + GridLocation_t location = Vertex; + + std::string boconame = "BC" + std::to_string( iboco + 1 ); + + PhysicalSplitBc * physicalSplitBc = bccoList[ iboco ]; + BCType_t bocotype = static_cast( physicalSplitBc->bcType ); + PointSetType_t ptset_type = PointRange; + cgsize_t npnts = 2; + std::vector pnts; + int nSize = physicalSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.end[ i ] ); + } + + cg_boco_write( fileId, baseId, zoneId, boconame.c_str(), bocotype, ptset_type, npnts, pnts.data(), & bccoId ); + } + + //std::vector< InterfaceSplitBc * > & bc1to1List = splitZone->interfaceSplitBcList; + std::vector< InterfaceSplitBc * > bc1to1List; + splitZone->GetLeafInterfaceBc( bc1to1List ); + + int n1to1 = bc1to1List.size(); + std::cout << "n1to1 = " << n1to1 << "\n"; + + std::vector itranfrm( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + itranfrm[ m ] = m + 1; + } + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int index_conn = -1; + + InterfaceSplitBc * interfaceSplitBc = bc1to1List[ i1to1 ]; + + std::vector pnts; + std::vector pntsdonor; + int nSize = interfaceSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.end[ i ] ); + } + + int nPatchSize = interfaceSplitBc->donor_region.start.size(); + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.start[ i ] ); + } + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.end[ i ] ); + } + int id = interfaceSplitBc->donor_zone->newIndex; + int oldZoneIndex = interfaceSplitBc->donor_zone->zoneIndex; + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + std::cout << "donor zone id = " << id << "\n"; + std::cout << "donor zone oldZoneIndex = " << oldZoneIndex << "\n"; + std::string donorname = "Zone" + std::to_string( id ); + std::string connectname = "Interface" + std::to_string( i1to1 ); + + std::cout << "donorname = " << donorname << "\n"; + std::cout << "connectname = " << connectname << "\n"; + + std::vector & itranfrm = interfaceSplitBc->transform; + + cg_1to1_write( fileId, baseId, zoneId, connectname.c_str(), donorname.c_str(), pnts.data(), pntsdonor.data(), itranfrm.data(), &index_conn ); + std::cout << "index_conn = " << index_conn << "\n"; + } + } + } + cg_close( fileId ); +} + +void Partition::ModifyZoneIndex() +{ + std::cout << "ModifyZoneIndex +++++++++++++++++++++++++ " << "\n"; + int globalZoneId = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + std::cout << "iProc = " << iProc << "\n"; + int nZones = this->GetNZones( iProc ); + std::cout << "nZones in Proc " << iProc << " = " << nZones << "\n"; + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + //splitZone->SetZoneIndex( globalZoneId++ ); + splitZone->newIndex = ( globalZoneId++ ); + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + } + } +} \ No newline at end of file diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.h b/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.h new file mode 100644 index 00000000..8a4a9731 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/Partition.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include +#include + +class SplitZone; + +struct CmpSplitZone +{ + bool operator() ( SplitZone * a, SplitZone * b ) const; +}; + +class Partition +{ +public: + Partition(); + ~Partition(); +protected: + std::set < SplitZone * > zoneStorage; + std::set < SplitZone *, CmpSplitZone > unsignedZoneGroup; + std::vector< SplitZone * > refZone; + std::vector< std::vector< SplitZone * > > procSplitZone; + std::vector procSpeed; + std::vector timeProc; + double aveFloatOp, delta; + double idealUniProcTime, eps; + int minNumberCell; + int nTZone; + int nOriZone; + int nProc; +public: + std::string inputName; + std::string outName; +public: + void Solve(); + void ReadGrid(); + void Split(); + void InitSplit(); + void BinarySplit(); + //void GreedySplit(); +public: + void AddNewZone( SplitZone * zone ); + void AddZoneToUnsignedGroup( SplitZone * zone ); + void RemoveZoneFromUnsignedGroup( SplitZone * zone ); + void AddZoneToProcess( int iProc, SplitZone * zone ); + void DumpPartitionedGridFile(); + void ModifyZoneIndex(); + void FreeAllZones(); + int GetNZones( int iProc ); + SplitZone * GetSplitZone( int iProc, int zoneId ); + void ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ); + void DumpBc( SplitZone * splitZone ); +private: + int GetMinValueIndex( double * data, int numberOfData ); + int GetMinLoadProc(); + SplitZone * GetLargestZone(); + SplitZone * Split( SplitZone * zone, double nCell ); +}; + diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/README.txt b/example/partition/struct/1d-shock-tube/1to4blocks/01/README.txt new file mode 100644 index 00000000..13dc2f91 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/README.txt @@ -0,0 +1 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.cpp b/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.cpp new file mode 100644 index 00000000..aef70754 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.cpp @@ -0,0 +1,1091 @@ +#include "SplitZone.h" +#include "cgnslib.h" +#include + +int Dim::dim = -1; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ) +{ + domainBox.start = zoneBox.start; + domainBox.end = zoneBox.end; + + int axis = iDomain / 2; + int direction = iDomain % 2; + + if ( direction == 0 ) + { + domainBox.end[ axis ] = domainBox.start[ axis ]; + } + else if ( direction == 1 ) + { + domainBox.start[ axis ] = domainBox.end[ axis ]; + } +} + +DimInfo::DimInfo() +{ + this->Init( 1 ); +} + +DimInfo::~DimInfo() +{ +} + +void DimInfo::Init( int dim ) +{ + this->dim = dim; + dimList.resize( this->dim, 1 ); + oriPoint.resize( this->dim, 0 ); +} + +DimInfo & DimInfo::operator = ( const DimInfo & rhs ) +{ + if ( this == & rhs ) return * this; + + this->dim = rhs.dim; + this->dimList = rhs.dimList; + this->oriPoint = rhs.oriPoint; + + return * this; +} + +int DimInfo::ComputeNumNodes() +{ + int nNodes = 1; + for ( int m = 0; m < this->dimList.size(); ++ m ) + { + nNodes *= this->dimList[ m ]; + } + return nNodes; +} + +void DimInfo::ComputeISize() +{ + int index_dim = this->dimList.size(); + this->isize.resize( index_dim * 3, 0 ); + for ( int m = 0; m < index_dim; ++ m ) + { + isize[ m ] = this->dimList[ m ]; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 1; + isize[ start + m ] = this->dimList[ m ] - 1; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 2; + isize[ start + m ] = 0; + } + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } +} + +void DimInfo::ComputeRminmax( std::vector & ref ) +{ + int index_dim = this->dimList.size(); + this->rmin.resize( index_dim ); + this->rmax.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + rmin[ m ] = ref[ m ] + 1; + rmax[ m ] = ref[ m ] + this->dimList[ m ]; + } + + std::cout << "rmin, rmax = \n"; + for ( int m = 0; m < index_dim; ++ m ) + { + std::cout << rmin[ m ] << " " << rmax[ m ] << "\n"; + } +} + +void DimInfo::Init( std::vector & dimList ) +{ + this->dim = dimList.size(); + this->dimList = dimList; + std::vector zero( dimList.size(), 0 ); + this->oriPoint = zero; +} + +void DimInfo::SetNewDimension( int axis, int newStart, int newWidth ) +{ + this->oriPoint[ axis ] = newStart; + this->dimList [ axis ] = newWidth; +} + +void DimInfo::GetZoneGlobalBox( RangeRegion &zoneBox ) +{ + int index_dim = this->dimList.size(); + zoneBox.start.resize( index_dim ); + zoneBox.end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + zoneBox.start[ m ] = this->oriPoint[ m ] + 1; + zoneBox.end[ m ] = this->oriPoint[ m ] + this->dimList[ m ]; + } +} + +void DimInfo::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + int index_dim = this->dimList.size(); + localBox.start.resize( index_dim ); + localBox.end.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + localBox.start[ m ] = globalBox.start[ m ] - this->oriPoint[ m ]; + localBox.end[ m ] = globalBox.end[ m ] - this->oriPoint[ m ]; + } +} + +RangeRegion::RangeRegion( int nSize ) +{ + this->Init( nSize ); +} + +RangeRegion::~RangeRegion() +{ +} + +void RangeRegion::Init( int nSize ) +{ + this->start.resize( nSize ); + this->end.resize( nSize ); +} + +RangeRegion & RangeRegion::operator = ( const RangeRegion & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +bool RangeRegion::operator == ( const RangeRegion & rhs ) const +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( this->start[ m ] != rhs.start[ m ] || + this->end [ m ] != rhs.end [ m ] ) + { + return false; + } + } + return true; +} + +void RangeRegion::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +bool RangeRegion::InRegion( const RangeRegion & region ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( ( this->start[ m ] < region.start[ m ] ) || ( this->end[ m ] > region.end[ m ] ) ) + { + return false; + } + } + return true; +} + +void RangeRegion::Normalize() +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + int minv = std::min( this->start[ m ], this->end[ m ] ); + int maxv = std::max( this->start[ m ], this->end[ m ] ); + this->start[ m ] = minv; + this->end[ m ] = maxv; + } +} + +void RangeRegion::Localize( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::ToGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] += oriPoint[ m ]; + this->end[ m ] += oriPoint[ m ]; + } +} + +void RangeRegion::ToLocal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::PrintGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + std::cout << "global start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "global end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +void RangeRegion::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"; +} + +bool CheckOverLapping( RangeRegion & overlapRegion ); + +bool ComputeOverlapRegion( RangeRegion & region1, RangeRegion & region2, RangeRegion & overlapRegion ) +{ + int index_dim = region1.start.size(); + overlapRegion.Init( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + int ijkmin1 = std::min( region1.start[ m ], region1.end[ m ] ); + int ijkmax1 = std::max( region1.start[ m ], region1.end[ m ] ); + int ijkmin2 = std::min( region2.start[ m ], region2.end[ m ] ); + int ijkmax2 = std::max( region2.start[ m ], region2.end[ m ] ); + if ( ( ijkmax1 < ijkmin2 ) || ( ijkmin1 > ijkmax2 ) ) + { + return false; + } + + int ijkmin = std::max( ijkmin1, ijkmin2 ); + int ijkmax = std::min( ijkmax1, ijkmax2 ); + + overlapRegion.start[ m ] = ijkmin; + overlapRegion.end [ m ] = ijkmax; + } + + return CheckOverLapping( overlapRegion ); +} + +bool CheckOverLapping( RangeRegion & overlapRegion ) +{ + int index_dim = overlapRegion.start.size(); + int iCount = 0; + for ( int m = 0; m < index_dim; ++ m ) + { + if ( overlapRegion.start[ m ] == overlapRegion.end[ m ] ) + { + ++ iCount; + } + } + + return ( iCount == 1 ); +} + +bool GetInterfaceRegion( RangeRegion & zoneBoxL, RangeRegion & zoneBoxR, RangeRegion & interfaceRegion ) +{ + int index_dim = zoneBoxL.start.size(); + int nDomains = 2 * index_dim; + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegionL; + GetDomainRegion( zoneBoxL, iDomain, domainRegionL ); + + for ( int jDomain = 0; jDomain < nDomains; ++ jDomain ) + { + RangeRegion domainRegionR; + GetDomainRegion( zoneBoxR, jDomain, domainRegionR ); + + if ( domainRegionL == domainRegionR ) + { + interfaceRegion = domainRegionL; + return true; + } + } + } + return false; +} + +void CreateInterfaceBc( SplitZone * zoneL, SplitZone * zoneR ) +{ + RangeRegion globalBoxL, globalBoxR, globalInterfaceRegion; + + zoneL->GetZoneGlobalBox( globalBoxL ); + zoneR->GetZoneGlobalBox( globalBoxR ); + + if ( ! GetInterfaceRegion( globalBoxL, globalBoxR, globalInterfaceRegion ) ) + { + return; + } + + RangeRegion localInterfaceRegionL, localInterfaceRegionR; + + zoneL->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionL ); + zoneR->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionR ); + + int kkk = 1; + + InterfaceSplitBc * interfaceSplitBcL = new InterfaceSplitBc(); + zoneL->interfaceSplitBcList.push_back( interfaceSplitBcL ); + interfaceSplitBcL->zone = zoneL; + interfaceSplitBcL->region = localInterfaceRegionL; + + int nSize = localInterfaceRegionL.start.size(); + + std::vector transform; + + for ( int m = 0; m < nSize; ++ m ) + { + transform.push_back( m + 1 ); + } + + interfaceSplitBcL->transform = transform; + interfaceSplitBcL->CalcTransformMatrix(); + + interfaceSplitBcL->donor_zone = zoneR; + interfaceSplitBcL->donor_region = localInterfaceRegionR; + + InterfaceSplitBc * interfaceSplitBcR = new InterfaceSplitBc(); + zoneR->interfaceSplitBcList.push_back( interfaceSplitBcR ); + + interfaceSplitBcR->zone = zoneR; + interfaceSplitBcR->region = localInterfaceRegionR; + + interfaceSplitBcR->transform = transform; + interfaceSplitBcR->CalcTransformMatrix(); + + interfaceSplitBcR->donor_zone = zoneL; + interfaceSplitBcR->donor_region = localInterfaceRegionL; +} + + +PhysicalSplitBc::PhysicalSplitBc() +{ + this->region.Init( Dim::dim ); +} + +PhysicalSplitBc::~PhysicalSplitBc() +{ +} + +void PhysicalSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void PhysicalSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +void PhysicalSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = splitZone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +BasicSplitBc::BasicSplitBc() +{ + this->region.Init( Dim::dim ); +} + +BasicSplitBc::~BasicSplitBc() +{ + ; +} + +void BasicSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void BasicSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +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; + } +} + +InterfaceInfo::InterfaceInfo() +{ + this->donor_region.Init( Dim::dim ); +} + +InterfaceInfo::~InterfaceInfo() +{ +} + +InterfaceSplitBc::InterfaceSplitBc() +{ + this->region.Init( Dim::dim ); + this->donor_region.Init( Dim::dim ); +} + +InterfaceSplitBc::~InterfaceSplitBc() +{ +} + +void InterfaceSplitBc::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nChild = this->child.size(); + if ( nChild == 0 ) + { + leafInterfaceBcList.push_back( this ); + } + else + { + for ( int iChild = 0; iChild < nChild; ++ iChild ) + { + InterfaceSplitBc * interfaceSplitBc = this->child[ iChild ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } + } +} + +void InterfaceSplitBc::CopyMatrix( InterfaceSplitBc * interfaceSplitBc ) +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = interfaceSplitBc->Mt[ i ][ j ]; + } + } +} + +void InterfaceSplitBc::CalcTransformMatrix() +{ + 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 InterfaceSplitBc::mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ) +{ + int dim = Dim::dim; + std::vector diff( dim ); + for ( int m = 0; m < dim; ++ m ) + { + diff[ m ] = index1[ m ] - begin1[ m ]; + } + + std::vector mul( dim ); + + Multiply( Mt, diff, mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = mul[ m ] + begin2[ m ]; + } +} + +void InterfaceSplitBc::Multiply( int Mt[][3], std::vector & a, std::vector & b ) +{ + int dim = Dim::dim; + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += Mt[ i ][ j ] * a[ j ]; + } + } +} + +void InterfaceSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = this->zone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +void InterfaceSplitBc::CalcSubDonorRegion( RangeRegion &subRegion, RangeRegion &subDonorRegion ) +{ + std::vector begin1 = this->region.start; + std::vector end1 = this->region.end; + std::vector begin2 = this->donor_region.start; + std::vector end2 = this->donor_region.end; + + std::vector new_begin1 = subRegion.start; + std::vector new_end1 = subRegion.end; + + int dim = Dim::dim; + std::vector new_begin2( dim ); + std::vector new_end2( dim ); + + mapindex( begin1, begin2, new_begin1, new_begin2 ); + mapindex( begin1, begin2, new_end1, new_end2 ); + + subDonorRegion.start = new_begin2; + subDonorRegion.end = new_end2; +} + +SplitZone::SplitZone() +{ + this->parent = 0; + this->zoneIndex = 0; + this->iProc = 0; + dimInfo.Init( Dim::dim ); + int kk = 1; +} + +SplitZone::~SplitZone() +{ + ; +} + +void SplitZone::GetZoneGlobalBox( RangeRegion & zoneBox ) +{ + this->dimInfo.GetZoneGlobalBox( zoneBox ); +} + +void SplitZone::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + this->dimInfo.GetZoneLocalBox( globalBox, localBox ); +} + + +void SplitZone::ComputeRminmax() +{ + int index_dim = this->dimInfo.dimList.size(); + std::vector ref( index_dim, 0 ); + + SplitZone * rootSplitZone = 0; + this->GetRootInfo( rootSplitZone, ref ); + + this->dimInfo.ComputeRminmax( ref ); +} + +SplitZone * SplitZone::GetRootZone() +{ + SplitZone * root = this; + + while ( true ) + { + if ( root->parent ) + { + root = root->parent; + } + else + { + return root; + } + }; +} + +void SplitZone::GetRootInfo( SplitZone *& root, std::vector & ref ) +{ + for ( int i = 0; i < this->dimInfo.dimList.size(); ++ i ) + { + ref[ i ] += this->dimInfo.oriPoint[ i ]; + } + + if ( this->parent ) + { + this->parent->GetRootInfo( root, ref ); + } + else + { + root = this; + } +} + +void SplitZone::SetParentAndChild( SplitZone * parent ) +{ + this->parent = parent; + if ( parent ) + { + parent->child.push_back( this ); + } +} + +void SplitZone::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nInterfaceBcs = this->interfaceSplitBcList.size(); + for ( int i = 0; i < nInterfaceBcs; ++ i ) + { + InterfaceSplitBc * interfaceSplitBc = this->interfaceSplitBcList[ i ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } +} + +int SplitZone::GetNCell() +{ + int numberOfCells = 1; + for ( int i = 0; i < this->dimInfo.dim; ++ i ) + { + numberOfCells *= std::max( 1, ( this->dimInfo.dimList[ i ] - 1 ) ); + } + + return numberOfCells; +} + +void SplitZone::SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int leftStart = 0; + int leftWidth = iSplit - 0; + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, leftStart , leftWidth ); +} + +void SplitZone::SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int rightStart = iSplit - 1; + int rightWidth = dimList[ axisNeedSplit ] - ( iSplit - 1 ); + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, rightStart, rightWidth ); +} + +void SplitZone::Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ) +{ + //Find the longest axis + int axisNeedSplit = this->FindAxisNeedSplit(); + int iSplit = this->FindSplitPosition( axisNeedSplit, nCell ); + + zoneL->SetLeftDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + zoneR->SetRightDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + + zoneL->CreateBcFromParent(); + zoneR->CreateBcFromParent(); + + CreateInterfaceBc( zoneL, zoneR ); +} + +void SplitZone::CreateBcFromParent() +{ + this->CreatePhysicalBcFromParent(); + this->CreateInterfaceBcFromParent(); +} + +void SplitZone::CreatePhysicalBcFromParent() +{ + int nParentPhysicalBcs = this->parent->physicalSplitBcList.size(); + + for ( int iParentPhysicalBcs = 0; iParentPhysicalBcs < nParentPhysicalBcs; ++ iParentPhysicalBcs ) + { + PhysicalSplitBc * parentPhysicalSplitBc = this->parent->physicalSplitBcList[ iParentPhysicalBcs ]; + + this->CreatePhysicalBcFromParent( parentPhysicalSplitBc ); + } +} + +void SplitZone::CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentPhysicalSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreatePhysicalBc( overlapRegion, parentPhysicalSplitBc->bcType ); + + int kkk = 1; + } +} + +void SplitZone::CreateInterfaceBcFromParent() +{ + int nInterfaceSplitBcs = this->parent->interfaceSplitBcList.size(); + + for ( int iInterfaceSplitBcs = 0; iInterfaceSplitBcs < nInterfaceSplitBcs; ++ iInterfaceSplitBcs ) + { + InterfaceSplitBc * parentInterfaceSplitBc = this->parent->interfaceSplitBcList[ iInterfaceSplitBcs ]; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc ); + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentInterfaceSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc, overlapRegion ); + + int kkk = 1; + } +} + +void SplitZone::FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ) +{ + RangeRegion donor_region = interfaceSplitBc->donor_region; + donor_region.Normalize(); + interfaceInfo.donor_zone = this; + for ( int iInterface = 0; iInterface < interfaceSplitBcList.size(); ++ iInterface ) + { + InterfaceSplitBc * candidateDonorBc = interfaceSplitBcList[ iInterface ]; + bool flag = donor_region.InRegion( candidateDonorBc->region ); + if ( flag ) + { + if ( donor_region == candidateDonorBc->region ) + { + interfaceInfo.donor_interface = candidateDonorBc; + return; + } + else + { + InterfaceSplitBc * donorBc = new InterfaceSplitBc(); + candidateDonorBc->child.push_back( donorBc ); + donorBc->region = donor_region; + donorBc->zone = candidateDonorBc->zone; + donorBc->donor_zone = interfaceSplitBc->zone; + donorBc->transform = candidateDonorBc->transform; + donorBc->CopyMatrix( candidateDonorBc ); + RangeRegion subDonorRegion( Dim::dim ); + candidateDonorBc->CalcSubDonorRegion( donorBc->region, subDonorRegion ); + std::vector & oriPoint = interfaceSplitBc->zone->dimInfo.oriPoint; + subDonorRegion.Localize( oriPoint ); + donorBc->donor_region = subDonorRegion; + donorBc->donor_bc = interfaceSplitBc; + interfaceInfo.donor_interface = donorBc; + return; + } + } + } + return; +} + +void SplitZone::GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ) +{ + std::cout << "subDonorRegion = \n"; + //subDonorRegion.Print(); + RangeRegion normalizedDonorRegion = subDonorRegion; + normalizedDonorRegion.Normalize(); + int nChild = this->child.size(); + for ( int ichild = 0; ichild < nChild; ++ ichild ) + { + std::cout << " iChild = " << ichild << " nChild = " << nChild << "\n"; + SplitZone * sub_zone = this->child[ ichild ]; + std::cout << " zoneIndex = " << sub_zone->zoneIndex << "\n"; + int nInters = sub_zone->interfaceSplitBcList.size(); + for ( int iInter = 0; iInter < nInters; ++ iInter ) + { + std::cout << " iInter = " << iInter << "\n"; + InterfaceSplitBc * interfaceSplitBc = sub_zone->interfaceSplitBcList[ iInter ]; + std::cout << "interfaceSplitBc local = \n"; + interfaceSplitBc->region.Print(); + std::cout << "interfaceSplitBc global = \n"; + interfaceSplitBc->region.PrintGlobal( sub_zone->dimInfo.oriPoint ); + RangeRegion g_region = interfaceSplitBc->region; + g_region.ToGlobal( sub_zone->dimInfo.oriPoint ); + if ( g_region == normalizedDonorRegion ) + { + RangeRegion donorRegion = subDonorRegion; + donorRegion.ToLocal( sub_zone->dimInfo.oriPoint ); + + interfaceInfo.donor_zone = sub_zone; + interfaceInfo.donor_interface = interfaceSplitBc; + interfaceInfo.donor_region = donorRegion; + return; + } + } + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ) +{ + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + this->interfaceSplitBcList.push_back( interfaceSplitBc ); + + interfaceSplitBc->region = overlapRegion; + interfaceSplitBc->zone = this; + interfaceSplitBc->transform = parentInterfaceSplitBc->transform; + interfaceSplitBc->CopyMatrix( parentInterfaceSplitBc ); + RangeRegion subDonorRegion( Dim::dim ); + parentInterfaceSplitBc->CalcSubDonorRegion( overlapRegion, subDonorRegion ); + interfaceSplitBc->ChangeRegionToLocalCoordinate(); + interfaceSplitBc->donor_region = subDonorRegion; + SplitZone * parent_donor_zone = parentInterfaceSplitBc->donor_zone; + std::cout << " parentInterfaceSplitBc->zone->zoneIndex " << parentInterfaceSplitBc->zone->zoneIndex << "\n"; + std::cout << " parentInterfaceSplitBc->donor_zone->zoneIndex " << parent_donor_zone->zoneIndex << "\n"; + if ( parent_donor_zone->child.size() > 0 ) + { + InterfaceInfo interfaceInfo; + parent_donor_zone->GetChildDonorRegion( subDonorRegion, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + interfaceSplitBc->donor_region = interfaceInfo.donor_region; + //compatibility + InterfaceSplitBc * donor_bc = interfaceSplitBc->donor_bc; + SplitZone * donor_zone = interfaceSplitBc->donor_zone; + if ( interfaceSplitBc->zone != donor_bc->donor_zone ) + { + if ( interfaceSplitBc->zone->parent == donor_bc->donor_zone ) + { + RangeRegion d_region = donor_bc->donor_region; + d_region.ToLocal( interfaceSplitBc->zone->dimInfo.oriPoint ); + donor_bc->donor_region = d_region; + } + donor_bc->donor_zone = interfaceSplitBc->zone; + + int kkk = 1; + } + int kkk = 1; + } + else + { + InterfaceInfo interfaceInfo; + parent_donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + + int kkk = 1; +} + +void SplitZone::CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ) +{ + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + this->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->SetRegion( overlapRegion ); + physicalSplitBc->bcType = bcType; + physicalSplitBc->splitZone = this; + physicalSplitBc->ChangeRegionToLocalCoordinate(); +} + +int SplitZone::FindAxisNeedSplit() +{ + //Find the longest axis + int axisNeedSplit = 0; + int maxN = this->dimInfo.dimList[ 0 ]; + + for ( int m = 1; m < this->dimInfo.dimList.size(); ++ m ) + { + if ( this->IsPoleBc( m ) ) + { + continue; + } + int Nm = this->dimInfo.dimList[ m ]; + if ( maxN < Nm ) + { + maxN = Nm; + axisNeedSplit = m; + } + } + + return axisNeedSplit; +} + +int SplitZone::GetCrossSection( int axis ) +{ + int nDim = this->dimInfo.dimList.size(); + int crossSection = 1; + int N = nDim - 1; + for ( int m = 0; m < N; ++ m ) + { + int mm = ( axis + 1 ) % nDim; + int nLineElements = std::max( 1, ( this->dimInfo.dimList[ mm ] - 1 ) ); + crossSection *= nLineElements; + } + return crossSection; +} + +int SplitZone::FindSplitPosition( int axisNeedSplit, double nCell ) +{ + int nDim = this->dimInfo.dimList.size(); + std::vector crossSections( nDim ); + for ( int m = 0; m < nDim; ++ m ) + { + crossSections[ m ] = this->GetCrossSection( m ); + } + + //guess the value + double dSplit = nCell / crossSections[ axisNeedSplit ]; + int iSplit = 1 + static_cast< int >( std::floor( dSplit + 0.5 ) ); + return iSplit; +} + + +bool SplitZone::IsPoleBc( int splitDirection ) +{ + return false; +} + diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.h b/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.h new file mode 100644 index 00000000..ffe1e306 --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/SplitZone.h @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include + +class Dim +{ +public: + static int dim; +}; + +class SplitZone; +class RangeRegion; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ); + +class DimInfo +{ +public: + DimInfo(); + ~DimInfo(); +public: + int dim; + std::vector dimList; + std::vector oriPoint; + std::vector isize; + std::vector rmin; + std::vector rmax; +public: + int GetSize() const { return dim; } + DimInfo & operator = ( const DimInfo & rhs ); +public: + int ComputeNumNodes(); + void ComputeISize(); + void ComputeRminmax( std::vector & ref ); + void Init( int dim ); + void Init( std::vector & dimList ); + void SetNewDimension( int axis, int newStart, int newWidth ); + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); +}; + +class SplitZone; +class SplitBcPatch; + +class RangeRegion +{ +public: + RangeRegion( int nSize = 1 ); + ~RangeRegion(); +public: + std::vector start; + std::vector end; +public: + void Init( int nSize ); + RangeRegion & operator = ( const RangeRegion & rhs ); + bool operator == ( const RangeRegion & rhs ) const; + bool InRegion( const RangeRegion & region ); + void SetRegion( std::vector &pnts ); + void Normalize(); + void Localize( std::vector & oriPoint ); + void ToGlobal( std::vector & oriPoint ); + void ToLocal( std::vector & oriPoint ); + void PrintGlobal( std::vector & oriPoint ); + void Print(); +}; + +class PhysicalSplitBc +{ +public: + PhysicalSplitBc(); + ~PhysicalSplitBc(); +public: + int bcType; + RangeRegion region; +public: + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector &pnts ); + void SetRegion( RangeRegion ®ion ); + void ChangeRegionToLocalCoordinate(); +}; + +class BasicSplitBc +{ +public: + BasicSplitBc(); + ~BasicSplitBc(); +public: + RangeRegion region; + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector & pnts ); + void SetRegion( RangeRegion & region ); +}; + +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 InterfaceSplitBc; +class SplitZone; + +class InterfaceInfo +{ +public: + InterfaceInfo(); + ~InterfaceInfo(); +public: + InterfaceSplitBc * donor_interface = nullptr; + SplitZone * donor_zone = nullptr; + RangeRegion donor_region; +}; + +class InterfaceSplitBc +{ +public: + InterfaceSplitBc(); + ~InterfaceSplitBc(); +public: + std::vector transform; + int Mt[ 3 ][ 3 ]; + RangeRegion region; + SplitZone * zone = nullptr; + RangeRegion donor_region; + SplitZone * donor_zone = nullptr; + InterfaceSplitBc * donor_bc = nullptr; +public: + std::vector child; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + void CopyMatrix( InterfaceSplitBc * interfaceSplitBc ); + void CalcTransformMatrix(); + void CalcSubDonorRegion( RangeRegion & subRegion, RangeRegion & subDonorRegion ); + void mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ); + void Multiply( int Mt[][ 3 ], std::vector & a, std::vector & b ); + void ChangeRegionToLocalCoordinate(); +}; + +class SplitZone +{ +public: + SplitZone(); + ~SplitZone(); +public: + DimInfo dimInfo; + int zoneIndex, iProc; + int newIndex; +protected: + SplitZone * parent; + std::vector child; +public: + std::vector< PhysicalSplitBc * > physicalSplitBcList; + std::vector< InterfaceSplitBc * > interfaceSplitBcList; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + int GetNCell(); + void ComputeRminmax(); + void GetRootInfo( SplitZone *& root, std::vector & ref ); + void SetZoneIndex( int zoneIndex ) { this->zoneIndex = zoneIndex; } + int GetZoneIndex() { return zoneIndex; } + void SetProcId( int iProc ) { this->iProc = iProc; } + void SetParent( SplitZone * parent ) { this->parent = parent; }; + void SetParentAndChild( SplitZone * parent ); + void FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ); + void GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ); +public: + void CreateBcFromParent(); + void CreatePhysicalBcFromParent(); + void CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ); + void CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ); + void CreateInterfaceBcFromParent(); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ); + + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); + SplitZone * GetRootZone(); +public: + void Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ); + void SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); + void SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); +private: + int FindAxisNeedSplit(); + int FindSplitPosition( int axisNeedSplit, double nCell ); + bool IsPoleBc( int splitDirection ); + int GetCrossSection( int axis ); +}; + diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/main.cpp b/example/partition/struct/1d-shock-tube/1to4blocks/01/main.cpp new file mode 100644 index 00000000..5da1de7c --- /dev/null +++ b/example/partition/struct/1d-shock-tube/1to4blocks/01/main.cpp @@ -0,0 +1,18 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include "Partition.h" +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + Partition * partition = new Partition(); + partition->Solve(); + delete partition; + + return 0; +} diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d1blocksv1.cgns b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d2blocks.cgns b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d4blocks.cgns b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/partition/struct/1d-shock-tube/1to4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/partition/struct/1d/1to2blocks/01/CMakeLists.txt b/example/partition/struct/1d/1to2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..74ceea7d --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.30) + +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 ) + +find_package(Eigen3 CONFIG REQUIRED) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +#list ( APPEND PRJ_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR} ) +list ( APPEND PRJ_LIBRARIES Eigen3::Eigen ) +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() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Partition.h Partition.cpp + CgnsGrid.h CgnsGrid.cpp + SplitZone.h SplitZone.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/partition/struct/1d/1to2blocks/01/CgnsGrid.cpp b/example/partition/struct/1d/1to2blocks/01/CgnsGrid.cpp new file mode 100644 index 00000000..dfe750bd --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/CgnsGrid.cpp @@ -0,0 +1,349 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include + +Grid::Grid() +{ + ; +} + +Grid::~Grid() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } +} + +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"; +} + +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 ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ + delete this->patch; +} + + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +ZoneBcPatch::ZoneBcPatch() +{ + ; +} + +ZoneBcPatch::~ZoneBcPatch() +{ +} + +std::vector Global::zones; +BaseZoneList Global::zone_names; +int Global::cell_dim = -1; +int Global::phys_dim = -1; + +Global::Global() +{ + ; +} + +Global::~Global() +{ +} + +void Global::FreeData() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } + zones.resize( 0 ); +} + + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + BaseZone baseZone; + //baseZone.baseId = baseId; + baseZone.zone_name = zonename; + + Global::zone_names.AddBaseZone( baseZone ); + } + } + cg_close( fileId ); +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + Zone * zone = new Zone(); + Global::zones.push_back( zone ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + + BaseZone baseZone; + baseZone.zone_name = zonename; + int gZoneId = Global::zone_names.FindBaseZone( baseZone ); + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + std::vector irmin( index_dim ); + std::vector irmax( index_dim ); + int nNodes = 1; + 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 ]; + zone->nijk.push_back( isize[ m ] ); + } + std::cout << "nNodes = " << nNodes << "\n"; + + ZoneType_t zoneType; + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[zoneType] << "\n"; + int ncoords = -1; + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + std::cout << "coordname = " << coordname << "\n"; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[dataType] << "\n"; + std::vector coord( nNodes * sizeof(double) ); + + Coor * coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord.resize( nNodes * sizeof( double ) ); + + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coor->coord.data() ); + coor->DumpCoor(); + } + + int nbocos = -1; + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + + ZoneBc * zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + std::vector normalIndex( index_dim, -1 ); + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + zonebc->bcType = bocotype; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[bocotype] << "\n"; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "ndataset = " << ndataset << "\n"; + + std::vector normalList( nNodes * iphysdim * sizeof( double ) ); + + std::vector pnts( npnts * index_dim ); + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + zonebc->pnts.push_back( pnts[ i ] ); + } + std::cout << "\n"; + + double * normal_d = reinterpret_cast( const_cast( normalList.data() ) ); + } + + int n1to1 = -1; + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + std::cout << "n1to1 = " << n1to1 << "\n"; + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + ZoneBc1To1 * zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range( npnts * index_dim ); + std::vector donor_range( npnts * index_dim ); + std::vector transform( index_dim ); + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + std::cout << "connectname = " << connectname << "\n"; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "range = \n"; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "donor_range = \n"; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + BaseZone baseZone; + baseZone.zone_name = donorname; + int gDonorZoneId = Global::zone_names.FindBaseZone( baseZone ); + + 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 ] ); + } + + int kkk = 1; + } + } + int kkk = 1; + } + int kkk = 1; + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/partition/struct/1d/1to2blocks/01/CgnsGrid.h b/example/partition/struct/1d/1to2blocks/01/CgnsGrid.h new file mode 100644 index 00000000..053c467b --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/CgnsGrid.h @@ -0,0 +1,140 @@ +#pragma once +#include +#include +#include + +class Grid; + +class Zone; + +class Grid +{ +public: + Grid(); + ~Grid(); +public: + int nZone; + std::vector x; + std::vector zones; +}; + + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); +}; + +class ZoneBc; +class ZoneBc1To1; + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class ZoneBcPatch; +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; + ZoneBcPatch * patch = nullptr; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + +class ZoneBcPatch +{ +public: + ZoneBcPatch(); + ~ZoneBcPatch(); +public: + int donor_zoneid; + std::vector transform; + std::vector donor_pnts; +}; + +class BaseZone +{ +public: + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + 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; + } +}; + +class Global +{ +public: + Global(); + ~Global(); +public: + static int cell_dim; + static int phys_dim; + static std::vector zones; + static BaseZoneList zone_names; +public: + static void FreeData(); +}; + +void ReadCgnsGrid( const std::string & filename ); +void ReadCgnsGridBaseZone( const std::string & filename ); \ No newline at end of file diff --git a/example/partition/struct/1d/1to2blocks/01/Partition.cpp b/example/partition/struct/1d/1to2blocks/01/Partition.cpp new file mode 100644 index 00000000..dab73fb6 --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/Partition.cpp @@ -0,0 +1,619 @@ +#include "Partition.h" +#include "CgnsGrid.h" +#include "SplitZone.h" +#include "cgnslib.h" +#include + +bool CmpSplitZone::operator() ( SplitZone * a, SplitZone * b ) const +{ + return a->zoneIndex < b->zoneIndex; +}; + + +double CalSumOfProcSpeed( std::vector & procSpeed ); +double CalSumOfProcSpeed( std::vector & procSpeed ) +{ + int nProc = procSpeed.size(); + double sumOfProcSpeed = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + sumOfProcSpeed += procSpeed[ iProc ]; + } + return sumOfProcSpeed; +} + +Partition::Partition() +{ + this->nProc = 2; + this->inputName = "../heat1d1blocksv1.cgns"; + this->outName = std::format( "../heat1d{}blocks.cgns", this->nProc ); +} + +Partition::~Partition() +{ + ; +} + +int Partition::GetMinValueIndex( double * data, int numberOfData ) +{ + double minValue = data[ 0 ]; + int minimumValueIndex = 0; + + for ( int iData = 1; iData < numberOfData; ++ iData ) + { + if ( minValue > data[ iData ] ) + { + minValue = data[ iData ]; + minimumValueIndex = iData; + } + } + return minimumValueIndex; +} + +int Partition::GetMinLoadProc() +{ + return this->GetMinValueIndex( this->timeProc.data(), this->nProc ); +} + +SplitZone * Partition::GetLargestZone() +{ + SplitZone * largestZone = 0; + + double nMaxCell = 0.0; + + for ( std::set< SplitZone * >::iterator iter = unsignedZoneGroup.begin(); iter != unsignedZoneGroup.end(); ++ iter ) + { + double nSize = ( * iter )->GetNCell(); + if ( nMaxCell < nSize ) + { + nMaxCell = nSize; + largestZone = * iter; + } + } + + return largestZone; +} + +void Partition::Solve() +{ + std::cout << "Partition::Split()\n"; + this->ReadGrid(); + this->Split(); + this->DumpPartitionedGridFile(); + this->FreeAllZones(); +} + +void Partition::ReadGrid() +{ + ReadCgnsGridBaseZone( this->inputName ); + ReadCgnsGrid( this->inputName ); + + this->nOriZone = ::Global::zones.size(); + Dim::dim = Global::cell_dim; + + std::cout << "numberOfBlocks = " << nOriZone << "\n"; + + this->refZone.resize( nOriZone ); + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = new SplitZone(); + refZone[ iZone ] = splitZone; + + splitZone->SetZoneIndex( iZone ); + splitZone->SetProcId( 0 ); + splitZone->SetParentAndChild( 0 ); + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + Zone * zone = ::Global::zones[ iZone ]; + + splitZone->dimInfo.dimList = zone->nijk; + + int nbccos = zone->bccos.size(); + std::cout << "nbccos = " << nbccos << "\n"; + + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zoneBc = zone->bccos[ ibcco ]; + + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + splitZone->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->bcType = zoneBc->bcType; + physicalSplitBc->SetRegion( zoneBc->pnts ); + physicalSplitBc->splitZone = splitZone; + } + + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * zoneBc1To1 = zone->bc1to1s[ ibc1to1 ]; + + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + splitZone->interfaceSplitBcList.push_back( interfaceSplitBc ); + interfaceSplitBc->zone = splitZone; + interfaceSplitBc->region.SetRegion( zoneBc1To1->pnts ); + + interfaceSplitBc->transform = zoneBc1To1->transform; + interfaceSplitBc->CalcTransformMatrix(); + + interfaceSplitBc->donor_zone = refZone[ zoneBc1To1->donor_zoneid ]; + interfaceSplitBc->donor_region.SetRegion( zoneBc1To1->donor_pnts ); + } + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + int nbc1to1s = splitZone->interfaceSplitBcList.size(); + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + InterfaceSplitBc * interfaceSplitBc = splitZone->interfaceSplitBcList[ ibc1to1 ]; + InterfaceInfo interfaceInfo; + interfaceSplitBc->donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + } +} + +void Partition::Split() +{ + this->InitSplit(); + this->BinarySplit(); + this->ModifyZoneIndex(); + int kkk = 1; +} + +void Partition::InitSplit() +{ + //nZone is the number of zones in the original grid + //nProc is not the number of blocks in the end, but the number of processes that need to be divided. + //This difference occurs because the structure grid can have many blocks per process. + + //this->nProc = nProc; + //this->nPhyBlocks = referenceBlock.size(); + //this->nZone = this->nPhyBlocks; + + //tj Computation time on processor j + //Nk Number of internal grid-cells for zone j + //aveFloatOp: Number of Real operations per gridcell + //Gj The set of blocks allocated to process j + //Pj Real operations per second for process j + + //The Greedy Load Balancing Algorithm + //1.Compute an "ideal" uniprocessor time, Tuni = sum ( Nk * aveFloatOp )/ sum( Pj ). + //2.Set the group of unassigned blocks, Gu, to contain all blocks. The number of blocks in Nu=M, where M is the total number of blocks in the mesh. + //3.Start all processors with a very small fictitious zone to get a start tj=delt aveFloatOp/Pj, where delt<<1 is the size of the very small fictious zone. + //This is used to find the fastest processor in a heterogeneous system, tj could otherwise be set to 0 in the homogeneous case. + this->aveFloatOp = 1.0; + this->delta = 1.0e-5; + this->procSpeed.resize( nProc ); + this->timeProc.resize( nProc ); + + this->nTZone = this->nOriZone; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + procSpeed[ iProc ] = 1.0; + } + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + timeProc[ iProc ] = delta * aveFloatOp / procSpeed[ iProc ]; + } + + double sumProcSpeed = CalSumOfProcSpeed( procSpeed ); + + double sumProcOp = 0.0; + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + sumProcOp += refZone[ iZone ]->GetNCell() * aveFloatOp; + } + + this->idealUniProcTime = sumProcOp / sumProcSpeed; + + this->eps = 0.05; + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + unsignedZoneGroup.insert( refZone[ iZone ] ); + } + + //Init zoneStorage + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + zoneStorage.insert( refZone[ iZone ] ); + } + + //Assign procSplitZone to each process + procSplitZone.resize( nProc ); + + this->minNumberCell = 1; + for ( int m = 0; m < Dim::dim; ++ m ) + { + this->minNumberCell *= 1; + } + + int kkk = 1; + +} + +void Partition::FreeAllZones() +{ + int iCount = 0; + for ( std::set < SplitZone * >::iterator iter = zoneStorage.begin(); iter != zoneStorage.end(); ++ iter ) + { + //cout << "iCount = " << iCount << "\n"; + ++ iCount; + delete * iter; + } +} + +int Partition::GetNZones( int iProc ) +{ + return this->procSplitZone[ iProc ].size(); +} + +SplitZone * Partition::GetSplitZone( int iProc, int zoneId ) +{ + return this->procSplitZone[ iProc ][ zoneId ]; +} + +void Partition::AddZoneToUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.insert( zone ); +} + +void Partition::RemoveZoneFromUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.erase( zone ); +} + +void Partition::AddZoneToProcess( int iProc, SplitZone * zone ) +{ + this->procSplitZone[ iProc ].push_back( zone ); +} + +void Partition::AddNewZone( SplitZone * zone ) +{ + zone->SetZoneIndex( nTZone ++ ); + + this->AddZoneToUnsignedGroup( zone ); + + this->zoneStorage.insert( zone ); +} + +SplitZone * Partition::Split( SplitZone * zone, double nCell ) +{ + SplitZone * zoneL = new SplitZone(); + zoneL->SetParentAndChild( zone ); + + SplitZone * zoneR = new SplitZone(); + zoneR->SetParentAndChild( zone ); + + //Remove the original block from the UnsignedGroup + this->RemoveZoneFromUnsignedGroup( zone ); + + this->AddNewZone( zoneL ); + this->AddNewZone( zoneR ); + + zone->Split( zoneL, zoneR, nCell ); + + return zoneL; +} + +void Partition::BinarySplit() +{ + while ( ! unsignedZoneGroup.empty() ) + { + std::cout << "number of unsigned zone = " << unsignedZoneGroup.size() << "\n"; + int iProc = this->GetMinLoadProc(); + + //Get the block with the largest number of grids and its size + SplitZone * largestZone = this->GetLargestZone(); + + double nMaxCell = largestZone->GetNCell(); + + double aveFloatOp = this->aveFloatOp; + double tau = timeProc[ iProc ] + nMaxCell * aveFloatOp / procSpeed[ iProc ]; + + //It seems that EPS is still necessary + //The idea here is as follows. For the candidate blocks which can be divided into blocks, + //if the difference between the target blocks and the candidate blocks is too wide, + //the binarySplit method is adopted. The binarySplit blocks do not directly join the process, + //but enter the next round of screening. + + if ( tau > idealUniProcTime * ( 1.0 + eps ) ) + { + double nRest = ( tau - idealUniProcTime ) * procSpeed[ iProc ] / aveFloatOp; + + double nTarget = nMaxCell - nRest; + if ( nRest > this->minNumberCell && nTarget > this->minNumberCell ) + { + //It is necessary to divide blocks only when a certain number of points are satisfied. + double nHalf = nMaxCell / 2.0; + nMaxCell = nTarget; + double ratio = nMaxCell / nRest; + double oRatio = 1.0 / ratio; + + if ( std::max( ratio, oRatio ) < 3.0 ) + { + int kkk = 1; + largestZone = this->Split( largestZone, nMaxCell ); + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + else + { + this->Split( largestZone, nHalf ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } +} + +void Partition::ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ) +{ + SplitZone * rootSplitZone = splitZone->GetRootZone(); + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + coord.resize( nNodes * sizeof(double) ); + + int index_dim = splitZone->dimInfo.dimList.size(); + Coor * coor = zone->coors[ icoord ]; + + double * xlocal = reinterpret_cast( const_cast( coord.data() ) ); + double * xglobal = reinterpret_cast( const_cast( coor->coord.data() ) ); + if ( index_dim == 1 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ i ]; + } + } + else if ( index_dim == 2 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + int jmin = splitZone->dimInfo.rmin[ 1 ] - 1; + int jmax = splitZone->dimInfo.rmax[ 1 ]; + int ni = rootSplitZone->dimInfo.dimList[ 0 ]; + int nj = rootSplitZone->dimInfo.dimList[ 1 ]; + for ( int j = jmin; j < jmax; ++ j ) + { + int jstride = j * ni; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ jstride + i ]; + } + } + } +} + +void Partition::DumpBc( SplitZone * splitZone ) +{ +} + +void Partition::DumpPartitionedGridFile() +{ + std::cout << "\n"; + std::cout << "DumpPartitionedGridFile -------------------------------" << "\n"; + std::cout << "\n"; + int fileId = -1; + std::string filename = this->outName; + int ierr = cg_open( filename.c_str(), CG_MODE_WRITE, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + + std::vector coordnames; + coordnames.push_back( "CoordinateX" ); + coordnames.push_back( "CoordinateY" ); + coordnames.push_back( "CoordinateZ" ); + + std::string basename = "Base"; + int baseId = -1; + int icelldim = Global::cell_dim; + int iphysdim = Global::phys_dim; + cg_base_write( fileId, basename.c_str(), icelldim, iphysdim, &baseId ); + + std::cout << "baseId = " << baseId << "\n"; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + int nZones = this->GetNZones( iProc ); + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + ZoneType_t zoneType = Structured; + + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + + int index_dim = splitZone->dimInfo.dimList.size(); + std::cout << "index_dim = " << index_dim << "\n"; + + splitZone->dimInfo.ComputeISize(); + + int isize_dim = index_dim * 3; + + std::vector isize( index_dim * 3, 0 ); + for ( int m = 0; m < isize_dim; ++ m ) + { + isize[ m ] = splitZone->dimInfo.isize[ m ]; + } + + int zoneId = -1; + + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + + std::string zonename = "Zone" + std::to_string( splitZone->newIndex ); + + cg_zone_write( fileId, baseId, zonename.c_str(), isize.data(), zoneType, &zoneId ); + + std::cout << "zoneId = " << zoneId << "\n"; + std::cout << "zonename = " << zonename << "\n"; + + splitZone->ComputeRminmax(); + + SplitZone * rootSplitZone = splitZone->GetRootZone(); + + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int ncoords = zone->coors.size(); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = -1; + DataType_t dataType = RealDouble; + std::string coordname = coordnames[ icoord ]; + Coor * coor = zone->coors[ icoord ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + std::vector coord; + ComputeCoor( splitZone, icoord, coord ); + + cg_coord_write( fileId, baseId, zoneId, dataType, coordname.c_str(), coord.data(), &coorId ); + + std::cout << "fileId = " << fileId << " baseId = " << baseId << " zoneId = " << zoneId << " coorId = " << coorId << "\n"; + } + + std::vector< PhysicalSplitBc * > &bccoList = splitZone->physicalSplitBcList; + + int nbocos = bccoList.size(); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = -1; + GridLocation_t location = Vertex; + + std::string boconame = "BC" + std::to_string( iboco + 1 ); + + PhysicalSplitBc * physicalSplitBc = bccoList[ iboco ]; + BCType_t bocotype = static_cast( physicalSplitBc->bcType ); + PointSetType_t ptset_type = PointRange; + cgsize_t npnts = 2; + std::vector pnts; + int nSize = physicalSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.end[ i ] ); + } + + cg_boco_write( fileId, baseId, zoneId, boconame.c_str(), bocotype, ptset_type, npnts, pnts.data(), & bccoId ); + } + + //std::vector< InterfaceSplitBc * > & bc1to1List = splitZone->interfaceSplitBcList; + std::vector< InterfaceSplitBc * > bc1to1List; + splitZone->GetLeafInterfaceBc( bc1to1List ); + + int n1to1 = bc1to1List.size(); + std::cout << "n1to1 = " << n1to1 << "\n"; + + std::vector itranfrm( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + itranfrm[ m ] = m + 1; + } + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int index_conn = -1; + + InterfaceSplitBc * interfaceSplitBc = bc1to1List[ i1to1 ]; + + std::vector pnts; + std::vector pntsdonor; + int nSize = interfaceSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.end[ i ] ); + } + + int nPatchSize = interfaceSplitBc->donor_region.start.size(); + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.start[ i ] ); + } + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.end[ i ] ); + } + int id = interfaceSplitBc->donor_zone->newIndex; + int oldZoneIndex = interfaceSplitBc->donor_zone->zoneIndex; + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + std::cout << "donor zone id = " << id << "\n"; + std::cout << "donor zone oldZoneIndex = " << oldZoneIndex << "\n"; + std::string donorname = "Zone" + std::to_string( id ); + std::string connectname = "Interface" + std::to_string( i1to1 ); + + std::cout << "donorname = " << donorname << "\n"; + std::cout << "connectname = " << connectname << "\n"; + + std::vector & itranfrm = interfaceSplitBc->transform; + + cg_1to1_write( fileId, baseId, zoneId, connectname.c_str(), donorname.c_str(), pnts.data(), pntsdonor.data(), itranfrm.data(), &index_conn ); + std::cout << "index_conn = " << index_conn << "\n"; + } + } + } + cg_close( fileId ); +} + +void Partition::ModifyZoneIndex() +{ + std::cout << "ModifyZoneIndex +++++++++++++++++++++++++ " << "\n"; + int globalZoneId = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + std::cout << "iProc = " << iProc << "\n"; + int nZones = this->GetNZones( iProc ); + std::cout << "nZones in Proc " << iProc << " = " << nZones << "\n"; + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + //splitZone->SetZoneIndex( globalZoneId++ ); + splitZone->newIndex = ( globalZoneId++ ); + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + } + } +} \ No newline at end of file diff --git a/example/partition/struct/1d/1to2blocks/01/Partition.h b/example/partition/struct/1d/1to2blocks/01/Partition.h new file mode 100644 index 00000000..8a4a9731 --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/Partition.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include +#include + +class SplitZone; + +struct CmpSplitZone +{ + bool operator() ( SplitZone * a, SplitZone * b ) const; +}; + +class Partition +{ +public: + Partition(); + ~Partition(); +protected: + std::set < SplitZone * > zoneStorage; + std::set < SplitZone *, CmpSplitZone > unsignedZoneGroup; + std::vector< SplitZone * > refZone; + std::vector< std::vector< SplitZone * > > procSplitZone; + std::vector procSpeed; + std::vector timeProc; + double aveFloatOp, delta; + double idealUniProcTime, eps; + int minNumberCell; + int nTZone; + int nOriZone; + int nProc; +public: + std::string inputName; + std::string outName; +public: + void Solve(); + void ReadGrid(); + void Split(); + void InitSplit(); + void BinarySplit(); + //void GreedySplit(); +public: + void AddNewZone( SplitZone * zone ); + void AddZoneToUnsignedGroup( SplitZone * zone ); + void RemoveZoneFromUnsignedGroup( SplitZone * zone ); + void AddZoneToProcess( int iProc, SplitZone * zone ); + void DumpPartitionedGridFile(); + void ModifyZoneIndex(); + void FreeAllZones(); + int GetNZones( int iProc ); + SplitZone * GetSplitZone( int iProc, int zoneId ); + void ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ); + void DumpBc( SplitZone * splitZone ); +private: + int GetMinValueIndex( double * data, int numberOfData ); + int GetMinLoadProc(); + SplitZone * GetLargestZone(); + SplitZone * Split( SplitZone * zone, double nCell ); +}; + diff --git a/example/partition/struct/1d/1to2blocks/01/README.txt b/example/partition/struct/1d/1to2blocks/01/README.txt new file mode 100644 index 00000000..13dc2f91 --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/README.txt @@ -0,0 +1 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. diff --git a/example/partition/struct/1d/1to2blocks/01/SplitZone.cpp b/example/partition/struct/1d/1to2blocks/01/SplitZone.cpp new file mode 100644 index 00000000..aef70754 --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/SplitZone.cpp @@ -0,0 +1,1091 @@ +#include "SplitZone.h" +#include "cgnslib.h" +#include + +int Dim::dim = -1; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ) +{ + domainBox.start = zoneBox.start; + domainBox.end = zoneBox.end; + + int axis = iDomain / 2; + int direction = iDomain % 2; + + if ( direction == 0 ) + { + domainBox.end[ axis ] = domainBox.start[ axis ]; + } + else if ( direction == 1 ) + { + domainBox.start[ axis ] = domainBox.end[ axis ]; + } +} + +DimInfo::DimInfo() +{ + this->Init( 1 ); +} + +DimInfo::~DimInfo() +{ +} + +void DimInfo::Init( int dim ) +{ + this->dim = dim; + dimList.resize( this->dim, 1 ); + oriPoint.resize( this->dim, 0 ); +} + +DimInfo & DimInfo::operator = ( const DimInfo & rhs ) +{ + if ( this == & rhs ) return * this; + + this->dim = rhs.dim; + this->dimList = rhs.dimList; + this->oriPoint = rhs.oriPoint; + + return * this; +} + +int DimInfo::ComputeNumNodes() +{ + int nNodes = 1; + for ( int m = 0; m < this->dimList.size(); ++ m ) + { + nNodes *= this->dimList[ m ]; + } + return nNodes; +} + +void DimInfo::ComputeISize() +{ + int index_dim = this->dimList.size(); + this->isize.resize( index_dim * 3, 0 ); + for ( int m = 0; m < index_dim; ++ m ) + { + isize[ m ] = this->dimList[ m ]; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 1; + isize[ start + m ] = this->dimList[ m ] - 1; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 2; + isize[ start + m ] = 0; + } + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } +} + +void DimInfo::ComputeRminmax( std::vector & ref ) +{ + int index_dim = this->dimList.size(); + this->rmin.resize( index_dim ); + this->rmax.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + rmin[ m ] = ref[ m ] + 1; + rmax[ m ] = ref[ m ] + this->dimList[ m ]; + } + + std::cout << "rmin, rmax = \n"; + for ( int m = 0; m < index_dim; ++ m ) + { + std::cout << rmin[ m ] << " " << rmax[ m ] << "\n"; + } +} + +void DimInfo::Init( std::vector & dimList ) +{ + this->dim = dimList.size(); + this->dimList = dimList; + std::vector zero( dimList.size(), 0 ); + this->oriPoint = zero; +} + +void DimInfo::SetNewDimension( int axis, int newStart, int newWidth ) +{ + this->oriPoint[ axis ] = newStart; + this->dimList [ axis ] = newWidth; +} + +void DimInfo::GetZoneGlobalBox( RangeRegion &zoneBox ) +{ + int index_dim = this->dimList.size(); + zoneBox.start.resize( index_dim ); + zoneBox.end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + zoneBox.start[ m ] = this->oriPoint[ m ] + 1; + zoneBox.end[ m ] = this->oriPoint[ m ] + this->dimList[ m ]; + } +} + +void DimInfo::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + int index_dim = this->dimList.size(); + localBox.start.resize( index_dim ); + localBox.end.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + localBox.start[ m ] = globalBox.start[ m ] - this->oriPoint[ m ]; + localBox.end[ m ] = globalBox.end[ m ] - this->oriPoint[ m ]; + } +} + +RangeRegion::RangeRegion( int nSize ) +{ + this->Init( nSize ); +} + +RangeRegion::~RangeRegion() +{ +} + +void RangeRegion::Init( int nSize ) +{ + this->start.resize( nSize ); + this->end.resize( nSize ); +} + +RangeRegion & RangeRegion::operator = ( const RangeRegion & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +bool RangeRegion::operator == ( const RangeRegion & rhs ) const +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( this->start[ m ] != rhs.start[ m ] || + this->end [ m ] != rhs.end [ m ] ) + { + return false; + } + } + return true; +} + +void RangeRegion::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +bool RangeRegion::InRegion( const RangeRegion & region ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( ( this->start[ m ] < region.start[ m ] ) || ( this->end[ m ] > region.end[ m ] ) ) + { + return false; + } + } + return true; +} + +void RangeRegion::Normalize() +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + int minv = std::min( this->start[ m ], this->end[ m ] ); + int maxv = std::max( this->start[ m ], this->end[ m ] ); + this->start[ m ] = minv; + this->end[ m ] = maxv; + } +} + +void RangeRegion::Localize( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::ToGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] += oriPoint[ m ]; + this->end[ m ] += oriPoint[ m ]; + } +} + +void RangeRegion::ToLocal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::PrintGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + std::cout << "global start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "global end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +void RangeRegion::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"; +} + +bool CheckOverLapping( RangeRegion & overlapRegion ); + +bool ComputeOverlapRegion( RangeRegion & region1, RangeRegion & region2, RangeRegion & overlapRegion ) +{ + int index_dim = region1.start.size(); + overlapRegion.Init( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + int ijkmin1 = std::min( region1.start[ m ], region1.end[ m ] ); + int ijkmax1 = std::max( region1.start[ m ], region1.end[ m ] ); + int ijkmin2 = std::min( region2.start[ m ], region2.end[ m ] ); + int ijkmax2 = std::max( region2.start[ m ], region2.end[ m ] ); + if ( ( ijkmax1 < ijkmin2 ) || ( ijkmin1 > ijkmax2 ) ) + { + return false; + } + + int ijkmin = std::max( ijkmin1, ijkmin2 ); + int ijkmax = std::min( ijkmax1, ijkmax2 ); + + overlapRegion.start[ m ] = ijkmin; + overlapRegion.end [ m ] = ijkmax; + } + + return CheckOverLapping( overlapRegion ); +} + +bool CheckOverLapping( RangeRegion & overlapRegion ) +{ + int index_dim = overlapRegion.start.size(); + int iCount = 0; + for ( int m = 0; m < index_dim; ++ m ) + { + if ( overlapRegion.start[ m ] == overlapRegion.end[ m ] ) + { + ++ iCount; + } + } + + return ( iCount == 1 ); +} + +bool GetInterfaceRegion( RangeRegion & zoneBoxL, RangeRegion & zoneBoxR, RangeRegion & interfaceRegion ) +{ + int index_dim = zoneBoxL.start.size(); + int nDomains = 2 * index_dim; + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegionL; + GetDomainRegion( zoneBoxL, iDomain, domainRegionL ); + + for ( int jDomain = 0; jDomain < nDomains; ++ jDomain ) + { + RangeRegion domainRegionR; + GetDomainRegion( zoneBoxR, jDomain, domainRegionR ); + + if ( domainRegionL == domainRegionR ) + { + interfaceRegion = domainRegionL; + return true; + } + } + } + return false; +} + +void CreateInterfaceBc( SplitZone * zoneL, SplitZone * zoneR ) +{ + RangeRegion globalBoxL, globalBoxR, globalInterfaceRegion; + + zoneL->GetZoneGlobalBox( globalBoxL ); + zoneR->GetZoneGlobalBox( globalBoxR ); + + if ( ! GetInterfaceRegion( globalBoxL, globalBoxR, globalInterfaceRegion ) ) + { + return; + } + + RangeRegion localInterfaceRegionL, localInterfaceRegionR; + + zoneL->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionL ); + zoneR->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionR ); + + int kkk = 1; + + InterfaceSplitBc * interfaceSplitBcL = new InterfaceSplitBc(); + zoneL->interfaceSplitBcList.push_back( interfaceSplitBcL ); + interfaceSplitBcL->zone = zoneL; + interfaceSplitBcL->region = localInterfaceRegionL; + + int nSize = localInterfaceRegionL.start.size(); + + std::vector transform; + + for ( int m = 0; m < nSize; ++ m ) + { + transform.push_back( m + 1 ); + } + + interfaceSplitBcL->transform = transform; + interfaceSplitBcL->CalcTransformMatrix(); + + interfaceSplitBcL->donor_zone = zoneR; + interfaceSplitBcL->donor_region = localInterfaceRegionR; + + InterfaceSplitBc * interfaceSplitBcR = new InterfaceSplitBc(); + zoneR->interfaceSplitBcList.push_back( interfaceSplitBcR ); + + interfaceSplitBcR->zone = zoneR; + interfaceSplitBcR->region = localInterfaceRegionR; + + interfaceSplitBcR->transform = transform; + interfaceSplitBcR->CalcTransformMatrix(); + + interfaceSplitBcR->donor_zone = zoneL; + interfaceSplitBcR->donor_region = localInterfaceRegionL; +} + + +PhysicalSplitBc::PhysicalSplitBc() +{ + this->region.Init( Dim::dim ); +} + +PhysicalSplitBc::~PhysicalSplitBc() +{ +} + +void PhysicalSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void PhysicalSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +void PhysicalSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = splitZone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +BasicSplitBc::BasicSplitBc() +{ + this->region.Init( Dim::dim ); +} + +BasicSplitBc::~BasicSplitBc() +{ + ; +} + +void BasicSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void BasicSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +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; + } +} + +InterfaceInfo::InterfaceInfo() +{ + this->donor_region.Init( Dim::dim ); +} + +InterfaceInfo::~InterfaceInfo() +{ +} + +InterfaceSplitBc::InterfaceSplitBc() +{ + this->region.Init( Dim::dim ); + this->donor_region.Init( Dim::dim ); +} + +InterfaceSplitBc::~InterfaceSplitBc() +{ +} + +void InterfaceSplitBc::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nChild = this->child.size(); + if ( nChild == 0 ) + { + leafInterfaceBcList.push_back( this ); + } + else + { + for ( int iChild = 0; iChild < nChild; ++ iChild ) + { + InterfaceSplitBc * interfaceSplitBc = this->child[ iChild ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } + } +} + +void InterfaceSplitBc::CopyMatrix( InterfaceSplitBc * interfaceSplitBc ) +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = interfaceSplitBc->Mt[ i ][ j ]; + } + } +} + +void InterfaceSplitBc::CalcTransformMatrix() +{ + 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 InterfaceSplitBc::mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ) +{ + int dim = Dim::dim; + std::vector diff( dim ); + for ( int m = 0; m < dim; ++ m ) + { + diff[ m ] = index1[ m ] - begin1[ m ]; + } + + std::vector mul( dim ); + + Multiply( Mt, diff, mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = mul[ m ] + begin2[ m ]; + } +} + +void InterfaceSplitBc::Multiply( int Mt[][3], std::vector & a, std::vector & b ) +{ + int dim = Dim::dim; + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += Mt[ i ][ j ] * a[ j ]; + } + } +} + +void InterfaceSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = this->zone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +void InterfaceSplitBc::CalcSubDonorRegion( RangeRegion &subRegion, RangeRegion &subDonorRegion ) +{ + std::vector begin1 = this->region.start; + std::vector end1 = this->region.end; + std::vector begin2 = this->donor_region.start; + std::vector end2 = this->donor_region.end; + + std::vector new_begin1 = subRegion.start; + std::vector new_end1 = subRegion.end; + + int dim = Dim::dim; + std::vector new_begin2( dim ); + std::vector new_end2( dim ); + + mapindex( begin1, begin2, new_begin1, new_begin2 ); + mapindex( begin1, begin2, new_end1, new_end2 ); + + subDonorRegion.start = new_begin2; + subDonorRegion.end = new_end2; +} + +SplitZone::SplitZone() +{ + this->parent = 0; + this->zoneIndex = 0; + this->iProc = 0; + dimInfo.Init( Dim::dim ); + int kk = 1; +} + +SplitZone::~SplitZone() +{ + ; +} + +void SplitZone::GetZoneGlobalBox( RangeRegion & zoneBox ) +{ + this->dimInfo.GetZoneGlobalBox( zoneBox ); +} + +void SplitZone::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + this->dimInfo.GetZoneLocalBox( globalBox, localBox ); +} + + +void SplitZone::ComputeRminmax() +{ + int index_dim = this->dimInfo.dimList.size(); + std::vector ref( index_dim, 0 ); + + SplitZone * rootSplitZone = 0; + this->GetRootInfo( rootSplitZone, ref ); + + this->dimInfo.ComputeRminmax( ref ); +} + +SplitZone * SplitZone::GetRootZone() +{ + SplitZone * root = this; + + while ( true ) + { + if ( root->parent ) + { + root = root->parent; + } + else + { + return root; + } + }; +} + +void SplitZone::GetRootInfo( SplitZone *& root, std::vector & ref ) +{ + for ( int i = 0; i < this->dimInfo.dimList.size(); ++ i ) + { + ref[ i ] += this->dimInfo.oriPoint[ i ]; + } + + if ( this->parent ) + { + this->parent->GetRootInfo( root, ref ); + } + else + { + root = this; + } +} + +void SplitZone::SetParentAndChild( SplitZone * parent ) +{ + this->parent = parent; + if ( parent ) + { + parent->child.push_back( this ); + } +} + +void SplitZone::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nInterfaceBcs = this->interfaceSplitBcList.size(); + for ( int i = 0; i < nInterfaceBcs; ++ i ) + { + InterfaceSplitBc * interfaceSplitBc = this->interfaceSplitBcList[ i ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } +} + +int SplitZone::GetNCell() +{ + int numberOfCells = 1; + for ( int i = 0; i < this->dimInfo.dim; ++ i ) + { + numberOfCells *= std::max( 1, ( this->dimInfo.dimList[ i ] - 1 ) ); + } + + return numberOfCells; +} + +void SplitZone::SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int leftStart = 0; + int leftWidth = iSplit - 0; + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, leftStart , leftWidth ); +} + +void SplitZone::SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int rightStart = iSplit - 1; + int rightWidth = dimList[ axisNeedSplit ] - ( iSplit - 1 ); + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, rightStart, rightWidth ); +} + +void SplitZone::Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ) +{ + //Find the longest axis + int axisNeedSplit = this->FindAxisNeedSplit(); + int iSplit = this->FindSplitPosition( axisNeedSplit, nCell ); + + zoneL->SetLeftDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + zoneR->SetRightDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + + zoneL->CreateBcFromParent(); + zoneR->CreateBcFromParent(); + + CreateInterfaceBc( zoneL, zoneR ); +} + +void SplitZone::CreateBcFromParent() +{ + this->CreatePhysicalBcFromParent(); + this->CreateInterfaceBcFromParent(); +} + +void SplitZone::CreatePhysicalBcFromParent() +{ + int nParentPhysicalBcs = this->parent->physicalSplitBcList.size(); + + for ( int iParentPhysicalBcs = 0; iParentPhysicalBcs < nParentPhysicalBcs; ++ iParentPhysicalBcs ) + { + PhysicalSplitBc * parentPhysicalSplitBc = this->parent->physicalSplitBcList[ iParentPhysicalBcs ]; + + this->CreatePhysicalBcFromParent( parentPhysicalSplitBc ); + } +} + +void SplitZone::CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentPhysicalSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreatePhysicalBc( overlapRegion, parentPhysicalSplitBc->bcType ); + + int kkk = 1; + } +} + +void SplitZone::CreateInterfaceBcFromParent() +{ + int nInterfaceSplitBcs = this->parent->interfaceSplitBcList.size(); + + for ( int iInterfaceSplitBcs = 0; iInterfaceSplitBcs < nInterfaceSplitBcs; ++ iInterfaceSplitBcs ) + { + InterfaceSplitBc * parentInterfaceSplitBc = this->parent->interfaceSplitBcList[ iInterfaceSplitBcs ]; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc ); + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentInterfaceSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc, overlapRegion ); + + int kkk = 1; + } +} + +void SplitZone::FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ) +{ + RangeRegion donor_region = interfaceSplitBc->donor_region; + donor_region.Normalize(); + interfaceInfo.donor_zone = this; + for ( int iInterface = 0; iInterface < interfaceSplitBcList.size(); ++ iInterface ) + { + InterfaceSplitBc * candidateDonorBc = interfaceSplitBcList[ iInterface ]; + bool flag = donor_region.InRegion( candidateDonorBc->region ); + if ( flag ) + { + if ( donor_region == candidateDonorBc->region ) + { + interfaceInfo.donor_interface = candidateDonorBc; + return; + } + else + { + InterfaceSplitBc * donorBc = new InterfaceSplitBc(); + candidateDonorBc->child.push_back( donorBc ); + donorBc->region = donor_region; + donorBc->zone = candidateDonorBc->zone; + donorBc->donor_zone = interfaceSplitBc->zone; + donorBc->transform = candidateDonorBc->transform; + donorBc->CopyMatrix( candidateDonorBc ); + RangeRegion subDonorRegion( Dim::dim ); + candidateDonorBc->CalcSubDonorRegion( donorBc->region, subDonorRegion ); + std::vector & oriPoint = interfaceSplitBc->zone->dimInfo.oriPoint; + subDonorRegion.Localize( oriPoint ); + donorBc->donor_region = subDonorRegion; + donorBc->donor_bc = interfaceSplitBc; + interfaceInfo.donor_interface = donorBc; + return; + } + } + } + return; +} + +void SplitZone::GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ) +{ + std::cout << "subDonorRegion = \n"; + //subDonorRegion.Print(); + RangeRegion normalizedDonorRegion = subDonorRegion; + normalizedDonorRegion.Normalize(); + int nChild = this->child.size(); + for ( int ichild = 0; ichild < nChild; ++ ichild ) + { + std::cout << " iChild = " << ichild << " nChild = " << nChild << "\n"; + SplitZone * sub_zone = this->child[ ichild ]; + std::cout << " zoneIndex = " << sub_zone->zoneIndex << "\n"; + int nInters = sub_zone->interfaceSplitBcList.size(); + for ( int iInter = 0; iInter < nInters; ++ iInter ) + { + std::cout << " iInter = " << iInter << "\n"; + InterfaceSplitBc * interfaceSplitBc = sub_zone->interfaceSplitBcList[ iInter ]; + std::cout << "interfaceSplitBc local = \n"; + interfaceSplitBc->region.Print(); + std::cout << "interfaceSplitBc global = \n"; + interfaceSplitBc->region.PrintGlobal( sub_zone->dimInfo.oriPoint ); + RangeRegion g_region = interfaceSplitBc->region; + g_region.ToGlobal( sub_zone->dimInfo.oriPoint ); + if ( g_region == normalizedDonorRegion ) + { + RangeRegion donorRegion = subDonorRegion; + donorRegion.ToLocal( sub_zone->dimInfo.oriPoint ); + + interfaceInfo.donor_zone = sub_zone; + interfaceInfo.donor_interface = interfaceSplitBc; + interfaceInfo.donor_region = donorRegion; + return; + } + } + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ) +{ + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + this->interfaceSplitBcList.push_back( interfaceSplitBc ); + + interfaceSplitBc->region = overlapRegion; + interfaceSplitBc->zone = this; + interfaceSplitBc->transform = parentInterfaceSplitBc->transform; + interfaceSplitBc->CopyMatrix( parentInterfaceSplitBc ); + RangeRegion subDonorRegion( Dim::dim ); + parentInterfaceSplitBc->CalcSubDonorRegion( overlapRegion, subDonorRegion ); + interfaceSplitBc->ChangeRegionToLocalCoordinate(); + interfaceSplitBc->donor_region = subDonorRegion; + SplitZone * parent_donor_zone = parentInterfaceSplitBc->donor_zone; + std::cout << " parentInterfaceSplitBc->zone->zoneIndex " << parentInterfaceSplitBc->zone->zoneIndex << "\n"; + std::cout << " parentInterfaceSplitBc->donor_zone->zoneIndex " << parent_donor_zone->zoneIndex << "\n"; + if ( parent_donor_zone->child.size() > 0 ) + { + InterfaceInfo interfaceInfo; + parent_donor_zone->GetChildDonorRegion( subDonorRegion, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + interfaceSplitBc->donor_region = interfaceInfo.donor_region; + //compatibility + InterfaceSplitBc * donor_bc = interfaceSplitBc->donor_bc; + SplitZone * donor_zone = interfaceSplitBc->donor_zone; + if ( interfaceSplitBc->zone != donor_bc->donor_zone ) + { + if ( interfaceSplitBc->zone->parent == donor_bc->donor_zone ) + { + RangeRegion d_region = donor_bc->donor_region; + d_region.ToLocal( interfaceSplitBc->zone->dimInfo.oriPoint ); + donor_bc->donor_region = d_region; + } + donor_bc->donor_zone = interfaceSplitBc->zone; + + int kkk = 1; + } + int kkk = 1; + } + else + { + InterfaceInfo interfaceInfo; + parent_donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + + int kkk = 1; +} + +void SplitZone::CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ) +{ + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + this->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->SetRegion( overlapRegion ); + physicalSplitBc->bcType = bcType; + physicalSplitBc->splitZone = this; + physicalSplitBc->ChangeRegionToLocalCoordinate(); +} + +int SplitZone::FindAxisNeedSplit() +{ + //Find the longest axis + int axisNeedSplit = 0; + int maxN = this->dimInfo.dimList[ 0 ]; + + for ( int m = 1; m < this->dimInfo.dimList.size(); ++ m ) + { + if ( this->IsPoleBc( m ) ) + { + continue; + } + int Nm = this->dimInfo.dimList[ m ]; + if ( maxN < Nm ) + { + maxN = Nm; + axisNeedSplit = m; + } + } + + return axisNeedSplit; +} + +int SplitZone::GetCrossSection( int axis ) +{ + int nDim = this->dimInfo.dimList.size(); + int crossSection = 1; + int N = nDim - 1; + for ( int m = 0; m < N; ++ m ) + { + int mm = ( axis + 1 ) % nDim; + int nLineElements = std::max( 1, ( this->dimInfo.dimList[ mm ] - 1 ) ); + crossSection *= nLineElements; + } + return crossSection; +} + +int SplitZone::FindSplitPosition( int axisNeedSplit, double nCell ) +{ + int nDim = this->dimInfo.dimList.size(); + std::vector crossSections( nDim ); + for ( int m = 0; m < nDim; ++ m ) + { + crossSections[ m ] = this->GetCrossSection( m ); + } + + //guess the value + double dSplit = nCell / crossSections[ axisNeedSplit ]; + int iSplit = 1 + static_cast< int >( std::floor( dSplit + 0.5 ) ); + return iSplit; +} + + +bool SplitZone::IsPoleBc( int splitDirection ) +{ + return false; +} + diff --git a/example/partition/struct/1d/1to2blocks/01/SplitZone.h b/example/partition/struct/1d/1to2blocks/01/SplitZone.h new file mode 100644 index 00000000..ffe1e306 --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/SplitZone.h @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include + +class Dim +{ +public: + static int dim; +}; + +class SplitZone; +class RangeRegion; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ); + +class DimInfo +{ +public: + DimInfo(); + ~DimInfo(); +public: + int dim; + std::vector dimList; + std::vector oriPoint; + std::vector isize; + std::vector rmin; + std::vector rmax; +public: + int GetSize() const { return dim; } + DimInfo & operator = ( const DimInfo & rhs ); +public: + int ComputeNumNodes(); + void ComputeISize(); + void ComputeRminmax( std::vector & ref ); + void Init( int dim ); + void Init( std::vector & dimList ); + void SetNewDimension( int axis, int newStart, int newWidth ); + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); +}; + +class SplitZone; +class SplitBcPatch; + +class RangeRegion +{ +public: + RangeRegion( int nSize = 1 ); + ~RangeRegion(); +public: + std::vector start; + std::vector end; +public: + void Init( int nSize ); + RangeRegion & operator = ( const RangeRegion & rhs ); + bool operator == ( const RangeRegion & rhs ) const; + bool InRegion( const RangeRegion & region ); + void SetRegion( std::vector &pnts ); + void Normalize(); + void Localize( std::vector & oriPoint ); + void ToGlobal( std::vector & oriPoint ); + void ToLocal( std::vector & oriPoint ); + void PrintGlobal( std::vector & oriPoint ); + void Print(); +}; + +class PhysicalSplitBc +{ +public: + PhysicalSplitBc(); + ~PhysicalSplitBc(); +public: + int bcType; + RangeRegion region; +public: + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector &pnts ); + void SetRegion( RangeRegion ®ion ); + void ChangeRegionToLocalCoordinate(); +}; + +class BasicSplitBc +{ +public: + BasicSplitBc(); + ~BasicSplitBc(); +public: + RangeRegion region; + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector & pnts ); + void SetRegion( RangeRegion & region ); +}; + +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 InterfaceSplitBc; +class SplitZone; + +class InterfaceInfo +{ +public: + InterfaceInfo(); + ~InterfaceInfo(); +public: + InterfaceSplitBc * donor_interface = nullptr; + SplitZone * donor_zone = nullptr; + RangeRegion donor_region; +}; + +class InterfaceSplitBc +{ +public: + InterfaceSplitBc(); + ~InterfaceSplitBc(); +public: + std::vector transform; + int Mt[ 3 ][ 3 ]; + RangeRegion region; + SplitZone * zone = nullptr; + RangeRegion donor_region; + SplitZone * donor_zone = nullptr; + InterfaceSplitBc * donor_bc = nullptr; +public: + std::vector child; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + void CopyMatrix( InterfaceSplitBc * interfaceSplitBc ); + void CalcTransformMatrix(); + void CalcSubDonorRegion( RangeRegion & subRegion, RangeRegion & subDonorRegion ); + void mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ); + void Multiply( int Mt[][ 3 ], std::vector & a, std::vector & b ); + void ChangeRegionToLocalCoordinate(); +}; + +class SplitZone +{ +public: + SplitZone(); + ~SplitZone(); +public: + DimInfo dimInfo; + int zoneIndex, iProc; + int newIndex; +protected: + SplitZone * parent; + std::vector child; +public: + std::vector< PhysicalSplitBc * > physicalSplitBcList; + std::vector< InterfaceSplitBc * > interfaceSplitBcList; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + int GetNCell(); + void ComputeRminmax(); + void GetRootInfo( SplitZone *& root, std::vector & ref ); + void SetZoneIndex( int zoneIndex ) { this->zoneIndex = zoneIndex; } + int GetZoneIndex() { return zoneIndex; } + void SetProcId( int iProc ) { this->iProc = iProc; } + void SetParent( SplitZone * parent ) { this->parent = parent; }; + void SetParentAndChild( SplitZone * parent ); + void FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ); + void GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ); +public: + void CreateBcFromParent(); + void CreatePhysicalBcFromParent(); + void CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ); + void CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ); + void CreateInterfaceBcFromParent(); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ); + + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); + SplitZone * GetRootZone(); +public: + void Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ); + void SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); + void SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); +private: + int FindAxisNeedSplit(); + int FindSplitPosition( int axisNeedSplit, double nCell ); + bool IsPoleBc( int splitDirection ); + int GetCrossSection( int axis ); +}; + diff --git a/example/partition/struct/1d/1to2blocks/01/heat1d1blocksv1.cgns b/example/partition/struct/1d/1to2blocks/01/heat1d1blocksv1.cgns new file mode 100644 index 00000000..1d0a3fb2 Binary files /dev/null and b/example/partition/struct/1d/1to2blocks/01/heat1d1blocksv1.cgns differ diff --git a/example/partition/struct/1d/1to2blocks/01/heat1d2blocks.cgns b/example/partition/struct/1d/1to2blocks/01/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/partition/struct/1d/1to2blocks/01/heat1d2blocks.cgns differ diff --git a/example/partition/struct/1d/1to2blocks/01/main.cpp b/example/partition/struct/1d/1to2blocks/01/main.cpp new file mode 100644 index 00000000..5da1de7c --- /dev/null +++ b/example/partition/struct/1d/1to2blocks/01/main.cpp @@ -0,0 +1,18 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include "Partition.h" +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + Partition * partition = new Partition(); + partition->Solve(); + delete partition; + + return 0; +} diff --git a/example/partition/struct/1d/1to4blocks/02/CMakeLists.txt b/example/partition/struct/1d/1to4blocks/02/CMakeLists.txt new file mode 100644 index 00000000..74ceea7d --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.30) + +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 ) + +find_package(Eigen3 CONFIG REQUIRED) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +#list ( APPEND PRJ_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIR} ) +list ( APPEND PRJ_LIBRARIES Eigen3::Eigen ) +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() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Partition.h Partition.cpp + CgnsGrid.h CgnsGrid.cpp + SplitZone.h SplitZone.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/partition/struct/1d/1to4blocks/02/CgnsGrid.cpp b/example/partition/struct/1d/1to4blocks/02/CgnsGrid.cpp new file mode 100644 index 00000000..dfe750bd --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/CgnsGrid.cpp @@ -0,0 +1,349 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include + +Grid::Grid() +{ + ; +} + +Grid::~Grid() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } +} + +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"; +} + +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 ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ + delete this->patch; +} + + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +ZoneBcPatch::ZoneBcPatch() +{ + ; +} + +ZoneBcPatch::~ZoneBcPatch() +{ +} + +std::vector Global::zones; +BaseZoneList Global::zone_names; +int Global::cell_dim = -1; +int Global::phys_dim = -1; + +Global::Global() +{ + ; +} + +Global::~Global() +{ +} + +void Global::FreeData() +{ + for ( int i = 0; i < zones.size(); ++ i ) + { + delete zones[ i ]; + } + zones.resize( 0 ); +} + + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + BaseZone baseZone; + //baseZone.baseId = baseId; + baseZone.zone_name = zonename; + + Global::zone_names.AddBaseZone( baseZone ); + } + } + cg_close( fileId ); +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + int nbases = -1; + cg_nbases( fileId, &nbases ); + 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; + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + int nzones = -1; + cg_nzones( fileId, baseId, &nzones ); + std::cout << "nzones = " << nzones << "\n"; + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + Zone * zone = new Zone(); + Global::zones.push_back( zone ); + + char zonename[33]; + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + + BaseZone baseZone; + baseZone.zone_name = zonename; + int gZoneId = Global::zone_names.FindBaseZone( baseZone ); + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } + + std::vector irmin( index_dim ); + std::vector irmax( index_dim ); + int nNodes = 1; + 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 ]; + zone->nijk.push_back( isize[ m ] ); + } + std::cout << "nNodes = " << nNodes << "\n"; + + ZoneType_t zoneType; + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[zoneType] << "\n"; + int ncoords = -1; + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + std::cout << "coordname = " << coordname << "\n"; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[dataType] << "\n"; + std::vector coord( nNodes * sizeof(double) ); + + Coor * coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord.resize( nNodes * sizeof( double ) ); + + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coor->coord.data() ); + coor->DumpCoor(); + } + + int nbocos = -1; + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + + ZoneBc * zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + std::vector normalIndex( index_dim, -1 ); + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + zonebc->bcType = bocotype; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[bocotype] << "\n"; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "ndataset = " << ndataset << "\n"; + + std::vector normalList( nNodes * iphysdim * sizeof( double ) ); + + std::vector pnts( npnts * index_dim ); + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + zonebc->pnts.push_back( pnts[ i ] ); + } + std::cout << "\n"; + + double * normal_d = reinterpret_cast( const_cast( normalList.data() ) ); + } + + int n1to1 = -1; + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + std::cout << "n1to1 = " << n1to1 << "\n"; + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + ZoneBc1To1 * zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range( npnts * index_dim ); + std::vector donor_range( npnts * index_dim ); + std::vector transform( index_dim ); + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + std::cout << "connectname = " << connectname << "\n"; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "range = \n"; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "donor_range = \n"; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + BaseZone baseZone; + baseZone.zone_name = donorname; + int gDonorZoneId = Global::zone_names.FindBaseZone( baseZone ); + + 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 ] ); + } + + int kkk = 1; + } + } + int kkk = 1; + } + int kkk = 1; + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/partition/struct/1d/1to4blocks/02/CgnsGrid.h b/example/partition/struct/1d/1to4blocks/02/CgnsGrid.h new file mode 100644 index 00000000..053c467b --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/CgnsGrid.h @@ -0,0 +1,140 @@ +#pragma once +#include +#include +#include + +class Grid; + +class Zone; + +class Grid +{ +public: + Grid(); + ~Grid(); +public: + int nZone; + std::vector x; + std::vector zones; +}; + + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); +}; + +class ZoneBc; +class ZoneBc1To1; + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class ZoneBcPatch; +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; + ZoneBcPatch * patch = nullptr; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + +class ZoneBcPatch +{ +public: + ZoneBcPatch(); + ~ZoneBcPatch(); +public: + int donor_zoneid; + std::vector transform; + std::vector donor_pnts; +}; + +class BaseZone +{ +public: + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + 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; + } +}; + +class Global +{ +public: + Global(); + ~Global(); +public: + static int cell_dim; + static int phys_dim; + static std::vector zones; + static BaseZoneList zone_names; +public: + static void FreeData(); +}; + +void ReadCgnsGrid( const std::string & filename ); +void ReadCgnsGridBaseZone( const std::string & filename ); \ No newline at end of file diff --git a/example/partition/struct/1d/1to4blocks/02/Partition.cpp b/example/partition/struct/1d/1to4blocks/02/Partition.cpp new file mode 100644 index 00000000..0d53a3d8 --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/Partition.cpp @@ -0,0 +1,619 @@ +#include "Partition.h" +#include "CgnsGrid.h" +#include "SplitZone.h" +#include "cgnslib.h" +#include + +bool CmpSplitZone::operator() ( SplitZone * a, SplitZone * b ) const +{ + return a->zoneIndex < b->zoneIndex; +}; + + +double CalSumOfProcSpeed( std::vector & procSpeed ); +double CalSumOfProcSpeed( std::vector & procSpeed ) +{ + int nProc = procSpeed.size(); + double sumOfProcSpeed = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + sumOfProcSpeed += procSpeed[ iProc ]; + } + return sumOfProcSpeed; +} + +Partition::Partition() +{ + this->nProc = 4; + this->inputName = "../heat1d1blocksv1.cgns"; + this->outName = std::format( "../heat1d{}blocks.cgns", this->nProc ); +} + +Partition::~Partition() +{ + ; +} + +int Partition::GetMinValueIndex( double * data, int numberOfData ) +{ + double minValue = data[ 0 ]; + int minimumValueIndex = 0; + + for ( int iData = 1; iData < numberOfData; ++ iData ) + { + if ( minValue > data[ iData ] ) + { + minValue = data[ iData ]; + minimumValueIndex = iData; + } + } + return minimumValueIndex; +} + +int Partition::GetMinLoadProc() +{ + return this->GetMinValueIndex( this->timeProc.data(), this->nProc ); +} + +SplitZone * Partition::GetLargestZone() +{ + SplitZone * largestZone = 0; + + double nMaxCell = 0.0; + + for ( std::set< SplitZone * >::iterator iter = unsignedZoneGroup.begin(); iter != unsignedZoneGroup.end(); ++ iter ) + { + double nSize = ( * iter )->GetNCell(); + if ( nMaxCell < nSize ) + { + nMaxCell = nSize; + largestZone = * iter; + } + } + + return largestZone; +} + +void Partition::Solve() +{ + std::cout << "Partition::Split()\n"; + this->ReadGrid(); + this->Split(); + this->DumpPartitionedGridFile(); + this->FreeAllZones(); +} + +void Partition::ReadGrid() +{ + ReadCgnsGridBaseZone( this->inputName ); + ReadCgnsGrid( this->inputName ); + + this->nOriZone = ::Global::zones.size(); + Dim::dim = Global::cell_dim; + + std::cout << "numberOfBlocks = " << nOriZone << "\n"; + + this->refZone.resize( nOriZone ); + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = new SplitZone(); + refZone[ iZone ] = splitZone; + + splitZone->SetZoneIndex( iZone ); + splitZone->SetProcId( 0 ); + splitZone->SetParentAndChild( 0 ); + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + Zone * zone = ::Global::zones[ iZone ]; + + splitZone->dimInfo.dimList = zone->nijk; + + int nbccos = zone->bccos.size(); + std::cout << "nbccos = " << nbccos << "\n"; + + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zoneBc = zone->bccos[ ibcco ]; + + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + splitZone->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->bcType = zoneBc->bcType; + physicalSplitBc->SetRegion( zoneBc->pnts ); + physicalSplitBc->splitZone = splitZone; + } + + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * zoneBc1To1 = zone->bc1to1s[ ibc1to1 ]; + + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + splitZone->interfaceSplitBcList.push_back( interfaceSplitBc ); + interfaceSplitBc->zone = splitZone; + interfaceSplitBc->region.SetRegion( zoneBc1To1->pnts ); + + interfaceSplitBc->transform = zoneBc1To1->transform; + interfaceSplitBc->CalcTransformMatrix(); + + interfaceSplitBc->donor_zone = refZone[ zoneBc1To1->donor_zoneid ]; + interfaceSplitBc->donor_region.SetRegion( zoneBc1To1->donor_pnts ); + } + } + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + SplitZone * splitZone = refZone[ iZone ]; + + int nbc1to1s = splitZone->interfaceSplitBcList.size(); + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + InterfaceSplitBc * interfaceSplitBc = splitZone->interfaceSplitBcList[ ibc1to1 ]; + InterfaceInfo interfaceInfo; + interfaceSplitBc->donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + } +} + +void Partition::Split() +{ + this->InitSplit(); + this->BinarySplit(); + this->ModifyZoneIndex(); + int kkk = 1; +} + +void Partition::InitSplit() +{ + //nZone is the number of zones in the original grid + //nProc is not the number of blocks in the end, but the number of processes that need to be divided. + //This difference occurs because the structure grid can have many blocks per process. + + //this->nProc = nProc; + //this->nPhyBlocks = referenceBlock.size(); + //this->nZone = this->nPhyBlocks; + + //tj Computation time on processor j + //Nk Number of internal grid-cells for zone j + //aveFloatOp: Number of Real operations per gridcell + //Gj The set of blocks allocated to process j + //Pj Real operations per second for process j + + //The Greedy Load Balancing Algorithm + //1.Compute an "ideal" uniprocessor time, Tuni = sum ( Nk * aveFloatOp )/ sum( Pj ). + //2.Set the group of unassigned blocks, Gu, to contain all blocks. The number of blocks in Nu=M, where M is the total number of blocks in the mesh. + //3.Start all processors with a very small fictitious zone to get a start tj=delt aveFloatOp/Pj, where delt<<1 is the size of the very small fictious zone. + //This is used to find the fastest processor in a heterogeneous system, tj could otherwise be set to 0 in the homogeneous case. + this->aveFloatOp = 1.0; + this->delta = 1.0e-5; + this->procSpeed.resize( nProc ); + this->timeProc.resize( nProc ); + + this->nTZone = this->nOriZone; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + procSpeed[ iProc ] = 1.0; + } + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + timeProc[ iProc ] = delta * aveFloatOp / procSpeed[ iProc ]; + } + + double sumProcSpeed = CalSumOfProcSpeed( procSpeed ); + + double sumProcOp = 0.0; + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + sumProcOp += refZone[ iZone ]->GetNCell() * aveFloatOp; + } + + this->idealUniProcTime = sumProcOp / sumProcSpeed; + + this->eps = 0.05; + + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + unsignedZoneGroup.insert( refZone[ iZone ] ); + } + + //Init zoneStorage + for ( int iZone = 0; iZone < nOriZone; ++ iZone ) + { + zoneStorage.insert( refZone[ iZone ] ); + } + + //Assign procSplitZone to each process + procSplitZone.resize( nProc ); + + this->minNumberCell = 1; + for ( int m = 0; m < Dim::dim; ++ m ) + { + this->minNumberCell *= 1; + } + + int kkk = 1; + +} + +void Partition::FreeAllZones() +{ + int iCount = 0; + for ( std::set < SplitZone * >::iterator iter = zoneStorage.begin(); iter != zoneStorage.end(); ++ iter ) + { + //cout << "iCount = " << iCount << "\n"; + ++ iCount; + delete * iter; + } +} + +int Partition::GetNZones( int iProc ) +{ + return this->procSplitZone[ iProc ].size(); +} + +SplitZone * Partition::GetSplitZone( int iProc, int zoneId ) +{ + return this->procSplitZone[ iProc ][ zoneId ]; +} + +void Partition::AddZoneToUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.insert( zone ); +} + +void Partition::RemoveZoneFromUnsignedGroup( SplitZone * zone ) +{ + this->unsignedZoneGroup.erase( zone ); +} + +void Partition::AddZoneToProcess( int iProc, SplitZone * zone ) +{ + this->procSplitZone[ iProc ].push_back( zone ); +} + +void Partition::AddNewZone( SplitZone * zone ) +{ + zone->SetZoneIndex( nTZone ++ ); + + this->AddZoneToUnsignedGroup( zone ); + + this->zoneStorage.insert( zone ); +} + +SplitZone * Partition::Split( SplitZone * zone, double nCell ) +{ + SplitZone * zoneL = new SplitZone(); + zoneL->SetParentAndChild( zone ); + + SplitZone * zoneR = new SplitZone(); + zoneR->SetParentAndChild( zone ); + + //Remove the original block from the UnsignedGroup + this->RemoveZoneFromUnsignedGroup( zone ); + + this->AddNewZone( zoneL ); + this->AddNewZone( zoneR ); + + zone->Split( zoneL, zoneR, nCell ); + + return zoneL; +} + +void Partition::BinarySplit() +{ + while ( ! unsignedZoneGroup.empty() ) + { + std::cout << "number of unsigned zone = " << unsignedZoneGroup.size() << "\n"; + int iProc = this->GetMinLoadProc(); + + //Get the block with the largest number of grids and its size + SplitZone * largestZone = this->GetLargestZone(); + + double nMaxCell = largestZone->GetNCell(); + + double aveFloatOp = this->aveFloatOp; + double tau = timeProc[ iProc ] + nMaxCell * aveFloatOp / procSpeed[ iProc ]; + + //It seems that EPS is still necessary + //The idea here is as follows. For the candidate blocks which can be divided into blocks, + //if the difference between the target blocks and the candidate blocks is too wide, + //the binarySplit method is adopted. The binarySplit blocks do not directly join the process, + //but enter the next round of screening. + + if ( tau > idealUniProcTime * ( 1.0 + eps ) ) + { + double nRest = ( tau - idealUniProcTime ) * procSpeed[ iProc ] / aveFloatOp; + + double nTarget = nMaxCell - nRest; + if ( nRest > this->minNumberCell && nTarget > this->minNumberCell ) + { + //It is necessary to divide blocks only when a certain number of points are satisfied. + double nHalf = nMaxCell / 2.0; + nMaxCell = nTarget; + double ratio = nMaxCell / nRest; + double oRatio = 1.0 / ratio; + + if ( std::max( ratio, oRatio ) < 3.0 ) + { + int kkk = 1; + largestZone = this->Split( largestZone, nMaxCell ); + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + else + { + this->Split( largestZone, nHalf ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } + else + { + //If the block is of the right size, join the process directly, and there is no need to split it. + timeProc[ iProc ] += nMaxCell * aveFloatOp / procSpeed[ iProc ]; + this->RemoveZoneFromUnsignedGroup( largestZone ); + this->AddZoneToProcess( iProc, largestZone ); + } + } +} + +void Partition::ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ) +{ + SplitZone * rootSplitZone = splitZone->GetRootZone(); + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + coord.resize( nNodes * sizeof(double) ); + + int index_dim = splitZone->dimInfo.dimList.size(); + Coor * coor = zone->coors[ icoord ]; + + double * xlocal = reinterpret_cast( const_cast( coord.data() ) ); + double * xglobal = reinterpret_cast( const_cast( coor->coord.data() ) ); + if ( index_dim == 1 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ i ]; + } + } + else if ( index_dim == 2 ) + { + int icount = 0; + int imin = splitZone->dimInfo.rmin[ 0 ] - 1; + int imax = splitZone->dimInfo.rmax[ 0 ]; + int jmin = splitZone->dimInfo.rmin[ 1 ] - 1; + int jmax = splitZone->dimInfo.rmax[ 1 ]; + int ni = rootSplitZone->dimInfo.dimList[ 0 ]; + int nj = rootSplitZone->dimInfo.dimList[ 1 ]; + for ( int j = jmin; j < jmax; ++ j ) + { + int jstride = j * ni; + for ( int i = imin; i < imax; ++ i ) + { + xlocal[ icount++ ] = xglobal[ jstride + i ]; + } + } + } +} + +void Partition::DumpBc( SplitZone * splitZone ) +{ +} + +void Partition::DumpPartitionedGridFile() +{ + std::cout << "\n"; + std::cout << "DumpPartitionedGridFile -------------------------------" << "\n"; + std::cout << "\n"; + int fileId = -1; + std::string filename = this->outName; + int ierr = cg_open( filename.c_str(), CG_MODE_WRITE, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + + std::vector coordnames; + coordnames.push_back( "CoordinateX" ); + coordnames.push_back( "CoordinateY" ); + coordnames.push_back( "CoordinateZ" ); + + std::string basename = "Base"; + int baseId = -1; + int icelldim = Global::cell_dim; + int iphysdim = Global::phys_dim; + cg_base_write( fileId, basename.c_str(), icelldim, iphysdim, &baseId ); + + std::cout << "baseId = " << baseId << "\n"; + + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + int nZones = this->GetNZones( iProc ); + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + ZoneType_t zoneType = Structured; + + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + + int index_dim = splitZone->dimInfo.dimList.size(); + std::cout << "index_dim = " << index_dim << "\n"; + + splitZone->dimInfo.ComputeISize(); + + int isize_dim = index_dim * 3; + + std::vector isize( index_dim * 3, 0 ); + for ( int m = 0; m < isize_dim; ++ m ) + { + isize[ m ] = splitZone->dimInfo.isize[ m ]; + } + + int zoneId = -1; + + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + + std::string zonename = "Zone" + std::to_string( splitZone->newIndex ); + + cg_zone_write( fileId, baseId, zonename.c_str(), isize.data(), zoneType, &zoneId ); + + std::cout << "zoneId = " << zoneId << "\n"; + std::cout << "zonename = " << zonename << "\n"; + + splitZone->ComputeRminmax(); + + SplitZone * rootSplitZone = splitZone->GetRootZone(); + + Zone * zone = Global::zones[ rootSplitZone->zoneIndex ]; + + int ncoords = zone->coors.size(); + std::cout << "ncoords = " << ncoords << "\n"; + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = -1; + DataType_t dataType = RealDouble; + std::string coordname = coordnames[ icoord ]; + Coor * coor = zone->coors[ icoord ]; + + int nNodes = splitZone->dimInfo.ComputeNumNodes(); + std::cout << "nNodes = " << nNodes << "\n"; + + std::vector coord; + ComputeCoor( splitZone, icoord, coord ); + + cg_coord_write( fileId, baseId, zoneId, dataType, coordname.c_str(), coord.data(), &coorId ); + + std::cout << "fileId = " << fileId << " baseId = " << baseId << " zoneId = " << zoneId << " coorId = " << coorId << "\n"; + } + + std::vector< PhysicalSplitBc * > &bccoList = splitZone->physicalSplitBcList; + + int nbocos = bccoList.size(); + std::cout << "nbocos = " << nbocos << "\n"; + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = -1; + GridLocation_t location = Vertex; + + std::string boconame = "BC" + std::to_string( iboco + 1 ); + + PhysicalSplitBc * physicalSplitBc = bccoList[ iboco ]; + BCType_t bocotype = static_cast( physicalSplitBc->bcType ); + PointSetType_t ptset_type = PointRange; + cgsize_t npnts = 2; + std::vector pnts; + int nSize = physicalSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( physicalSplitBc->region.end[ i ] ); + } + + cg_boco_write( fileId, baseId, zoneId, boconame.c_str(), bocotype, ptset_type, npnts, pnts.data(), & bccoId ); + } + + //std::vector< InterfaceSplitBc * > & bc1to1List = splitZone->interfaceSplitBcList; + std::vector< InterfaceSplitBc * > bc1to1List; + splitZone->GetLeafInterfaceBc( bc1to1List ); + + int n1to1 = bc1to1List.size(); + std::cout << "n1to1 = " << n1to1 << "\n"; + + std::vector itranfrm( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + itranfrm[ m ] = m + 1; + } + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int index_conn = -1; + + InterfaceSplitBc * interfaceSplitBc = bc1to1List[ i1to1 ]; + + std::vector pnts; + std::vector pntsdonor; + int nSize = interfaceSplitBc->region.start.size(); + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.start[ i ] ); + } + for ( int i = 0; i < nSize; ++ i ) + { + pnts.push_back( interfaceSplitBc->region.end[ i ] ); + } + + int nPatchSize = interfaceSplitBc->donor_region.start.size(); + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.start[ i ] ); + } + for ( int i = 0; i < nPatchSize; ++ i ) + { + pntsdonor.push_back( interfaceSplitBc->donor_region.end[ i ] ); + } + int id = interfaceSplitBc->donor_zone->newIndex; + int oldZoneIndex = interfaceSplitBc->donor_zone->zoneIndex; + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + std::cout << "donor zone id = " << id << "\n"; + std::cout << "donor zone oldZoneIndex = " << oldZoneIndex << "\n"; + std::string donorname = "Zone" + std::to_string( id ); + std::string connectname = "Interface" + std::to_string( i1to1 ); + + std::cout << "donorname = " << donorname << "\n"; + std::cout << "connectname = " << connectname << "\n"; + + std::vector & itranfrm = interfaceSplitBc->transform; + + cg_1to1_write( fileId, baseId, zoneId, connectname.c_str(), donorname.c_str(), pnts.data(), pntsdonor.data(), itranfrm.data(), &index_conn ); + std::cout << "index_conn = " << index_conn << "\n"; + } + } + } + cg_close( fileId ); +} + +void Partition::ModifyZoneIndex() +{ + std::cout << "ModifyZoneIndex +++++++++++++++++++++++++ " << "\n"; + int globalZoneId = 0; + for ( int iProc = 0; iProc < nProc; ++ iProc ) + { + std::cout << "iProc = " << iProc << "\n"; + int nZones = this->GetNZones( iProc ); + std::cout << "nZones in Proc " << iProc << " = " << nZones << "\n"; + + for ( int iZone = 0; iZone < nZones; ++ iZone ) + { + SplitZone * splitZone = this->GetSplitZone( iProc, iZone ); + //splitZone->SetZoneIndex( globalZoneId++ ); + splitZone->newIndex = ( globalZoneId++ ); + std::cout << "splitZone->newIndex = " << splitZone->newIndex << "\n"; + std::cout << "splitZone->zoneIndex = " << splitZone->zoneIndex << "\n"; + } + } +} \ No newline at end of file diff --git a/example/partition/struct/1d/1to4blocks/02/Partition.h b/example/partition/struct/1d/1to4blocks/02/Partition.h new file mode 100644 index 00000000..8a4a9731 --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/Partition.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include +#include + +class SplitZone; + +struct CmpSplitZone +{ + bool operator() ( SplitZone * a, SplitZone * b ) const; +}; + +class Partition +{ +public: + Partition(); + ~Partition(); +protected: + std::set < SplitZone * > zoneStorage; + std::set < SplitZone *, CmpSplitZone > unsignedZoneGroup; + std::vector< SplitZone * > refZone; + std::vector< std::vector< SplitZone * > > procSplitZone; + std::vector procSpeed; + std::vector timeProc; + double aveFloatOp, delta; + double idealUniProcTime, eps; + int minNumberCell; + int nTZone; + int nOriZone; + int nProc; +public: + std::string inputName; + std::string outName; +public: + void Solve(); + void ReadGrid(); + void Split(); + void InitSplit(); + void BinarySplit(); + //void GreedySplit(); +public: + void AddNewZone( SplitZone * zone ); + void AddZoneToUnsignedGroup( SplitZone * zone ); + void RemoveZoneFromUnsignedGroup( SplitZone * zone ); + void AddZoneToProcess( int iProc, SplitZone * zone ); + void DumpPartitionedGridFile(); + void ModifyZoneIndex(); + void FreeAllZones(); + int GetNZones( int iProc ); + SplitZone * GetSplitZone( int iProc, int zoneId ); + void ComputeCoor( SplitZone * splitZone, int icoord, std::vector & coord ); + void DumpBc( SplitZone * splitZone ); +private: + int GetMinValueIndex( double * data, int numberOfData ); + int GetMinLoadProc(); + SplitZone * GetLargestZone(); + SplitZone * Split( SplitZone * zone, double nCell ); +}; + diff --git a/example/partition/struct/1d/1to4blocks/02/README.txt b/example/partition/struct/1d/1to4blocks/02/README.txt new file mode 100644 index 00000000..13dc2f91 --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/README.txt @@ -0,0 +1 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. diff --git a/example/partition/struct/1d/1to4blocks/02/SplitZone.cpp b/example/partition/struct/1d/1to4blocks/02/SplitZone.cpp new file mode 100644 index 00000000..aef70754 --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/SplitZone.cpp @@ -0,0 +1,1091 @@ +#include "SplitZone.h" +#include "cgnslib.h" +#include + +int Dim::dim = -1; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ) +{ + domainBox.start = zoneBox.start; + domainBox.end = zoneBox.end; + + int axis = iDomain / 2; + int direction = iDomain % 2; + + if ( direction == 0 ) + { + domainBox.end[ axis ] = domainBox.start[ axis ]; + } + else if ( direction == 1 ) + { + domainBox.start[ axis ] = domainBox.end[ axis ]; + } +} + +DimInfo::DimInfo() +{ + this->Init( 1 ); +} + +DimInfo::~DimInfo() +{ +} + +void DimInfo::Init( int dim ) +{ + this->dim = dim; + dimList.resize( this->dim, 1 ); + oriPoint.resize( this->dim, 0 ); +} + +DimInfo & DimInfo::operator = ( const DimInfo & rhs ) +{ + if ( this == & rhs ) return * this; + + this->dim = rhs.dim; + this->dimList = rhs.dimList; + this->oriPoint = rhs.oriPoint; + + return * this; +} + +int DimInfo::ComputeNumNodes() +{ + int nNodes = 1; + for ( int m = 0; m < this->dimList.size(); ++ m ) + { + nNodes *= this->dimList[ m ]; + } + return nNodes; +} + +void DimInfo::ComputeISize() +{ + int index_dim = this->dimList.size(); + this->isize.resize( index_dim * 3, 0 ); + for ( int m = 0; m < index_dim; ++ m ) + { + isize[ m ] = this->dimList[ m ]; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 1; + isize[ start + m ] = this->dimList[ m ] - 1; + } + + for ( int m = 0; m < index_dim; ++ m ) + { + int start = index_dim * 2; + isize[ start + m ] = 0; + } + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "i = " << i << " isize = " << isize[i] << "\n"; + } +} + +void DimInfo::ComputeRminmax( std::vector & ref ) +{ + int index_dim = this->dimList.size(); + this->rmin.resize( index_dim ); + this->rmax.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + rmin[ m ] = ref[ m ] + 1; + rmax[ m ] = ref[ m ] + this->dimList[ m ]; + } + + std::cout << "rmin, rmax = \n"; + for ( int m = 0; m < index_dim; ++ m ) + { + std::cout << rmin[ m ] << " " << rmax[ m ] << "\n"; + } +} + +void DimInfo::Init( std::vector & dimList ) +{ + this->dim = dimList.size(); + this->dimList = dimList; + std::vector zero( dimList.size(), 0 ); + this->oriPoint = zero; +} + +void DimInfo::SetNewDimension( int axis, int newStart, int newWidth ) +{ + this->oriPoint[ axis ] = newStart; + this->dimList [ axis ] = newWidth; +} + +void DimInfo::GetZoneGlobalBox( RangeRegion &zoneBox ) +{ + int index_dim = this->dimList.size(); + zoneBox.start.resize( index_dim ); + zoneBox.end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + zoneBox.start[ m ] = this->oriPoint[ m ] + 1; + zoneBox.end[ m ] = this->oriPoint[ m ] + this->dimList[ m ]; + } +} + +void DimInfo::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + int index_dim = this->dimList.size(); + localBox.start.resize( index_dim ); + localBox.end.resize( index_dim ); + + for ( int m = 0; m < index_dim; ++ m ) + { + localBox.start[ m ] = globalBox.start[ m ] - this->oriPoint[ m ]; + localBox.end[ m ] = globalBox.end[ m ] - this->oriPoint[ m ]; + } +} + +RangeRegion::RangeRegion( int nSize ) +{ + this->Init( nSize ); +} + +RangeRegion::~RangeRegion() +{ +} + +void RangeRegion::Init( int nSize ) +{ + this->start.resize( nSize ); + this->end.resize( nSize ); +} + +RangeRegion & RangeRegion::operator = ( const RangeRegion & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +bool RangeRegion::operator == ( const RangeRegion & rhs ) const +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( this->start[ m ] != rhs.start[ m ] || + this->end [ m ] != rhs.end [ m ] ) + { + return false; + } + } + return true; +} + +void RangeRegion::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +bool RangeRegion::InRegion( const RangeRegion & region ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + if ( ( this->start[ m ] < region.start[ m ] ) || ( this->end[ m ] > region.end[ m ] ) ) + { + return false; + } + } + return true; +} + +void RangeRegion::Normalize() +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + int minv = std::min( this->start[ m ], this->end[ m ] ); + int maxv = std::max( this->start[ m ], this->end[ m ] ); + this->start[ m ] = minv; + this->end[ m ] = maxv; + } +} + +void RangeRegion::Localize( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::ToGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] += oriPoint[ m ]; + this->end[ m ] += oriPoint[ m ]; + } +} + +void RangeRegion::ToLocal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + for ( int m = 0; m < nSize; ++ m ) + { + this->start[ m ] -= oriPoint[ m ]; + this->end[ m ] -= oriPoint[ m ]; + } +} + +void RangeRegion::PrintGlobal( std::vector & oriPoint ) +{ + int nSize = this->start.size(); + std::cout << "global start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "global end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ] + oriPoint[m]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +void RangeRegion::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"; +} + +bool CheckOverLapping( RangeRegion & overlapRegion ); + +bool ComputeOverlapRegion( RangeRegion & region1, RangeRegion & region2, RangeRegion & overlapRegion ) +{ + int index_dim = region1.start.size(); + overlapRegion.Init( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + int ijkmin1 = std::min( region1.start[ m ], region1.end[ m ] ); + int ijkmax1 = std::max( region1.start[ m ], region1.end[ m ] ); + int ijkmin2 = std::min( region2.start[ m ], region2.end[ m ] ); + int ijkmax2 = std::max( region2.start[ m ], region2.end[ m ] ); + if ( ( ijkmax1 < ijkmin2 ) || ( ijkmin1 > ijkmax2 ) ) + { + return false; + } + + int ijkmin = std::max( ijkmin1, ijkmin2 ); + int ijkmax = std::min( ijkmax1, ijkmax2 ); + + overlapRegion.start[ m ] = ijkmin; + overlapRegion.end [ m ] = ijkmax; + } + + return CheckOverLapping( overlapRegion ); +} + +bool CheckOverLapping( RangeRegion & overlapRegion ) +{ + int index_dim = overlapRegion.start.size(); + int iCount = 0; + for ( int m = 0; m < index_dim; ++ m ) + { + if ( overlapRegion.start[ m ] == overlapRegion.end[ m ] ) + { + ++ iCount; + } + } + + return ( iCount == 1 ); +} + +bool GetInterfaceRegion( RangeRegion & zoneBoxL, RangeRegion & zoneBoxR, RangeRegion & interfaceRegion ) +{ + int index_dim = zoneBoxL.start.size(); + int nDomains = 2 * index_dim; + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegionL; + GetDomainRegion( zoneBoxL, iDomain, domainRegionL ); + + for ( int jDomain = 0; jDomain < nDomains; ++ jDomain ) + { + RangeRegion domainRegionR; + GetDomainRegion( zoneBoxR, jDomain, domainRegionR ); + + if ( domainRegionL == domainRegionR ) + { + interfaceRegion = domainRegionL; + return true; + } + } + } + return false; +} + +void CreateInterfaceBc( SplitZone * zoneL, SplitZone * zoneR ) +{ + RangeRegion globalBoxL, globalBoxR, globalInterfaceRegion; + + zoneL->GetZoneGlobalBox( globalBoxL ); + zoneR->GetZoneGlobalBox( globalBoxR ); + + if ( ! GetInterfaceRegion( globalBoxL, globalBoxR, globalInterfaceRegion ) ) + { + return; + } + + RangeRegion localInterfaceRegionL, localInterfaceRegionR; + + zoneL->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionL ); + zoneR->GetZoneLocalBox( globalInterfaceRegion, localInterfaceRegionR ); + + int kkk = 1; + + InterfaceSplitBc * interfaceSplitBcL = new InterfaceSplitBc(); + zoneL->interfaceSplitBcList.push_back( interfaceSplitBcL ); + interfaceSplitBcL->zone = zoneL; + interfaceSplitBcL->region = localInterfaceRegionL; + + int nSize = localInterfaceRegionL.start.size(); + + std::vector transform; + + for ( int m = 0; m < nSize; ++ m ) + { + transform.push_back( m + 1 ); + } + + interfaceSplitBcL->transform = transform; + interfaceSplitBcL->CalcTransformMatrix(); + + interfaceSplitBcL->donor_zone = zoneR; + interfaceSplitBcL->donor_region = localInterfaceRegionR; + + InterfaceSplitBc * interfaceSplitBcR = new InterfaceSplitBc(); + zoneR->interfaceSplitBcList.push_back( interfaceSplitBcR ); + + interfaceSplitBcR->zone = zoneR; + interfaceSplitBcR->region = localInterfaceRegionR; + + interfaceSplitBcR->transform = transform; + interfaceSplitBcR->CalcTransformMatrix(); + + interfaceSplitBcR->donor_zone = zoneL; + interfaceSplitBcR->donor_region = localInterfaceRegionL; +} + + +PhysicalSplitBc::PhysicalSplitBc() +{ + this->region.Init( Dim::dim ); +} + +PhysicalSplitBc::~PhysicalSplitBc() +{ +} + +void PhysicalSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void PhysicalSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +void PhysicalSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = splitZone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +BasicSplitBc::BasicSplitBc() +{ + this->region.Init( Dim::dim ); +} + +BasicSplitBc::~BasicSplitBc() +{ + ; +} + +void BasicSplitBc::SetRegion( std::vector & pnts ) +{ + this->region.SetRegion( pnts ); +} + +void BasicSplitBc::SetRegion( RangeRegion & region ) +{ + this->region = region; +} + +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; + } +} + +InterfaceInfo::InterfaceInfo() +{ + this->donor_region.Init( Dim::dim ); +} + +InterfaceInfo::~InterfaceInfo() +{ +} + +InterfaceSplitBc::InterfaceSplitBc() +{ + this->region.Init( Dim::dim ); + this->donor_region.Init( Dim::dim ); +} + +InterfaceSplitBc::~InterfaceSplitBc() +{ +} + +void InterfaceSplitBc::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nChild = this->child.size(); + if ( nChild == 0 ) + { + leafInterfaceBcList.push_back( this ); + } + else + { + for ( int iChild = 0; iChild < nChild; ++ iChild ) + { + InterfaceSplitBc * interfaceSplitBc = this->child[ iChild ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } + } +} + +void InterfaceSplitBc::CopyMatrix( InterfaceSplitBc * interfaceSplitBc ) +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = interfaceSplitBc->Mt[ i ][ j ]; + } + } +} + +void InterfaceSplitBc::CalcTransformMatrix() +{ + 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 InterfaceSplitBc::mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ) +{ + int dim = Dim::dim; + std::vector diff( dim ); + for ( int m = 0; m < dim; ++ m ) + { + diff[ m ] = index1[ m ] - begin1[ m ]; + } + + std::vector mul( dim ); + + Multiply( Mt, diff, mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = mul[ m ] + begin2[ m ]; + } +} + +void InterfaceSplitBc::Multiply( int Mt[][3], std::vector & a, std::vector & b ) +{ + int dim = Dim::dim; + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += Mt[ i ][ j ] * a[ j ]; + } + } +} + +void InterfaceSplitBc::ChangeRegionToLocalCoordinate() +{ + int index_dim = this->region.start.size(); + std::vector & oriPoint = this->zone->dimInfo.oriPoint; + for ( int m = 0; m < index_dim; ++ m ) + { + this->region.start[ m ] -= oriPoint[ m ]; + this->region.end[ m ] -= oriPoint[ m ]; + } +} + +void InterfaceSplitBc::CalcSubDonorRegion( RangeRegion &subRegion, RangeRegion &subDonorRegion ) +{ + std::vector begin1 = this->region.start; + std::vector end1 = this->region.end; + std::vector begin2 = this->donor_region.start; + std::vector end2 = this->donor_region.end; + + std::vector new_begin1 = subRegion.start; + std::vector new_end1 = subRegion.end; + + int dim = Dim::dim; + std::vector new_begin2( dim ); + std::vector new_end2( dim ); + + mapindex( begin1, begin2, new_begin1, new_begin2 ); + mapindex( begin1, begin2, new_end1, new_end2 ); + + subDonorRegion.start = new_begin2; + subDonorRegion.end = new_end2; +} + +SplitZone::SplitZone() +{ + this->parent = 0; + this->zoneIndex = 0; + this->iProc = 0; + dimInfo.Init( Dim::dim ); + int kk = 1; +} + +SplitZone::~SplitZone() +{ + ; +} + +void SplitZone::GetZoneGlobalBox( RangeRegion & zoneBox ) +{ + this->dimInfo.GetZoneGlobalBox( zoneBox ); +} + +void SplitZone::GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ) +{ + this->dimInfo.GetZoneLocalBox( globalBox, localBox ); +} + + +void SplitZone::ComputeRminmax() +{ + int index_dim = this->dimInfo.dimList.size(); + std::vector ref( index_dim, 0 ); + + SplitZone * rootSplitZone = 0; + this->GetRootInfo( rootSplitZone, ref ); + + this->dimInfo.ComputeRminmax( ref ); +} + +SplitZone * SplitZone::GetRootZone() +{ + SplitZone * root = this; + + while ( true ) + { + if ( root->parent ) + { + root = root->parent; + } + else + { + return root; + } + }; +} + +void SplitZone::GetRootInfo( SplitZone *& root, std::vector & ref ) +{ + for ( int i = 0; i < this->dimInfo.dimList.size(); ++ i ) + { + ref[ i ] += this->dimInfo.oriPoint[ i ]; + } + + if ( this->parent ) + { + this->parent->GetRootInfo( root, ref ); + } + else + { + root = this; + } +} + +void SplitZone::SetParentAndChild( SplitZone * parent ) +{ + this->parent = parent; + if ( parent ) + { + parent->child.push_back( this ); + } +} + +void SplitZone::GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ) +{ + int nInterfaceBcs = this->interfaceSplitBcList.size(); + for ( int i = 0; i < nInterfaceBcs; ++ i ) + { + InterfaceSplitBc * interfaceSplitBc = this->interfaceSplitBcList[ i ]; + interfaceSplitBc->GetLeafInterfaceBc( leafInterfaceBcList ); + } +} + +int SplitZone::GetNCell() +{ + int numberOfCells = 1; + for ( int i = 0; i < this->dimInfo.dim; ++ i ) + { + numberOfCells *= std::max( 1, ( this->dimInfo.dimList[ i ] - 1 ) ); + } + + return numberOfCells; +} + +void SplitZone::SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int leftStart = 0; + int leftWidth = iSplit - 0; + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, leftStart , leftWidth ); +} + +void SplitZone::SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ) +{ + int rightStart = iSplit - 1; + int rightWidth = dimList[ axisNeedSplit ] - ( iSplit - 1 ); + + this->dimInfo.Init( dimList ); + this->dimInfo.SetNewDimension( axisNeedSplit, rightStart, rightWidth ); +} + +void SplitZone::Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ) +{ + //Find the longest axis + int axisNeedSplit = this->FindAxisNeedSplit(); + int iSplit = this->FindSplitPosition( axisNeedSplit, nCell ); + + zoneL->SetLeftDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + zoneR->SetRightDimension( this->dimInfo.dimList, axisNeedSplit, iSplit ); + + zoneL->CreateBcFromParent(); + zoneR->CreateBcFromParent(); + + CreateInterfaceBc( zoneL, zoneR ); +} + +void SplitZone::CreateBcFromParent() +{ + this->CreatePhysicalBcFromParent(); + this->CreateInterfaceBcFromParent(); +} + +void SplitZone::CreatePhysicalBcFromParent() +{ + int nParentPhysicalBcs = this->parent->physicalSplitBcList.size(); + + for ( int iParentPhysicalBcs = 0; iParentPhysicalBcs < nParentPhysicalBcs; ++ iParentPhysicalBcs ) + { + PhysicalSplitBc * parentPhysicalSplitBc = this->parent->physicalSplitBcList[ iParentPhysicalBcs ]; + + this->CreatePhysicalBcFromParent( parentPhysicalSplitBc ); + } +} + +void SplitZone::CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentPhysicalSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreatePhysicalBc( overlapRegion, parentPhysicalSplitBc->bcType ); + + int kkk = 1; + } +} + +void SplitZone::CreateInterfaceBcFromParent() +{ + int nInterfaceSplitBcs = this->parent->interfaceSplitBcList.size(); + + for ( int iInterfaceSplitBcs = 0; iInterfaceSplitBcs < nInterfaceSplitBcs; ++ iInterfaceSplitBcs ) + { + InterfaceSplitBc * parentInterfaceSplitBc = this->parent->interfaceSplitBcList[ iInterfaceSplitBcs ]; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc ); + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ) +{ + int index_dim = this->dimInfo.dimList.size(); + int nDomains = 2 * index_dim; + RangeRegion zoneBoxRegion( index_dim ); + this->dimInfo.GetZoneGlobalBox( zoneBoxRegion ); + + for ( int iDomain = 0; iDomain < nDomains; ++ iDomain ) + { + RangeRegion domainRegion( index_dim ); + GetDomainRegion( zoneBoxRegion, iDomain, domainRegion ); + + RangeRegion overlapRegion; + bool overlap_flag = ComputeOverlapRegion( parentInterfaceSplitBc->region, domainRegion, overlapRegion ); + if ( ! overlap_flag ) continue; + + this->CreateInterfaceBcFromParent( parentInterfaceSplitBc, overlapRegion ); + + int kkk = 1; + } +} + +void SplitZone::FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ) +{ + RangeRegion donor_region = interfaceSplitBc->donor_region; + donor_region.Normalize(); + interfaceInfo.donor_zone = this; + for ( int iInterface = 0; iInterface < interfaceSplitBcList.size(); ++ iInterface ) + { + InterfaceSplitBc * candidateDonorBc = interfaceSplitBcList[ iInterface ]; + bool flag = donor_region.InRegion( candidateDonorBc->region ); + if ( flag ) + { + if ( donor_region == candidateDonorBc->region ) + { + interfaceInfo.donor_interface = candidateDonorBc; + return; + } + else + { + InterfaceSplitBc * donorBc = new InterfaceSplitBc(); + candidateDonorBc->child.push_back( donorBc ); + donorBc->region = donor_region; + donorBc->zone = candidateDonorBc->zone; + donorBc->donor_zone = interfaceSplitBc->zone; + donorBc->transform = candidateDonorBc->transform; + donorBc->CopyMatrix( candidateDonorBc ); + RangeRegion subDonorRegion( Dim::dim ); + candidateDonorBc->CalcSubDonorRegion( donorBc->region, subDonorRegion ); + std::vector & oriPoint = interfaceSplitBc->zone->dimInfo.oriPoint; + subDonorRegion.Localize( oriPoint ); + donorBc->donor_region = subDonorRegion; + donorBc->donor_bc = interfaceSplitBc; + interfaceInfo.donor_interface = donorBc; + return; + } + } + } + return; +} + +void SplitZone::GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ) +{ + std::cout << "subDonorRegion = \n"; + //subDonorRegion.Print(); + RangeRegion normalizedDonorRegion = subDonorRegion; + normalizedDonorRegion.Normalize(); + int nChild = this->child.size(); + for ( int ichild = 0; ichild < nChild; ++ ichild ) + { + std::cout << " iChild = " << ichild << " nChild = " << nChild << "\n"; + SplitZone * sub_zone = this->child[ ichild ]; + std::cout << " zoneIndex = " << sub_zone->zoneIndex << "\n"; + int nInters = sub_zone->interfaceSplitBcList.size(); + for ( int iInter = 0; iInter < nInters; ++ iInter ) + { + std::cout << " iInter = " << iInter << "\n"; + InterfaceSplitBc * interfaceSplitBc = sub_zone->interfaceSplitBcList[ iInter ]; + std::cout << "interfaceSplitBc local = \n"; + interfaceSplitBc->region.Print(); + std::cout << "interfaceSplitBc global = \n"; + interfaceSplitBc->region.PrintGlobal( sub_zone->dimInfo.oriPoint ); + RangeRegion g_region = interfaceSplitBc->region; + g_region.ToGlobal( sub_zone->dimInfo.oriPoint ); + if ( g_region == normalizedDonorRegion ) + { + RangeRegion donorRegion = subDonorRegion; + donorRegion.ToLocal( sub_zone->dimInfo.oriPoint ); + + interfaceInfo.donor_zone = sub_zone; + interfaceInfo.donor_interface = interfaceSplitBc; + interfaceInfo.donor_region = donorRegion; + return; + } + } + } +} + +void SplitZone::CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ) +{ + InterfaceSplitBc * interfaceSplitBc = new InterfaceSplitBc(); + this->interfaceSplitBcList.push_back( interfaceSplitBc ); + + interfaceSplitBc->region = overlapRegion; + interfaceSplitBc->zone = this; + interfaceSplitBc->transform = parentInterfaceSplitBc->transform; + interfaceSplitBc->CopyMatrix( parentInterfaceSplitBc ); + RangeRegion subDonorRegion( Dim::dim ); + parentInterfaceSplitBc->CalcSubDonorRegion( overlapRegion, subDonorRegion ); + interfaceSplitBc->ChangeRegionToLocalCoordinate(); + interfaceSplitBc->donor_region = subDonorRegion; + SplitZone * parent_donor_zone = parentInterfaceSplitBc->donor_zone; + std::cout << " parentInterfaceSplitBc->zone->zoneIndex " << parentInterfaceSplitBc->zone->zoneIndex << "\n"; + std::cout << " parentInterfaceSplitBc->donor_zone->zoneIndex " << parent_donor_zone->zoneIndex << "\n"; + if ( parent_donor_zone->child.size() > 0 ) + { + InterfaceInfo interfaceInfo; + parent_donor_zone->GetChildDonorRegion( subDonorRegion, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + interfaceSplitBc->donor_region = interfaceInfo.donor_region; + //compatibility + InterfaceSplitBc * donor_bc = interfaceSplitBc->donor_bc; + SplitZone * donor_zone = interfaceSplitBc->donor_zone; + if ( interfaceSplitBc->zone != donor_bc->donor_zone ) + { + if ( interfaceSplitBc->zone->parent == donor_bc->donor_zone ) + { + RangeRegion d_region = donor_bc->donor_region; + d_region.ToLocal( interfaceSplitBc->zone->dimInfo.oriPoint ); + donor_bc->donor_region = d_region; + } + donor_bc->donor_zone = interfaceSplitBc->zone; + + int kkk = 1; + } + int kkk = 1; + } + else + { + InterfaceInfo interfaceInfo; + parent_donor_zone->FindDonorInterface( interfaceSplitBc, interfaceInfo ); + interfaceSplitBc->donor_zone = interfaceInfo.donor_zone; + interfaceSplitBc->donor_bc = interfaceInfo.donor_interface; + } + + int kkk = 1; +} + +void SplitZone::CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ) +{ + PhysicalSplitBc * physicalSplitBc = new PhysicalSplitBc(); + this->physicalSplitBcList.push_back( physicalSplitBc ); + physicalSplitBc->SetRegion( overlapRegion ); + physicalSplitBc->bcType = bcType; + physicalSplitBc->splitZone = this; + physicalSplitBc->ChangeRegionToLocalCoordinate(); +} + +int SplitZone::FindAxisNeedSplit() +{ + //Find the longest axis + int axisNeedSplit = 0; + int maxN = this->dimInfo.dimList[ 0 ]; + + for ( int m = 1; m < this->dimInfo.dimList.size(); ++ m ) + { + if ( this->IsPoleBc( m ) ) + { + continue; + } + int Nm = this->dimInfo.dimList[ m ]; + if ( maxN < Nm ) + { + maxN = Nm; + axisNeedSplit = m; + } + } + + return axisNeedSplit; +} + +int SplitZone::GetCrossSection( int axis ) +{ + int nDim = this->dimInfo.dimList.size(); + int crossSection = 1; + int N = nDim - 1; + for ( int m = 0; m < N; ++ m ) + { + int mm = ( axis + 1 ) % nDim; + int nLineElements = std::max( 1, ( this->dimInfo.dimList[ mm ] - 1 ) ); + crossSection *= nLineElements; + } + return crossSection; +} + +int SplitZone::FindSplitPosition( int axisNeedSplit, double nCell ) +{ + int nDim = this->dimInfo.dimList.size(); + std::vector crossSections( nDim ); + for ( int m = 0; m < nDim; ++ m ) + { + crossSections[ m ] = this->GetCrossSection( m ); + } + + //guess the value + double dSplit = nCell / crossSections[ axisNeedSplit ]; + int iSplit = 1 + static_cast< int >( std::floor( dSplit + 0.5 ) ); + return iSplit; +} + + +bool SplitZone::IsPoleBc( int splitDirection ) +{ + return false; +} + diff --git a/example/partition/struct/1d/1to4blocks/02/SplitZone.h b/example/partition/struct/1d/1to4blocks/02/SplitZone.h new file mode 100644 index 00000000..ffe1e306 --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/SplitZone.h @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include + +class Dim +{ +public: + static int dim; +}; + +class SplitZone; +class RangeRegion; + +void GetDomainRegion( RangeRegion & zoneBox, int iDomain, RangeRegion & domainBox ); + +class DimInfo +{ +public: + DimInfo(); + ~DimInfo(); +public: + int dim; + std::vector dimList; + std::vector oriPoint; + std::vector isize; + std::vector rmin; + std::vector rmax; +public: + int GetSize() const { return dim; } + DimInfo & operator = ( const DimInfo & rhs ); +public: + int ComputeNumNodes(); + void ComputeISize(); + void ComputeRminmax( std::vector & ref ); + void Init( int dim ); + void Init( std::vector & dimList ); + void SetNewDimension( int axis, int newStart, int newWidth ); + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); +}; + +class SplitZone; +class SplitBcPatch; + +class RangeRegion +{ +public: + RangeRegion( int nSize = 1 ); + ~RangeRegion(); +public: + std::vector start; + std::vector end; +public: + void Init( int nSize ); + RangeRegion & operator = ( const RangeRegion & rhs ); + bool operator == ( const RangeRegion & rhs ) const; + bool InRegion( const RangeRegion & region ); + void SetRegion( std::vector &pnts ); + void Normalize(); + void Localize( std::vector & oriPoint ); + void ToGlobal( std::vector & oriPoint ); + void ToLocal( std::vector & oriPoint ); + void PrintGlobal( std::vector & oriPoint ); + void Print(); +}; + +class PhysicalSplitBc +{ +public: + PhysicalSplitBc(); + ~PhysicalSplitBc(); +public: + int bcType; + RangeRegion region; +public: + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector &pnts ); + void SetRegion( RangeRegion ®ion ); + void ChangeRegionToLocalCoordinate(); +}; + +class BasicSplitBc +{ +public: + BasicSplitBc(); + ~BasicSplitBc(); +public: + RangeRegion region; + SplitZone * splitZone = nullptr; +public: + void SetRegion( std::vector & pnts ); + void SetRegion( RangeRegion & region ); +}; + +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 InterfaceSplitBc; +class SplitZone; + +class InterfaceInfo +{ +public: + InterfaceInfo(); + ~InterfaceInfo(); +public: + InterfaceSplitBc * donor_interface = nullptr; + SplitZone * donor_zone = nullptr; + RangeRegion donor_region; +}; + +class InterfaceSplitBc +{ +public: + InterfaceSplitBc(); + ~InterfaceSplitBc(); +public: + std::vector transform; + int Mt[ 3 ][ 3 ]; + RangeRegion region; + SplitZone * zone = nullptr; + RangeRegion donor_region; + SplitZone * donor_zone = nullptr; + InterfaceSplitBc * donor_bc = nullptr; +public: + std::vector child; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + void CopyMatrix( InterfaceSplitBc * interfaceSplitBc ); + void CalcTransformMatrix(); + void CalcSubDonorRegion( RangeRegion & subRegion, RangeRegion & subDonorRegion ); + void mapindex( std::vector & begin1, std::vector & begin2, std::vector & index1, std::vector & index2 ); + void Multiply( int Mt[][ 3 ], std::vector & a, std::vector & b ); + void ChangeRegionToLocalCoordinate(); +}; + +class SplitZone +{ +public: + SplitZone(); + ~SplitZone(); +public: + DimInfo dimInfo; + int zoneIndex, iProc; + int newIndex; +protected: + SplitZone * parent; + std::vector child; +public: + std::vector< PhysicalSplitBc * > physicalSplitBcList; + std::vector< InterfaceSplitBc * > interfaceSplitBcList; + void GetLeafInterfaceBc( std::vector< InterfaceSplitBc * > & leafInterfaceBcList ); +public: + int GetNCell(); + void ComputeRminmax(); + void GetRootInfo( SplitZone *& root, std::vector & ref ); + void SetZoneIndex( int zoneIndex ) { this->zoneIndex = zoneIndex; } + int GetZoneIndex() { return zoneIndex; } + void SetProcId( int iProc ) { this->iProc = iProc; } + void SetParent( SplitZone * parent ) { this->parent = parent; }; + void SetParentAndChild( SplitZone * parent ); + void FindDonorInterface( InterfaceSplitBc * interfaceSplitBc, InterfaceInfo & interfaceInfo ); + void GetChildDonorRegion( RangeRegion & subDonorRegion, InterfaceInfo & interfaceInfo ); +public: + void CreateBcFromParent(); + void CreatePhysicalBcFromParent(); + void CreatePhysicalBcFromParent( PhysicalSplitBc * parentPhysicalSplitBc ); + void CreatePhysicalBc( RangeRegion & overlapRegion, int bcType ); + void CreateInterfaceBcFromParent(); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc ); + void CreateInterfaceBcFromParent( InterfaceSplitBc * parentInterfaceSplitBc, RangeRegion & overlapRegion ); + + void GetZoneGlobalBox( RangeRegion & zoneBox ); + void GetZoneLocalBox( RangeRegion & globalBox, RangeRegion & localBox ); + SplitZone * GetRootZone(); +public: + void Split( SplitZone *& zoneL, SplitZone *& zoneR, double nCell ); + void SetLeftDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); + void SetRightDimension( std::vector & dimList, int axisNeedSplit, int iSplit ); +private: + int FindAxisNeedSplit(); + int FindSplitPosition( int axisNeedSplit, double nCell ); + bool IsPoleBc( int splitDirection ); + int GetCrossSection( int axis ); +}; + diff --git a/example/partition/struct/1d/1to4blocks/02/heat1d1blocksv1.cgns b/example/partition/struct/1d/1to4blocks/02/heat1d1blocksv1.cgns new file mode 100644 index 00000000..1d0a3fb2 Binary files /dev/null and b/example/partition/struct/1d/1to4blocks/02/heat1d1blocksv1.cgns differ diff --git a/example/partition/struct/1d/1to4blocks/02/heat1d2blocks.cgns b/example/partition/struct/1d/1to4blocks/02/heat1d2blocks.cgns new file mode 100644 index 00000000..afe06dc4 Binary files /dev/null and b/example/partition/struct/1d/1to4blocks/02/heat1d2blocks.cgns differ diff --git a/example/partition/struct/1d/1to4blocks/02/heat1d4blocks.cgns b/example/partition/struct/1d/1to4blocks/02/heat1d4blocks.cgns new file mode 100644 index 00000000..8d0013f1 Binary files /dev/null and b/example/partition/struct/1d/1to4blocks/02/heat1d4blocks.cgns differ diff --git a/example/partition/struct/1d/1to4blocks/02/main.cpp b/example/partition/struct/1d/1to4blocks/02/main.cpp new file mode 100644 index 00000000..5da1de7c --- /dev/null +++ b/example/partition/struct/1d/1to4blocks/02/main.cpp @@ -0,0 +1,18 @@ +#include "cgnslib.h" +#include "CgnsGrid.h" +#include "Partition.h" +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + Partition * partition = new Partition(); + partition->Solve(); + delete partition; + + return 0; +} diff --git a/example/sod-shock-tube/hllc/cpp/01/BurgersField.cpp b/example/sod-shock-tube/hllc/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/hllc/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( 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/sod-shock-tube/hllc/cpp/01/BurgersField.h b/example/sod-shock-tube/hllc/cpp/01/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/hllc/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( 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/sod-shock-tube/hllc/cpp/01/CMakeLists.txt b/example/sod-shock-tube/hllc/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/hllc/cpp/01/CgnsUtil.cpp b/example/sod-shock-tube/hllc/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/CgnsUtil.h b/example/sod-shock-tube/hllc/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/EulerField.cpp b/example/sod-shock-tube/hllc/cpp/01/EulerField.cpp new file mode 100644 index 00000000..70c9a422 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/EulerField.cpp @@ -0,0 +1,737 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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::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 EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/hllc/cpp/01/EulerField.h b/example/sod-shock-tube/hllc/cpp/01/EulerField.h new file mode 100644 index 00000000..441dcaac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/EulerField.h @@ -0,0 +1,42 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 ); +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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/hllc/cpp/01/Field.cpp b/example/sod-shock-tube/hllc/cpp/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/hllc/cpp/01/Field.h b/example/sod-shock-tube/hllc/cpp/01/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/hllc/cpp/01/Global.cpp b/example/sod-shock-tube/hllc/cpp/01/Global.cpp new file mode 100644 index 00000000..ea38d8e1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Global.cpp @@ -0,0 +1,444 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/hllc/cpp/01/Global.h b/example/sod-shock-tube/hllc/cpp/01/Global.h new file mode 100644 index 00000000..b71fcc5b --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Global.h @@ -0,0 +1,174 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/hllc/cpp/01/Grid.cpp b/example/sod-shock-tube/hllc/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Grid.h b/example/sod-shock-tube/hllc/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/HeatField.cpp b/example/sod-shock-tube/hllc/cpp/01/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/hllc/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( 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/sod-shock-tube/hllc/cpp/01/HeatField.h b/example/sod-shock-tube/hllc/cpp/01/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/hllc/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( 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/sod-shock-tube/hllc/cpp/01/LogFile.cpp b/example/sod-shock-tube/hllc/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/LogFile.h b/example/sod-shock-tube/hllc/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/MyCRWenoPlot.py b/example/sod-shock-tube/hllc/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/MyWenoPlot.py b/example/sod-shock-tube/hllc/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Parallel.cpp b/example/sod-shock-tube/hllc/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Parallel.h b/example/sod-shock-tube/hllc/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Post.cpp b/example/sod-shock-tube/hllc/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Post.h b/example/sod-shock-tube/hllc/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/README.txt b/example/sod-shock-tube/hllc/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Solver.cpp b/example/sod-shock-tube/hllc/cpp/01/Solver.cpp new file mode 100644 index 00000000..a9683ccf --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/hllc/cpp/01/Solver.h b/example/sod-shock-tube/hllc/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/hllc/cpp/01/Vec1d.cpp b/example/sod-shock-tube/hllc/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Vec1d.h b/example/sod-shock-tube/hllc/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/Weno.cpp b/example/sod-shock-tube/hllc/cpp/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/01/Weno.h b/example/sod-shock-tube/hllc/cpp/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/hllc/cpp/01/ZoneState.cpp b/example/sod-shock-tube/hllc/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/ZoneState.h b/example/sod-shock-tube/hllc/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/burgers.json b/example/sod-shock-tube/hllc/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/burgers_ftcs.json b/example/sod-shock-tube/hllc/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/burgers_plot.py b/example/sod-shock-tube/hllc/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/cfd.json b/example/sod-shock-tube/hllc/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/heat.json b/example/sod-shock-tube/hllc/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/heat_plot.py b/example/sod-shock-tube/hllc/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/heaticp.json b/example/sod-shock-tube/hllc/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/hxmath.cpp b/example/sod-shock-tube/hllc/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/hxmath.h b/example/sod-shock-tube/hllc/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/main.cpp b/example/sod-shock-tube/hllc/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/plot.py b/example/sod-shock-tube/hllc/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/plotting2.jl b/example/sod-shock-tube/hllc/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/hllc/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/sod-shock-tube/hllc/cpp/01/sod.json b/example/sod-shock-tube/hllc/cpp/01/sod.json new file mode 100644 index 00000000..494120d1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/01/sod_plot.py b/example/sod-shock-tube/hllc/cpp/01/sod_plot.py new file mode 100644 index 00000000..b18c08da --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/01/sod_plot.py @@ -0,0 +1,168 @@ +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' +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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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/sod-shock-tube/hllc/01/sod_theory.plt b/example/sod-shock-tube/hllc/cpp/01/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/hllc/01/sod_theory.plt rename to example/sod-shock-tube/hllc/cpp/01/sod_theory.plt diff --git a/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/BurgersField.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/BurgersField.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/CMakeLists.txt b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/hllc/cpp/1blocks/hllc/CgnsUtil.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/CgnsUtil.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/hllc/cpp/1blocks/hllc/Grid.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Grid.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/HeatField.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/HeatField.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/LogFile.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/LogFile.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/MyCRWenoPlot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/MyWenoPlot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Parallel.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Parallel.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Post.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Post.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/README.txt b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Solver.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/hllc/cpp/1blocks/hllc/Solver.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Vec1d.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Vec1d.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/ZoneState.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/ZoneState.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers_ftcs.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers_plot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/cfd.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/heat.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/heat_plot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/heaticp.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/hxmath.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/hxmath.h b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/main.cpp b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/plot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/plotting2.jl b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/cpp/1blocks/hllc/sod.json b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sod.json new file mode 100644 index 00000000..95405eb5 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sod_plot.py b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/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/sod-shock-tube/hllc/02/sod_theory.plt b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/hllc/02/sod_theory.plt rename to example/sod-shock-tube/hllc/cpp/1blocks/hllc/sod_theory.plt diff --git a/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/1blocks/hllc/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/BurgersField.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/BurgersField.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/CMakeLists.txt b/example/sod-shock-tube/hllc/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/hllc/cpp/2blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/CgnsUtil.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/hllc/cpp/2blocks/01/Field.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/hllc/cpp/2blocks/01/Field.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/Global.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/hllc/cpp/2blocks/01/Global.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/hllc/cpp/2blocks/01/Grid.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Grid.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/HeatField.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/HeatField.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/LogFile.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/LogFile.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/MyWenoPlot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Parallel.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Parallel.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Post.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Post.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/README.txt b/example/sod-shock-tube/hllc/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Solver.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/hllc/cpp/2blocks/01/Solver.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Vec1d.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Vec1d.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/Weno.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/Weno.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/ZoneState.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/ZoneState.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/burgers.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/burgers_ftcs.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/burgers_plot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/cfd.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/heat.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/heat_plot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/heaticp.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/hxmath.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/hxmath.h b/example/sod-shock-tube/hllc/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/main.cpp b/example/sod-shock-tube/hllc/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/plot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/plotting2.jl b/example/sod-shock-tube/hllc/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/hllc/cpp/2blocks/01/sod.json b/example/sod-shock-tube/hllc/cpp/2blocks/01/sod.json new file mode 100644 index 00000000..5f65b4ce --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/sod_plot.py b/example/sod-shock-tube/hllc/cpp/2blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/2blocks/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/sod-shock-tube/roe/01/sod_theory.plt b/example/sod-shock-tube/hllc/cpp/2blocks/01/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/roe/01/sod_theory.plt rename to example/sod-shock-tube/hllc/cpp/2blocks/01/sod_theory.plt diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/BurgersField.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/hllc/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/hllc/cpp/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/hllc/cpp/4blocks/01/Field.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/hllc/cpp/4blocks/01/Field.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/Global.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/hllc/cpp/4blocks/01/Global.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/hllc/cpp/4blocks/01/Grid.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Grid.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/HeatField.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/HeatField.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/LogFile.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/LogFile.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Parallel.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Parallel.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Post.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Post.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/README.txt b/example/sod-shock-tube/hllc/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Solver.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/hllc/cpp/4blocks/01/Solver.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Vec1d.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/Weno.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/Weno.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/ZoneState.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/burgers.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/burgers_plot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/cfd.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/heat.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/heat_plot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/heaticp.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/hxmath.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/hxmath.h b/example/sod-shock-tube/hllc/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/main.cpp b/example/sod-shock-tube/hllc/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/plot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/plotting2.jl b/example/sod-shock-tube/hllc/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/hllc/cpp/4blocks/01/sod.json b/example/sod-shock-tube/hllc/cpp/4blocks/01/sod.json new file mode 100644 index 00000000..2bab4bed --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/sod_plot.py b/example/sod-shock-tube/hllc/cpp/4blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/hllc/cpp/4blocks/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/sod-shock-tube/roe/02/sod_theory.plt b/example/sod-shock-tube/hllc/cpp/4blocks/01/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/roe/02/sod_theory.plt rename to example/sod-shock-tube/hllc/cpp/4blocks/01/sod_theory.plt diff --git a/example/sod-shock-tube/hllc/cpp/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/hllc/cpp/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/hllc/cpp/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/hllc/01/hllc.py b/example/sod-shock-tube/hllc/python/01/hllc.py similarity index 100% rename from example/sod-shock-tube/hllc/01/hllc.py rename to example/sod-shock-tube/hllc/python/01/hllc.py diff --git a/example/sod-shock-tube/roe/03/sod_theory.plt b/example/sod-shock-tube/hllc/python/01/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/roe/03/sod_theory.plt rename to example/sod-shock-tube/hllc/python/01/sod_theory.plt diff --git a/example/sod-shock-tube/hllc/02/hllc.py b/example/sod-shock-tube/hllc/python/02/hllc.py similarity index 100% rename from example/sod-shock-tube/hllc/02/hllc.py rename to example/sod-shock-tube/hllc/python/02/hllc.py diff --git a/example/sod-shock-tube/rusanov/01/sod_theory.plt b/example/sod-shock-tube/hllc/python/02/sod_theory.plt similarity index 100% rename from example/sod-shock-tube/rusanov/01/sod_theory.plt rename to example/sod-shock-tube/hllc/python/02/sod_theory.plt diff --git a/example/sod-shock-tube/lax/cpp/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/lax/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( 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/sod-shock-tube/lax/cpp/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/01/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/lax/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( 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/sod-shock-tube/lax/cpp/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/01/EulerField.cpp new file mode 100644 index 00000000..58e43d58 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/EulerField.cpp @@ -0,0 +1,762 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/lax/cpp/01/EulerField.h b/example/sod-shock-tube/lax/cpp/01/EulerField.h new file mode 100644 index 00000000..2e3120c9 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/EulerField.h @@ -0,0 +1,43 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/01/Field.cpp b/example/sod-shock-tube/lax/cpp/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/01/Field.h b/example/sod-shock-tube/lax/cpp/01/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/01/Global.cpp b/example/sod-shock-tube/lax/cpp/01/Global.cpp new file mode 100644 index 00000000..ea38d8e1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Global.cpp @@ -0,0 +1,444 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/lax/cpp/01/Global.h b/example/sod-shock-tube/lax/cpp/01/Global.h new file mode 100644 index 00000000..b71fcc5b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Global.h @@ -0,0 +1,174 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/lax/cpp/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Grid.h b/example/sod-shock-tube/lax/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/01/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/lax/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( 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/sod-shock-tube/lax/cpp/01/HeatField.h b/example/sod-shock-tube/lax/cpp/01/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/lax/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( 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/sod-shock-tube/lax/cpp/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/LogFile.h b/example/sod-shock-tube/lax/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Parallel.h b/example/sod-shock-tube/lax/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Post.cpp b/example/sod-shock-tube/lax/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Post.h b/example/sod-shock-tube/lax/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/README.txt b/example/sod-shock-tube/lax/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/01/Solver.cpp new file mode 100644 index 00000000..a9683ccf --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/lax/cpp/01/Solver.h b/example/sod-shock-tube/lax/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/lax/cpp/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/01/Weno.h b/example/sod-shock-tube/lax/cpp/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/burgers.json b/example/sod-shock-tube/lax/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/cfd.json b/example/sod-shock-tube/lax/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/heat.json b/example/sod-shock-tube/lax/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/heaticp.json b/example/sod-shock-tube/lax/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/hxmath.h b/example/sod-shock-tube/lax/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/main.cpp b/example/sod-shock-tube/lax/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/plot.py b/example/sod-shock-tube/lax/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/sod.json b/example/sod-shock-tube/lax/cpp/01/sod.json new file mode 100644 index 00000000..aaf907f1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/01/sod_plot.py new file mode 100644 index 00000000..b18c08da --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/01/sod_plot.py @@ -0,0 +1,168 @@ +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' +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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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/sod-shock-tube/lax/cpp/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/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/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/1blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/1blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/1blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/1blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/1blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/lax/cpp/1blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/1blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/1blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/1blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/1blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/1blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/1blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/1blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/1blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/1blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/1blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/1blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/1blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/1blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/1blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/1blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/1blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/1blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/1blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/1blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/1blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/1blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/1blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/1blocks/01/sod.json new file mode 100644 index 00000000..69046736 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/1blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/1blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/1blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks/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/sod-shock-tube/lax/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/BurgersField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.cpp new file mode 100644 index 00000000..8f8e1a5d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.cpp @@ -0,0 +1,897 @@ +#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; +// for ( int i = 0; i <= nx; ++ 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 ); +// } +// +// 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 ) +{ + auto lambda_value = [&](double xm, bool &flag, int &im ) { + im = -1; + flag = false; + for ( int i = 0; i < nic; ++ i ) + { + if ( std::abs( grid->xcc[ i ] - xm ) < 1.0e-5 ) + { + im = i; + flag = true; + int kkk = 1; + } + } + }; + bool flag1 = false; + int im1 = -1; + bool flag2 = false; + int im2 = -1; + + lambda_value( 0.748046875, flag1, im1 ); + lambda_value( 0.751953125, flag2, im2 ); + + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + 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; + } + } + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } +} + +void EulerField::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 ]; + } +} + +//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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.h new file mode 100644 index 00000000..31d1b075 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/EulerField.h @@ -0,0 +1,46 @@ +#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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.cpp new file mode 100644 index 00000000..76c6dbce --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.cpp @@ -0,0 +1,292 @@ +#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 ); + + auto lambda_value = [&](double xm, bool &flag, int &im ) { + im = -1; + flag = false; + for ( int i = 0; i < nic; ++ i ) + { + if ( std::abs( grid->xcc[ i ] - xm ) < 1.0e-5 ) + { + im = i; + flag = true; + int kkk = 1; + } + } + }; + bool flag1 = false; + int im1 = -1; + bool flag2 = false; + int im2 = -1; + + lambda_value( 0.748046875, flag1, im1 ); + lambda_value( 0.751953125, flag2, im2 ); + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + + 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 ]; + } + } + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } +} + +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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.h new file mode 100644 index 00000000..d9a14eee --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Field.h @@ -0,0 +1,52 @@ +#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 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Grid.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Grid.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/HeatField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/HeatField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/LogFile.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/LogFile.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Parallel.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Parallel.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Post.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Post.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/README.txt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Solver.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Solver.cpp new file mode 100644 index 00000000..8caef3ce --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Solver.cpp @@ -0,0 +1,783 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Solver.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Vec1d.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/ZoneState.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/cfd.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heat.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heat_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heaticp.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/hxmath.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/hxmath.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/main.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/plotting2.jl b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod.json new file mode 100644 index 00000000..505c8736 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "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" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_sort.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_sort.py new file mode 100644 index 00000000..fc56a6e4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_sort.py @@ -0,0 +1,66 @@ +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 ) ) +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 + +#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])) + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_sort_on_xcoor.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_theory.plt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/1blocks/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/BurgersField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.cpp new file mode 100644 index 00000000..eed4d4e4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.cpp @@ -0,0 +1,896 @@ +#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; +// for ( int i = 0; i <= nx; ++ 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 ); +// } +// +// 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 ) +{ + auto lambda_value = [&](double xm, bool &flag, int &im ) { + im = -1; + flag = false; + for ( int i = 0; i < nic; ++ i ) + { + if ( std::abs( grid->xcc[ i ] - xm ) < 1.0e-5 ) + { + im = i; + flag = true; + int kkk = 1; + } + } + }; + bool flag1 = false; + int im1 = -1; + bool flag2 = false; + int im2 = -1; + + lambda_value( 0.748046875, flag1, im1 ); + lambda_value( 0.751953125, flag2, im2 ); + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + 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; + } + } + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } +} + +void EulerField::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 ]; + } +} + +//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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.h new file mode 100644 index 00000000..31d1b075 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/EulerField.h @@ -0,0 +1,46 @@ +#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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.cpp new file mode 100644 index 00000000..76c6dbce --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.cpp @@ -0,0 +1,292 @@ +#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 ); + + auto lambda_value = [&](double xm, bool &flag, int &im ) { + im = -1; + flag = false; + for ( int i = 0; i < nic; ++ i ) + { + if ( std::abs( grid->xcc[ i ] - xm ) < 1.0e-5 ) + { + im = i; + flag = true; + int kkk = 1; + } + } + }; + bool flag1 = false; + int im1 = -1; + bool flag2 = false; + int im2 = -1; + + lambda_value( 0.748046875, flag1, im1 ); + lambda_value( 0.751953125, flag2, im2 ); + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + + 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 ]; + } + } + + if ( flag1 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } + if ( flag2 && ( Global::iter + 1) == 1441 ) + { + int kkk = 1; + } +} + +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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.h new file mode 100644 index 00000000..d9a14eee --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Field.h @@ -0,0 +1,52 @@ +#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 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Grid.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Grid.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/HeatField.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/HeatField.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/LogFile.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/LogFile.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Parallel.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Parallel.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Post.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Post.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/README.txt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Solver.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Solver.cpp new file mode 100644 index 00000000..fc492e48 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Solver.cpp @@ -0,0 +1,783 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Solver.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Vec1d.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/ZoneState.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/cfd.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heat.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heat_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heaticp.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/hxmath.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/hxmath.h b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/main.cpp b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/plotting2.jl b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod.json b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_plot.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_sort.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_sort_on_xcoor.py b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_theory.plt b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/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/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/1blocks_vs_4blocks_debug/4blocks/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/2blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/2blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/lax/cpp/2blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/2blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/2blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/2blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/2blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/2blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/2blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/2blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/2blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/2blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/2blocks/01/sod.json new file mode 100644 index 00000000..f446e4a1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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" : "../sodshocktube1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/2blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/2blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/2blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/2blocks/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/sod-shock-tube/lax/cpp/2blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/lax/cpp/4blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/4blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/4blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/4blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/4blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/4blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/4blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/4blocks/01/sod.json new file mode 100644 index 00000000..04cc4743 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "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/sod-shock-tube/lax/cpp/4blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/4blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/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/sod-shock-tube/lax/cpp/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01a/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/BurgersField.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/4blocks/01a/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/4blocks/01a/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/EulerField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/EulerField.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Field.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Field.cpp new file mode 100644 index 00000000..2170954f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Field.cpp @@ -0,0 +1,253 @@ +#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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/4blocks/01a/Field.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Field.h new file mode 100644 index 00000000..d9a14eee --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Field.h @@ -0,0 +1,52 @@ +#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 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/sod-shock-tube/lax/cpp/4blocks/01a/Global.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/4blocks/01a/Global.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/4blocks/01a/Grid.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Grid.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/HeatField.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/HeatField.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/LogFile.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/LogFile.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Parallel.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Parallel.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Post.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Post.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/README.txt b/example/sod-shock-tube/lax/cpp/4blocks/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Solver.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Solver.cpp new file mode 100644 index 00000000..fc492e48 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Solver.cpp @@ -0,0 +1,783 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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/sod-shock-tube/lax/cpp/4blocks/01a/Solver.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Vec1d.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/Weno.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01a/Weno.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/4blocks/01a/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/ZoneState.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/burgers.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/burgers_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/cfd.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/heat.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/heat_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/heaticp.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/hxmath.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/hxmath.h b/example/sod-shock-tube/lax/cpp/4blocks/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/main.cpp b/example/sod-shock-tube/lax/cpp/4blocks/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/plotting2.jl b/example/sod-shock-tube/lax/cpp/4blocks/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sod.json b/example/sod-shock-tube/lax/cpp/4blocks/01a/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sod_plot.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sod_sort.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sod_sort_on_xcoor.py b/example/sod-shock-tube/lax/cpp/4blocks/01a/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sod_theory.plt b/example/sod-shock-tube/lax/cpp/4blocks/01a/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/4blocks/01a/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/sod-shock-tube/lax/cpp/4blocks/01a/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/4blocks/01a/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/4blocks/01a/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sod.json new file mode 100644 index 00000000..316e0f17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/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/sod-shock-tube/lax/cpp/old/1blocks/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/01debug/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod.json new file mode 100644 index 00000000..feb6e44b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/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/sod-shock-tube/lax/cpp/old/1blocks/01debug/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/01debug/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/02/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/02/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/02/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/02/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/02/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/02/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/02/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/02/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/02/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sod.json new file mode 100644 index 00000000..e930df28 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02/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/sod-shock-tube/lax/cpp/old/1blocks/02/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/02/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/02debug/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod.json new file mode 100644 index 00000000..20f1c44b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/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/sod-shock-tube/lax/cpp/old/1blocks/02debug/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/02debug/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final.csv new file mode 100644 index 00000000..6a75c104 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 -0.0000000000000000026053234 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 -0.0000000000000000371850698 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000001084761910 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 -0.0000000000000001726618848 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 -0.0000000000000009779436520 2.5000000000000008881784197 +0.2402343750000000000000000 0.9999999999999913402604079 0.0000000000000084476425855 2.4999999999999693578445203 +0.2441406250000000000000000 0.9999999999999684696661006 0.0000000000000350870739870 2.4999999999998925304112163 +0.2480468750000000000000000 0.9999999999999844568776552 0.0000000000000165471192304 2.4999999999999462652056081 +0.2519531250000000000000000 1.0000000000001121325254871 -0.0000000000001417326700448 2.5000000000004054534485931 +0.2558593750000000000000000 1.0000000000001481037514850 -0.0000000000001986345902575 2.5000000000005502265310042 +0.2597656250000000000000000 0.9999999999994879651410429 0.0000000000006009500452819 2.4999999999982134291087732 +0.2636718750000000000000000 0.9999999999985795806622946 0.0000000000017495902208490 2.4999999999949387152753388 +0.2675781250000000000000000 1.0000000000010802470029603 -0.0000000000012186684254327 2.5000000000037059244561988 +0.2714843750000000000000000 1.0000000000085496054680334 -0.0000000000104376728889595 2.5000000000303517211364124 +0.2753906250000000000000000 1.0000000000041566750041966 -0.0000000000056185176807351 2.5000000000154809498553732 +0.2792968750000000000000000 0.9999999999614134216230354 0.0000000000463369741983873 2.4999999998640625165080564 +0.2832031250000000000000000 0.9999999999329209909859628 0.0000000000833551515218763 2.4999999997599586798457949 +0.2871093750000000000000000 1.0000000001074762501218629 -0.0000000001256870255872402 2.5000000003741869036844037 +0.2910156250000000000000000 1.0000000004585070101370547 -0.0000000005586989191878421 2.5000000016261170188158758 +0.2949218750000000000000000 1.0000000000736961602854080 -0.0000000001135054070289231 2.5000000002927418307763219 +0.2988281250000000000000000 0.9999999979513574110967511 0.0000000024608903051633518 2.4999999927812721622899517 +0.3027343750000000000000000 0.9999999969284010248316008 0.0000000037919083145728369 2.4999999890415200987092703 +0.3066406250000000000000000 1.0000000050544102236926847 -0.0000000059282322233400505 2.5000000176207266555650222 +0.3105468750000000000000000 1.0000000206443397932076778 -0.0000000249897076268249678 2.5000000729967917223461882 +0.3144531250000000000000000 1.0000000074396080407268528 -0.0000000097653634675508859 2.5000000273103881731628917 +0.3183593750000000000000000 0.9999999226664904039552084 0.0000000923250919115048605 2.4999997282520523000926005 +0.3222656250000000000000000 0.9999998524035175195834313 0.0000001793755014524831681 2.4999994771596250053846688 +0.3261718750000000000000000 1.0000000874931413985535755 -0.0000000996367500547992999 2.5000003011484164261446494 +0.3300781250000000000000000 1.0000007219438542538370029 -0.0000008646827176211969635 2.5000025405962764679657084 +0.3339843750000000000000000 1.0000008029385074603823114 -0.0000009779924413888793890 2.5000028462938668205595150 +0.3378906250000000000000000 0.9999984916182118599436990 0.0000017738580796792794980 2.4999947387594976255797974 +0.3417968750000000000000000 0.9999941617209262556542626 0.0000069860423752591740688 2.4999794753799524649195973 +0.3457031250000000000000000 0.9999944372610326537298420 0.0000067609801555147608232 2.4999802584565244956138486 +0.3496093750000000000000000 1.0000080794859085298043055 -0.0000097094213546742262752 2.5000294188560459041070771 +0.3535156250000000000000000 1.0000275324728984394084819 -0.0000335454907291686296841 2.5001013932677955686756377 +0.3574218750000000000000000 1.0000071920508804002025727 -0.0000088517724013398912860 2.5000235137643409544239148 +0.3613281250000000000000000 0.9998397103742842073614838 0.0001943302780465496154647 2.4994172579662654598564586 +0.3652343750000000000000000 0.9993025451859598451420652 0.0008335537703958162663448 2.4975298055593069257440675 +0.3691406250000000000000000 0.9979431479907459046074791 0.0024377672837875424827203 2.4927920010961259755788433 +0.3730468750000000000000000 0.9947905210502346884382519 0.0061458087275335394894515 2.4818170098879828167071082 +0.3769531250000000000000000 0.9877942600165647846210959 0.0143515843945611672877183 2.4574676950956932941494415 +0.3808593750000000000000000 0.9751165808281625491105160 0.0290264998374759157495628 2.4137406496531887967194052 +0.3847656250000000000000000 0.9575216018801875339505614 0.0489853898453691538605881 2.3538301511219938966235077 +0.3886718750000000000000000 0.9368861055895113532088203 0.0718086455968739434396753 2.2846686223737342480433199 +0.3925781250000000000000000 0.9147936744309576040379284 0.0955439436799453700732698 2.2119357927684002440571476 +0.3964843750000000000000000 0.8921804328663764938056602 0.1190730784535633801635157 2.1388958893496314850324325 +0.4003906250000000000000000 0.8694948335006998929586075 0.1418794411725775861388144 2.0670549674822988883704511 +0.4042968750000000000000000 0.8469447535402906401813539 0.1637394772366942974350934 1.9970643398141330049355702 +0.4082031250000000000000000 0.8246402396802287038113377 0.1845501434971708598631324 1.9292262995433544503498524 +0.4121093750000000000000000 0.8026478240066045044542875 0.2042626641676975329797727 1.8636874458574788082643181 +0.4160156250000000000000000 0.7810088718511971617175504 0.2228590953190253964866230 1.8005074289088658368029883 +0.4199218750000000000000000 0.7597484750056098246062675 0.2403411570291088539264024 1.7396886267718421059669254 +0.4238281250000000000000000 0.7388819920008485864215686 0.2567218928819124945661656 1.6812018570124653837893902 +0.4277343750000000000000000 0.7184195083398414727327008 0.2720207137501979843818845 1.6250013281783060037355426 +0.4316406250000000000000000 0.6983680625782477946472682 0.2862609047738396417237539 1.5710320723696289402226967 +0.4355468750000000000000000 0.6787327721789500056814859 0.2994683304925968014842397 1.5192338311245447979302980 +0.4394531250000000000000000 0.6595174495511335610586912 0.3116707618189175077461073 1.4695433313520898099824308 +0.4433593750000000000000000 0.6407249146253184424182336 0.3228973119315353135228008 1.4218953994589467182407816 +0.4472656250000000000000000 0.6223572906229063450567196 0.3331783019167262605009228 1.3762243004980403426884550 +0.4511718750000000000000000 0.6044161544049204692896637 0.3425447569574249784274400 1.3324638399296084845246924 +0.4550781250000000000000000 0.5869023235564264640018450 0.3510288344348490019442011 1.2905479445599705723424222 +0.4589843750000000000000000 0.5698150079348964780479037 0.3586634859058911994900143 1.2504075696859962008034017 +0.4628906250000000000000000 0.5531500339393202736459898 0.3654831248150911537919683 1.2119687892631119119357663 +0.4667968750000000000000000 0.5369016533166807159105360 0.3715236203180566909587412 1.1751566129380464076348289 +0.4707031250000000000000000 0.5210660407311135111640965 0.3768149896219734618085795 1.1398998801754867127300486 +0.4746093750000000000000000 0.5056627321441082845154824 0.3813921504872469503411025 1.1061907702076732018525718 +0.4785156250000000000000000 0.4907440291702241941251827 0.3852632588991805606681851 1.0740647929209725663923791 +0.4824218750000000000000000 0.4764290566543402660748541 0.3884623861782131037934107 1.0437490978261607654786758 +0.4863281250000000000000000 0.4629358685905710091290644 0.3909808799128849932102980 1.0155756694256055094882640 +0.4902343750000000000000000 0.4506807653325203832928025 0.3928858193094593720395835 0.9903343888405398143248703 +0.4941406250000000000000000 0.4403157584596712470492719 0.3941619961906518421201895 0.9692594275144634785590370 +0.4980468750000000000000000 0.4327072511864961112948436 0.3948172648327121225797498 0.9540832306507658344685296 +0.5019531250000000000000000 0.4288678424703177283205946 0.3953414890972404283076003 0.9460965183973053527211050 +0.5058593750000000000000000 0.4274442051798746922131045 0.3955384025209749965235062 0.9429764168678630431585930 +0.5097656250000000000000000 0.4269604798010757096271561 0.3952617109797000871651562 0.9425051148786431909343264 +0.5136718750000000000000000 0.4271207269692225416690690 0.3950816376714076927356700 0.9431308119459117511595991 +0.5175781250000000000000000 0.4275665819266847300639256 0.3952328540123453692878286 0.9437666578382298832039510 +0.5214843750000000000000000 0.4276250725815268771690114 0.3955775082590681224203877 0.9434066837109179592957275 +0.5253906250000000000000000 0.4269824502405373811697586 0.3958049518708501857133797 0.9418634845765442298315406 +0.5292968750000000000000000 0.4258672992810153545839569 0.3956492960839061434619168 0.9400213811688246101638811 +0.5332031250000000000000000 0.4250211573337731585375820 0.3952626194247728097508343 0.9389760901025794304075589 +0.5371093750000000000000000 0.4250146410464261670369979 0.3950977267326177266859588 0.9392505134181317050234838 +0.5410156250000000000000000 0.4259322898014054614712620 0.3954454565924437892121546 0.9404121635153073199830942 +0.5449218750000000000000000 0.4270411521047665637240698 0.3959584849099279102446758 0.9416638903077076960812519 +0.5488281250000000000000000 0.4275740703790540386819430 0.3961371204431222703412629 0.9423258598784108874824028 +0.5527343750000000000000000 0.4269656322838632500626943 0.3955803579755073906554230 0.9420258066356521631234955 +0.5566406250000000000000000 0.4257290792144119428996873 0.3946386064319277742207248 0.9411468552663416753389924 +0.5605468750000000000000000 0.4247300967181704134389975 0.3939857068949442209238043 0.9403404043822869429192224 +0.5644531250000000000000000 0.4245785461635636637289792 0.3939903026292335685987211 0.9401110211538560301747225 +0.5683593750000000000000000 0.4247875112944129449843444 0.3941673659561364950754125 0.9403145783256962042528926 +0.5722656250000000000000000 0.4247680404318103231098291 0.3940193842932155909863923 0.9406240109753841727169288 +0.5761718750000000000000000 0.4238121919816801308478205 0.3929350247972792642414674 0.9405443567970075413597897 +0.5800781250000000000000000 0.4201496989971185702650303 0.3895194890829591360947859 0.9389045461820110238804205 +0.5839843750000000000000000 0.4099044207279917140240855 0.3802972065433952719715194 0.9338575931363765070258864 +0.5878906250000000000000000 0.3852569683873666717133233 0.3573407724518367634125582 0.9227577993643928389033704 +0.5917968750000000000000000 0.3451862566139008992038839 0.3201853626684522668988109 0.9062303940476048591534664 +0.5957031250000000000000000 0.3022959461585349449919136 0.2805220859842934011396665 0.8882896378856103281052015 +0.5996093750000000000000000 0.2714392134943592327367412 0.2514335916428530048882806 0.8733386481987998051224054 +0.6035156250000000000000000 0.2594983153202207737386686 0.2403347171501430123985443 0.8678212429052906129456346 +0.6074218750000000000000000 0.2575111413450749675568829 0.2389356644313427591175270 0.8685864914874031894598261 +0.6113281250000000000000000 0.2590984716096734197243734 0.2406344402033220586378803 0.8704977299403195978300118 +0.6152343750000000000000000 0.2622939242027405581936250 0.2435891800726981137881211 0.8718545057212330195994809 +0.6191406250000000000000000 0.2656306618713255573993592 0.2464049908872641136969861 0.8721382547637012150332225 +0.6230468750000000000000000 0.2677473897934973812162696 0.2480292259114483532922435 0.8718723362064541015925556 +0.6269531250000000000000000 0.2681326752959513060048380 0.2483534552181367593970407 0.8717425666473973544512432 +0.6308593750000000000000000 0.2674350821636979902429232 0.2479722845452582979941525 0.8726248275701826706551856 +0.6347656250000000000000000 0.2662181537264394770581077 0.2471548454267822880758843 0.8733997929963908113393245 +0.6386718750000000000000000 0.2649509608604191379654935 0.2460455099771151066256891 0.8731571224066630998450478 +0.6425781250000000000000000 0.2641023808552972473862042 0.2451220179876666960261389 0.8722692651724717194383629 +0.6464843750000000000000000 0.2639935134876734701414591 0.2448197066745841643520265 0.8714580344583838789063179 +0.6503906250000000000000000 0.2645441865907449119355022 0.2452750237113880404926647 0.8714485118355433934667076 +0.6542968750000000000000000 0.2653700208604344301654976 0.2461056188533031485743408 0.8720485233537217384380824 +0.6582031250000000000000000 0.2660680403799107751616759 0.2467972543310016086959280 0.8725156824667156252317568 +0.6621093750000000000000000 0.2662807620411461462239799 0.2469032908869638054394358 0.8722199732891962042913292 +0.6660156250000000000000000 0.2656437898193811375513462 0.2456098774400455597710646 0.8691704776833132362057199 +0.6699218750000000000000000 0.2621501785659506866821289 0.2375178300913848572495368 0.8495559183488908816528351 +0.6738281250000000000000000 0.2383635484459319386907339 0.1807563795633301273468874 0.7075750714773634264531665 +0.6777343750000000000000000 0.1623064126893439262921959 0.0465661773974898191008620 0.3724345308146151389827594 +0.6816406250000000000000000 0.1292290250300576759379112 0.0044198407871362003704330 0.2623254020250173623729495 +0.6855468750000000000000000 0.1253930609061905121492941 0.0004133005058814855905633 0.2510946464757287110991513 +0.6894531250000000000000000 0.1250095130986038083342748 0.0000049715570442126065412 0.2500558405654013105490208 +0.6933593750000000000000000 0.1249891993400437939509828 -0.0000083205016085009311653 0.2499716797133632317784446 +0.6972656250000000000000000 0.1250035869498220819640011 0.0000020712795457082307101 0.2500058124783873791940891 +0.7011718750000000000000000 0.1250011750564252455131253 0.0000013431814089601999501 0.2500033947683406032602704 +0.7050781250000000000000000 0.1249997621477042936133373 -0.0000002255204394830138163 0.2499993843538668158998917 +0.7089843750000000000000000 0.1249999024416525855718518 -0.0000000998243312504421296 0.2499997234151252745171234 +0.7128906250000000000000000 0.1250000358418345003386207 0.0000000333074211363637352 0.2500000956265198137629113 +0.7167968750000000000000000 0.1250000082671087475727489 0.0000000084326149885072269 0.2500000228366717758277105 +0.7207031250000000000000000 0.1249999957245934850691427 -0.0000000039907690187135336 0.2499999886108933144779343 +0.7246093750000000000000000 0.1249999994921484058885142 -0.0000000005556880525799580 0.2499999985640729283087325 +0.7285156250000000000000000 0.1250000004859229962850264 0.0000000004606334479776801 0.2500000012980389541006332 +0.7324218750000000000000000 0.1250000000164448177297771 0.0000000000231558144806836 0.2500000000524876253571449 +0.7363281250000000000000000 0.1249999999485154889011795 -0.0000000000493665305079105 0.2499999998618167296182691 +0.7402343750000000000000000 0.1250000000022173096692057 0.0000000000013616739143648 0.2500000000050764392689473 +0.7441406250000000000000000 0.1250000000051646187326782 0.0000000000050085694406713 0.2500000000139289135780984 +0.7480468750000000000000000 0.1249999999993786914398441 -0.0000000000005189918124889 0.2499999999984183207679678 +0.7519531250000000000000000 0.1249999999995118210582845 -0.0000000000004795462397548 0.2499999999986764753767687 +0.7558593750000000000000000 0.1250000000000991984272503 0.0000000000000889985862784 0.2500000000002590705427963 +0.7597656250000000000000000 0.1250000000000414668299697 0.0000000000000418014067805 0.2500000000001137423488728 +0.7636718750000000000000000 0.1249999999999853866894384 -0.0000000000000129433352924 0.2499999999999617250612260 +0.7675781250000000000000000 0.1249999999999959893193235 -0.0000000000000038285522900 0.2499999999999889532809050 +0.7714843750000000000000000 0.1250000000000011934897515 0.0000000000000012759275118 0.2500000000000030531133177 +0.7753906250000000000000000 0.1250000000000000277555756 0.0000000000000000537644003 0.2499999999999998057109707 +0.7792968750000000000000000 0.1249999999999997224442438 -0.0000000000000002486603516 0.2499999999999990007992778 +0.7832031250000000000000000 0.1250000000000000000000000 -0.0000000000000000386357613 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000162832710 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 -0.0000000000000000027829590 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final0.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final0.csv new file mode 100644 index 00000000..8240d0e2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final0.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2402343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2441406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2480468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2519531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2558593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2597656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2636718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2675781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2714843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2753906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2792968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2832031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2871093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2910156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2949218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2988281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3027343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3066406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3105468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3144531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3183593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3222656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3261718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3300781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3339843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3378906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3417968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3457031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3496093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3535156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3574218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3613281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3652343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3691406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3730468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3769531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3808593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3847656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3886718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3925781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3964843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4003906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4042968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4082031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4121093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4160156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4199218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4238281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4277343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4316406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4355468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4394531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4433593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4472656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4511718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4550781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4589843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4628906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4667968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4707031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4746093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4785156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4824218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4863281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4902343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4941406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.4980468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.5019531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5058593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5097656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5136718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5175781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5214843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5253906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5292968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5332031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5371093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5410156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5449218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5488281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5527343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5566406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5605468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5644531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5683593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5722656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5761718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5800781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5839843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5878906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5917968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5957031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.5996093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6035156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6074218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6113281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6152343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6191406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6230468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6269531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6308593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6347656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6386718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6425781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6464843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6503906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6542968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6582031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6621093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6660156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6699218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6738281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6777343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6816406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6855468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6894531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6933593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.6972656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7011718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7050781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7089843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7128906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7167968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7207031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7246093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7285156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7324218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7363281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7402343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7441406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7480468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7519531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7558593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7597656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7636718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7675781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7714843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7753906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7792968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7832031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7910156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000555111512 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final1000.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final1000.csv new file mode 100644 index 00000000..6a75c104 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final1000.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 -0.0000000000000000026053234 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 -0.0000000000000000371850698 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000001084761910 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 -0.0000000000000001726618848 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 -0.0000000000000009779436520 2.5000000000000008881784197 +0.2402343750000000000000000 0.9999999999999913402604079 0.0000000000000084476425855 2.4999999999999693578445203 +0.2441406250000000000000000 0.9999999999999684696661006 0.0000000000000350870739870 2.4999999999998925304112163 +0.2480468750000000000000000 0.9999999999999844568776552 0.0000000000000165471192304 2.4999999999999462652056081 +0.2519531250000000000000000 1.0000000000001121325254871 -0.0000000000001417326700448 2.5000000000004054534485931 +0.2558593750000000000000000 1.0000000000001481037514850 -0.0000000000001986345902575 2.5000000000005502265310042 +0.2597656250000000000000000 0.9999999999994879651410429 0.0000000000006009500452819 2.4999999999982134291087732 +0.2636718750000000000000000 0.9999999999985795806622946 0.0000000000017495902208490 2.4999999999949387152753388 +0.2675781250000000000000000 1.0000000000010802470029603 -0.0000000000012186684254327 2.5000000000037059244561988 +0.2714843750000000000000000 1.0000000000085496054680334 -0.0000000000104376728889595 2.5000000000303517211364124 +0.2753906250000000000000000 1.0000000000041566750041966 -0.0000000000056185176807351 2.5000000000154809498553732 +0.2792968750000000000000000 0.9999999999614134216230354 0.0000000000463369741983873 2.4999999998640625165080564 +0.2832031250000000000000000 0.9999999999329209909859628 0.0000000000833551515218763 2.4999999997599586798457949 +0.2871093750000000000000000 1.0000000001074762501218629 -0.0000000001256870255872402 2.5000000003741869036844037 +0.2910156250000000000000000 1.0000000004585070101370547 -0.0000000005586989191878421 2.5000000016261170188158758 +0.2949218750000000000000000 1.0000000000736961602854080 -0.0000000001135054070289231 2.5000000002927418307763219 +0.2988281250000000000000000 0.9999999979513574110967511 0.0000000024608903051633518 2.4999999927812721622899517 +0.3027343750000000000000000 0.9999999969284010248316008 0.0000000037919083145728369 2.4999999890415200987092703 +0.3066406250000000000000000 1.0000000050544102236926847 -0.0000000059282322233400505 2.5000000176207266555650222 +0.3105468750000000000000000 1.0000000206443397932076778 -0.0000000249897076268249678 2.5000000729967917223461882 +0.3144531250000000000000000 1.0000000074396080407268528 -0.0000000097653634675508859 2.5000000273103881731628917 +0.3183593750000000000000000 0.9999999226664904039552084 0.0000000923250919115048605 2.4999997282520523000926005 +0.3222656250000000000000000 0.9999998524035175195834313 0.0000001793755014524831681 2.4999994771596250053846688 +0.3261718750000000000000000 1.0000000874931413985535755 -0.0000000996367500547992999 2.5000003011484164261446494 +0.3300781250000000000000000 1.0000007219438542538370029 -0.0000008646827176211969635 2.5000025405962764679657084 +0.3339843750000000000000000 1.0000008029385074603823114 -0.0000009779924413888793890 2.5000028462938668205595150 +0.3378906250000000000000000 0.9999984916182118599436990 0.0000017738580796792794980 2.4999947387594976255797974 +0.3417968750000000000000000 0.9999941617209262556542626 0.0000069860423752591740688 2.4999794753799524649195973 +0.3457031250000000000000000 0.9999944372610326537298420 0.0000067609801555147608232 2.4999802584565244956138486 +0.3496093750000000000000000 1.0000080794859085298043055 -0.0000097094213546742262752 2.5000294188560459041070771 +0.3535156250000000000000000 1.0000275324728984394084819 -0.0000335454907291686296841 2.5001013932677955686756377 +0.3574218750000000000000000 1.0000071920508804002025727 -0.0000088517724013398912860 2.5000235137643409544239148 +0.3613281250000000000000000 0.9998397103742842073614838 0.0001943302780465496154647 2.4994172579662654598564586 +0.3652343750000000000000000 0.9993025451859598451420652 0.0008335537703958162663448 2.4975298055593069257440675 +0.3691406250000000000000000 0.9979431479907459046074791 0.0024377672837875424827203 2.4927920010961259755788433 +0.3730468750000000000000000 0.9947905210502346884382519 0.0061458087275335394894515 2.4818170098879828167071082 +0.3769531250000000000000000 0.9877942600165647846210959 0.0143515843945611672877183 2.4574676950956932941494415 +0.3808593750000000000000000 0.9751165808281625491105160 0.0290264998374759157495628 2.4137406496531887967194052 +0.3847656250000000000000000 0.9575216018801875339505614 0.0489853898453691538605881 2.3538301511219938966235077 +0.3886718750000000000000000 0.9368861055895113532088203 0.0718086455968739434396753 2.2846686223737342480433199 +0.3925781250000000000000000 0.9147936744309576040379284 0.0955439436799453700732698 2.2119357927684002440571476 +0.3964843750000000000000000 0.8921804328663764938056602 0.1190730784535633801635157 2.1388958893496314850324325 +0.4003906250000000000000000 0.8694948335006998929586075 0.1418794411725775861388144 2.0670549674822988883704511 +0.4042968750000000000000000 0.8469447535402906401813539 0.1637394772366942974350934 1.9970643398141330049355702 +0.4082031250000000000000000 0.8246402396802287038113377 0.1845501434971708598631324 1.9292262995433544503498524 +0.4121093750000000000000000 0.8026478240066045044542875 0.2042626641676975329797727 1.8636874458574788082643181 +0.4160156250000000000000000 0.7810088718511971617175504 0.2228590953190253964866230 1.8005074289088658368029883 +0.4199218750000000000000000 0.7597484750056098246062675 0.2403411570291088539264024 1.7396886267718421059669254 +0.4238281250000000000000000 0.7388819920008485864215686 0.2567218928819124945661656 1.6812018570124653837893902 +0.4277343750000000000000000 0.7184195083398414727327008 0.2720207137501979843818845 1.6250013281783060037355426 +0.4316406250000000000000000 0.6983680625782477946472682 0.2862609047738396417237539 1.5710320723696289402226967 +0.4355468750000000000000000 0.6787327721789500056814859 0.2994683304925968014842397 1.5192338311245447979302980 +0.4394531250000000000000000 0.6595174495511335610586912 0.3116707618189175077461073 1.4695433313520898099824308 +0.4433593750000000000000000 0.6407249146253184424182336 0.3228973119315353135228008 1.4218953994589467182407816 +0.4472656250000000000000000 0.6223572906229063450567196 0.3331783019167262605009228 1.3762243004980403426884550 +0.4511718750000000000000000 0.6044161544049204692896637 0.3425447569574249784274400 1.3324638399296084845246924 +0.4550781250000000000000000 0.5869023235564264640018450 0.3510288344348490019442011 1.2905479445599705723424222 +0.4589843750000000000000000 0.5698150079348964780479037 0.3586634859058911994900143 1.2504075696859962008034017 +0.4628906250000000000000000 0.5531500339393202736459898 0.3654831248150911537919683 1.2119687892631119119357663 +0.4667968750000000000000000 0.5369016533166807159105360 0.3715236203180566909587412 1.1751566129380464076348289 +0.4707031250000000000000000 0.5210660407311135111640965 0.3768149896219734618085795 1.1398998801754867127300486 +0.4746093750000000000000000 0.5056627321441082845154824 0.3813921504872469503411025 1.1061907702076732018525718 +0.4785156250000000000000000 0.4907440291702241941251827 0.3852632588991805606681851 1.0740647929209725663923791 +0.4824218750000000000000000 0.4764290566543402660748541 0.3884623861782131037934107 1.0437490978261607654786758 +0.4863281250000000000000000 0.4629358685905710091290644 0.3909808799128849932102980 1.0155756694256055094882640 +0.4902343750000000000000000 0.4506807653325203832928025 0.3928858193094593720395835 0.9903343888405398143248703 +0.4941406250000000000000000 0.4403157584596712470492719 0.3941619961906518421201895 0.9692594275144634785590370 +0.4980468750000000000000000 0.4327072511864961112948436 0.3948172648327121225797498 0.9540832306507658344685296 +0.5019531250000000000000000 0.4288678424703177283205946 0.3953414890972404283076003 0.9460965183973053527211050 +0.5058593750000000000000000 0.4274442051798746922131045 0.3955384025209749965235062 0.9429764168678630431585930 +0.5097656250000000000000000 0.4269604798010757096271561 0.3952617109797000871651562 0.9425051148786431909343264 +0.5136718750000000000000000 0.4271207269692225416690690 0.3950816376714076927356700 0.9431308119459117511595991 +0.5175781250000000000000000 0.4275665819266847300639256 0.3952328540123453692878286 0.9437666578382298832039510 +0.5214843750000000000000000 0.4276250725815268771690114 0.3955775082590681224203877 0.9434066837109179592957275 +0.5253906250000000000000000 0.4269824502405373811697586 0.3958049518708501857133797 0.9418634845765442298315406 +0.5292968750000000000000000 0.4258672992810153545839569 0.3956492960839061434619168 0.9400213811688246101638811 +0.5332031250000000000000000 0.4250211573337731585375820 0.3952626194247728097508343 0.9389760901025794304075589 +0.5371093750000000000000000 0.4250146410464261670369979 0.3950977267326177266859588 0.9392505134181317050234838 +0.5410156250000000000000000 0.4259322898014054614712620 0.3954454565924437892121546 0.9404121635153073199830942 +0.5449218750000000000000000 0.4270411521047665637240698 0.3959584849099279102446758 0.9416638903077076960812519 +0.5488281250000000000000000 0.4275740703790540386819430 0.3961371204431222703412629 0.9423258598784108874824028 +0.5527343750000000000000000 0.4269656322838632500626943 0.3955803579755073906554230 0.9420258066356521631234955 +0.5566406250000000000000000 0.4257290792144119428996873 0.3946386064319277742207248 0.9411468552663416753389924 +0.5605468750000000000000000 0.4247300967181704134389975 0.3939857068949442209238043 0.9403404043822869429192224 +0.5644531250000000000000000 0.4245785461635636637289792 0.3939903026292335685987211 0.9401110211538560301747225 +0.5683593750000000000000000 0.4247875112944129449843444 0.3941673659561364950754125 0.9403145783256962042528926 +0.5722656250000000000000000 0.4247680404318103231098291 0.3940193842932155909863923 0.9406240109753841727169288 +0.5761718750000000000000000 0.4238121919816801308478205 0.3929350247972792642414674 0.9405443567970075413597897 +0.5800781250000000000000000 0.4201496989971185702650303 0.3895194890829591360947859 0.9389045461820110238804205 +0.5839843750000000000000000 0.4099044207279917140240855 0.3802972065433952719715194 0.9338575931363765070258864 +0.5878906250000000000000000 0.3852569683873666717133233 0.3573407724518367634125582 0.9227577993643928389033704 +0.5917968750000000000000000 0.3451862566139008992038839 0.3201853626684522668988109 0.9062303940476048591534664 +0.5957031250000000000000000 0.3022959461585349449919136 0.2805220859842934011396665 0.8882896378856103281052015 +0.5996093750000000000000000 0.2714392134943592327367412 0.2514335916428530048882806 0.8733386481987998051224054 +0.6035156250000000000000000 0.2594983153202207737386686 0.2403347171501430123985443 0.8678212429052906129456346 +0.6074218750000000000000000 0.2575111413450749675568829 0.2389356644313427591175270 0.8685864914874031894598261 +0.6113281250000000000000000 0.2590984716096734197243734 0.2406344402033220586378803 0.8704977299403195978300118 +0.6152343750000000000000000 0.2622939242027405581936250 0.2435891800726981137881211 0.8718545057212330195994809 +0.6191406250000000000000000 0.2656306618713255573993592 0.2464049908872641136969861 0.8721382547637012150332225 +0.6230468750000000000000000 0.2677473897934973812162696 0.2480292259114483532922435 0.8718723362064541015925556 +0.6269531250000000000000000 0.2681326752959513060048380 0.2483534552181367593970407 0.8717425666473973544512432 +0.6308593750000000000000000 0.2674350821636979902429232 0.2479722845452582979941525 0.8726248275701826706551856 +0.6347656250000000000000000 0.2662181537264394770581077 0.2471548454267822880758843 0.8733997929963908113393245 +0.6386718750000000000000000 0.2649509608604191379654935 0.2460455099771151066256891 0.8731571224066630998450478 +0.6425781250000000000000000 0.2641023808552972473862042 0.2451220179876666960261389 0.8722692651724717194383629 +0.6464843750000000000000000 0.2639935134876734701414591 0.2448197066745841643520265 0.8714580344583838789063179 +0.6503906250000000000000000 0.2645441865907449119355022 0.2452750237113880404926647 0.8714485118355433934667076 +0.6542968750000000000000000 0.2653700208604344301654976 0.2461056188533031485743408 0.8720485233537217384380824 +0.6582031250000000000000000 0.2660680403799107751616759 0.2467972543310016086959280 0.8725156824667156252317568 +0.6621093750000000000000000 0.2662807620411461462239799 0.2469032908869638054394358 0.8722199732891962042913292 +0.6660156250000000000000000 0.2656437898193811375513462 0.2456098774400455597710646 0.8691704776833132362057199 +0.6699218750000000000000000 0.2621501785659506866821289 0.2375178300913848572495368 0.8495559183488908816528351 +0.6738281250000000000000000 0.2383635484459319386907339 0.1807563795633301273468874 0.7075750714773634264531665 +0.6777343750000000000000000 0.1623064126893439262921959 0.0465661773974898191008620 0.3724345308146151389827594 +0.6816406250000000000000000 0.1292290250300576759379112 0.0044198407871362003704330 0.2623254020250173623729495 +0.6855468750000000000000000 0.1253930609061905121492941 0.0004133005058814855905633 0.2510946464757287110991513 +0.6894531250000000000000000 0.1250095130986038083342748 0.0000049715570442126065412 0.2500558405654013105490208 +0.6933593750000000000000000 0.1249891993400437939509828 -0.0000083205016085009311653 0.2499716797133632317784446 +0.6972656250000000000000000 0.1250035869498220819640011 0.0000020712795457082307101 0.2500058124783873791940891 +0.7011718750000000000000000 0.1250011750564252455131253 0.0000013431814089601999501 0.2500033947683406032602704 +0.7050781250000000000000000 0.1249997621477042936133373 -0.0000002255204394830138163 0.2499993843538668158998917 +0.7089843750000000000000000 0.1249999024416525855718518 -0.0000000998243312504421296 0.2499997234151252745171234 +0.7128906250000000000000000 0.1250000358418345003386207 0.0000000333074211363637352 0.2500000956265198137629113 +0.7167968750000000000000000 0.1250000082671087475727489 0.0000000084326149885072269 0.2500000228366717758277105 +0.7207031250000000000000000 0.1249999957245934850691427 -0.0000000039907690187135336 0.2499999886108933144779343 +0.7246093750000000000000000 0.1249999994921484058885142 -0.0000000005556880525799580 0.2499999985640729283087325 +0.7285156250000000000000000 0.1250000004859229962850264 0.0000000004606334479776801 0.2500000012980389541006332 +0.7324218750000000000000000 0.1250000000164448177297771 0.0000000000231558144806836 0.2500000000524876253571449 +0.7363281250000000000000000 0.1249999999485154889011795 -0.0000000000493665305079105 0.2499999998618167296182691 +0.7402343750000000000000000 0.1250000000022173096692057 0.0000000000013616739143648 0.2500000000050764392689473 +0.7441406250000000000000000 0.1250000000051646187326782 0.0000000000050085694406713 0.2500000000139289135780984 +0.7480468750000000000000000 0.1249999999993786914398441 -0.0000000000005189918124889 0.2499999999984183207679678 +0.7519531250000000000000000 0.1249999999995118210582845 -0.0000000000004795462397548 0.2499999999986764753767687 +0.7558593750000000000000000 0.1250000000000991984272503 0.0000000000000889985862784 0.2500000000002590705427963 +0.7597656250000000000000000 0.1250000000000414668299697 0.0000000000000418014067805 0.2500000000001137423488728 +0.7636718750000000000000000 0.1249999999999853866894384 -0.0000000000000129433352924 0.2499999999999617250612260 +0.7675781250000000000000000 0.1249999999999959893193235 -0.0000000000000038285522900 0.2499999999999889532809050 +0.7714843750000000000000000 0.1250000000000011934897515 0.0000000000000012759275118 0.2500000000000030531133177 +0.7753906250000000000000000 0.1250000000000000277555756 0.0000000000000000537644003 0.2499999999999998057109707 +0.7792968750000000000000000 0.1249999999999997224442438 -0.0000000000000002486603516 0.2499999999999990007992778 +0.7832031250000000000000000 0.1250000000000000000000000 -0.0000000000000000386357613 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000162832710 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 -0.0000000000000000027829590 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final200.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final200.csv new file mode 100644 index 00000000..7181bac4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final200.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2402343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2441406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2480468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2519531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2558593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2597656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2636718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2675781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2714843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2753906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2792968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2832031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2871093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2910156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2949218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2988281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3027343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3066406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3105468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3144531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3183593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3222656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3261718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3300781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3339843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3378906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3417968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3457031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3496093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3535156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3574218750000000000000000 1.0000000000000000000000000 -0.0000000000000000011842379 2.5000000000000004440892099 +0.3613281250000000000000000 1.0000000000000000000000000 -0.0000000000000000288954046 2.5000000000000004440892099 +0.3652343750000000000000000 1.0000000000000000000000000 0.0000000000000001061077152 2.5000000000000004440892099 +0.3691406250000000000000000 1.0000000000000000000000000 -0.0000000000000000523433149 2.5000000000000008881784197 +0.3730468750000000000000000 1.0000000000000000000000000 -0.0000000000000025361638715 2.5000000000000008881784197 +0.3769531250000000000000000 0.9999999999999892308366611 0.0000000000000103973718524 2.4999999999999640287740021 +0.3808593750000000000000000 0.9999999999999668043315637 0.0000000000000430285732970 2.4999999999998783195565011 +0.3847656250000000000000000 1.0000000000000952571355128 -0.0000000000001151102916689 2.5000000000003366196210663 +0.3886718750000000000000000 1.0000000000003255173908201 -0.0000000000004553323644056 2.5000000000012332357357536 +0.3925781250000000000000000 0.9999999999988850030163690 0.0000000000013087320856660 2.4999999999961168839490711 +0.3964843750000000000000000 0.9999999999965045738292702 0.0000000000047935898805917 2.4999999999868904865252262 +0.4003906250000000000000000 1.0000000000115072396056348 -0.0000000000135690195672093 2.5000000000401918498482701 +0.4042968750000000000000000 1.0000000000362341268100863 -0.0000000000491591976015115 2.5000000001351954104222841 +0.4082031250000000000000000 0.9999999998905871878562834 0.0000000001283759580417154 2.4999999996185162665085500 +0.4121093750000000000000000 0.9999999996305891647452313 0.0000000004924310196940943 2.4999999986340086799430082 +0.4160156250000000000000000 1.0000000009277558721265677 -0.0000000010762639711003887 2.5000000032198865795862730 +0.4199218750000000000000000 1.0000000036182346008217792 -0.0000000047220564681538201 2.5000000132278308306865711 +0.4238281250000000000000000 0.9999999931038044964637379 0.0000000078161055708866033 2.4999999763565399213405271 +0.4277343750000000000000000 0.9999999658789334722186481 0.0000000435709412189547789 2.4999998766911044612015758 +0.4316406250000000000000000 1.0000000380491524953896487 -0.0000000399081534114979975 2.5000001245256582294018699 +0.4355468750000000000000000 1.0000002804758445495991737 -0.0000003537567949872290527 2.5000010120675422164993051 +0.4394531250000000000000000 0.9999998543541094297992800 0.0000001204569597061800384 2.4999996044797199168385760 +0.4433593750000000000000000 0.9999977702351791064572240 0.0000028312874076242150614 2.4999917879573088086431198 +0.4472656250000000000000000 0.9999980892518938180302257 0.0000024539707033565998708 2.4999933686417579181693327 +0.4511718750000000000000000 1.0000081455387486162322830 -0.0000114984704435064102282 2.5000387946698854335636497 +0.4550781250000000000000000 1.0000134468889607664010555 -0.0000154719655061507696113 2.5000345379049377925184672 +0.4589843750000000000000000 0.9998985476714082887284007 0.0001429045024795582189640 2.4995626946292373027347367 +0.4628906250000000000000000 0.9992539353937816004602723 0.0008967088608682400501307 2.4973642900591896953699234 +0.4667968750000000000000000 0.9967870696470185754023419 0.0038655628381056321082876 2.4887640414037681679815250 +0.4707031250000000000000000 0.9875532970739048232999835 0.0148545537697283673572723 2.4564114417689606462147367 +0.4746093750000000000000000 0.9545068041430846417227940 0.0535263257078096785224197 2.3423996120767598405620902 +0.4785156250000000000000000 0.8869853566390492050075522 0.1255424799459163021086994 2.1208181593841586298765378 +0.4824218750000000000000000 0.8007003828292104108399485 0.2063430328887052578323846 1.8569698237998359946487881 +0.4863281250000000000000000 0.7122084272718202102581131 0.2768106820813708845996359 1.6078954202185400390590075 +0.4902343750000000000000000 0.6286230373299415141730151 0.3295142935993899402369323 1.3921145696216146170343109 +0.4941406250000000000000000 0.5558377443335104084454201 0.3653255865555909420727687 1.2193661750278210753606345 +0.4980468750000000000000000 0.4921179420494242728878476 0.3831409290737487483013979 1.0794534726837916593922273 +0.5019531250000000000000000 0.4418946884673664587950270 0.3912831648908420834054311 0.9810697430374227812066579 +0.5058593750000000000000000 0.4244905399672744827910265 0.3940556470352689077962793 0.9352747617560934756397728 +0.5097656250000000000000000 0.4099485962617450129918950 0.3848757830370035937228579 0.9308675987434364973438505 +0.5136718750000000000000000 0.3913202552084866781001438 0.3638120381702610872665105 0.9329680360811266615073123 +0.5175781250000000000000000 0.3514352234423323562140240 0.3245215758206561051935068 0.9215783649270975486089696 +0.5214843750000000000000000 0.3035012411483848371318572 0.2821901825660226292846744 0.8995754409454717048788552 +0.5253906250000000000000000 0.2695239139843311204636223 0.2520411145021410614930346 0.8809827583794020977592254 +0.5292968750000000000000000 0.2479066674036098094635605 0.2273264077332264043729282 0.8543146840493895943779989 +0.5332031250000000000000000 0.2284131482832309212316346 0.1761145365801969897567858 0.7142143474484733411955517 +0.5371093750000000000000000 0.1624909402524336576867370 0.0470189533265044368182117 0.3745249698160906803856562 +0.5410156250000000000000000 0.1291962094447887399173425 0.0044141752811696259931051 0.2623413495388723370993489 +0.5449218750000000000000000 0.1253863611806613487242856 0.0004066383190923494590600 0.2510765457225886398973103 +0.5488281250000000000000000 0.1250083537802638700142666 0.0000038095166117312548959 0.2500525085001413239105261 +0.5527343750000000000000000 0.1249892549785630163627914 -0.0000083330757286820037567 0.2499715515288884748468234 +0.5566406250000000000000000 0.1250035867844018766525949 0.0000020942190971420672526 0.2500059085495880406568858 +0.5605468750000000000000000 0.1250011840480522995466828 0.0000013541278946361438192 0.2500034221635493159041630 +0.5644531250000000000000000 0.1249997681379830111181306 -0.0000002202704197066473056 0.2499993995136287616709581 +0.5683593750000000000000000 0.1249998966440091785479183 -0.0000001053456087493150607 0.2499997076803396334199192 +0.5722656250000000000000000 0.1250000329388425424070874 0.0000000301444036526691354 0.2500000876416431094817483 +0.5761718750000000000000000 0.1250000093085725794139762 0.0000000095686678282191950 0.2500000256607637916239639 +0.5800781250000000000000000 0.1249999963831033428229844 -0.0000000033742589362321453 0.2499999904194325495154771 +0.5839843750000000000000000 0.1249999992872777992980460 -0.0000000007322123076155172 0.2499999980129838372810980 +0.5878906250000000000000000 0.1250000003839817630524323 0.0000000003494301286544041 0.2500000010185446930321973 +0.5917968750000000000000000 0.1250000000459309812406161 0.0000000000541691143792396 0.2500000001310471731130747 +0.5957031250000000000000000 0.1249999999641337872224867 -0.0000000000348088073328275 0.2499999999046637888522326 +0.5996093750000000000000000 0.1249999999973017833498901 -0.0000000000028343615158614 0.2499999999919721993535404 +0.6035156250000000000000000 0.1250000000033525127118850 0.0000000000030211292726771 0.2500000000089530050040310 +0.6074218750000000000000000 0.1250000000000286992651866 0.0000000000001397317817009 0.2500000000001455502385284 +0.6113281250000000000000000 0.1249999999997324640066410 -0.0000000000002706784426228 0.2499999999992853494390488 +0.6152343750000000000000000 0.1250000000000059119376061 0.0000000000000061345891330 0.2500000000000097699626167 +0.6191406250000000000000000 0.1250000000000219269047363 0.0000000000000196886951187 0.2500000000000586197757002 +0.6230468750000000000000000 0.1249999999999975158759824 -0.0000000000000012119490596 0.2499999999999940047956670 +0.6269531250000000000000000 0.1249999999999981958875850 -0.0000000000000016805519939 0.2499999999999952815521453 +0.6308593750000000000000000 0.1249999999999999861222122 0.0000000000000001037096335 0.2499999999999999167332732 +0.6347656250000000000000000 0.1250000000000000000000000 0.0000000000000000371258579 0.2500000000000000000000000 +0.6386718750000000000000000 0.1250000000000000000000000 -0.0000000000000000100068102 0.2500000000000000000000000 +0.6425781250000000000000000 0.1250000000000000000000000 -0.0000000000000000000592119 0.2500000000000000000000000 +0.6464843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6503906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6542968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6582031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6621093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6660156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6699218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6738281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6777343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6816406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6855468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6894531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6933593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6972656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7011718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7050781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7089843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7128906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7167968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7207031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7246093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7285156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7324218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7363281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7402343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7441406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7480468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7519531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7558593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7597656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7636718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7675781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7714843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7753906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7792968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7832031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final400.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final400.csv new file mode 100644 index 00000000..b5789f83 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final400.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2402343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2441406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2480468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2519531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2558593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2597656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2636718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2675781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2714843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2753906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2792968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2832031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2871093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2910156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2949218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2988281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3027343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3066406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3105468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3144531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3183593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.3222656250000000000000000 1.0000000000000000000000000 -0.0000000000000000104212935 2.5000000000000004440892099 +0.3261718750000000000000000 1.0000000000000000000000000 -0.0000000000000002427687681 2.5000000000000004440892099 +0.3300781250000000000000000 1.0000000000000000000000000 0.0000000000000006110667528 2.5000000000000004440892099 +0.3339843750000000000000000 0.9999999999999995559107901 0.0000000000000006373568340 2.5000000000000013322676296 +0.3378906250000000000000000 1.0000000000000115463194561 -0.0000000000000155857549089 2.5000000000000452970994047 +0.3417968750000000000000000 1.0000000000000077715611724 -0.0000000000000133338081317 2.5000000000000319744231092 +0.3457031250000000000000000 0.9999999999998799848910380 0.0000000000001446184209423 2.4999999999995750066261735 +0.3496093750000000000000000 0.9999999999998375743714973 0.0000000000002141604227290 2.4999999999994093613508994 +0.3535156250000000000000000 1.0000000000008095746295567 -0.0000000000009906607090215 2.5000000000028874680424451 +0.3574218750000000000000000 1.0000000000015856205237696 -0.0000000000021182212132468 2.5000000000058779647815754 +0.3613281250000000000000000 0.9999999999945838879966686 0.0000000000064313707544746 2.4999999999810214035278477 +0.3652343750000000000000000 0.9999999999848274701008677 0.0000000000195915414262041 2.4999999999447251042283824 +0.3691406250000000000000000 1.0000000000300302005484809 -0.0000000000347605838631656 2.5000000001040496577786598 +0.3730468750000000000000000 1.0000000001288638085128468 -0.0000000001629585410019747 2.5000000004648810225660327 +0.3769531250000000000000000 0.9999999998811149870547865 0.0000000001285431646162277 2.4999999996001478486107317 +0.3808593750000000000000000 0.9999999990268937377635439 0.0000000012089023916435801 2.4999999965182255756701579 +0.3847656250000000000000000 1.0000000000138618005962599 0.0000000001012238042126974 2.4999999998919544275111093 +0.3886718750000000000000000 1.0000000063478926559668025 -0.0000000077590764573661382 2.5000000225458500757724778 +0.3925781250000000000000000 1.0000000055577540347684362 -0.0000000074543331239832784 2.5000000206114290079995044 +0.3964843750000000000000000 0.9999999658218946541055061 0.0000000410488316392824418 2.4999998795634024162382048 +0.4003906250000000000000000 0.9999999316610729271914693 0.0000000860815954446536012 2.4999997540911085280868065 +0.4042968750000000000000000 1.0000001252178425392713734 -0.0000001456789189106190330 2.5000004346997459769852412 +0.4082031250000000000000000 1.0000005171030394990339119 -0.0000006343263739727444569 2.5000018375175585561009939 +0.4121093750000000000000000 0.9999998740447595402258685 0.0000001063404329722567398 2.4999996329624951663106458 +0.4160156250000000000000000 0.9999969576894297551561408 0.0000036830113923166136793 2.4999892480322345456045241 +0.4199218750000000000000000 0.9999960412308016577398462 0.0000049796176769869194835 2.4999855968896942393087102 +0.4238281250000000000000000 1.0000064050239314550339031 -0.0000081984441393352474448 2.5000261333255742179915160 +0.4277343750000000000000000 1.0000208967120487457691524 -0.0000266176982178919061168 2.5000810205270087571705062 +0.4316406250000000000000000 0.9999790459444795054366750 0.0000294969273462338407125 2.4998974929257715693609043 +0.4355468750000000000000000 0.9996912342525947625659910 0.0003840534968271519869476 2.4988545207060965935852437 +0.4394531250000000000000000 0.9986793740202277724904434 0.0015740678531381297605707 2.4953573069096468550753798 +0.4433593750000000000000000 0.9956698027902777248243638 0.0051359957488118779256325 2.4848855552642277189079323 +0.4472656250000000000000000 0.9870145479235644669913086 0.0153137520459090681335113 2.4547020875452432164820493 +0.4511718750000000000000000 0.9642279197937878576496473 0.0416698069975747278914646 2.3763246070866417269940030 +0.4550781250000000000000000 0.9255935482818284931738617 0.0842398287759321406920066 2.2471363756934534805509429 +0.4589843750000000000000000 0.8778695334918495962739371 0.1336518945684213033331389 2.0932744164891099458714052 +0.4628906250000000000000000 0.8272049177745414150209058 0.1822601381429525546629122 1.9368970529537568037170558 +0.4667968750000000000000000 0.7768165080785702780730162 0.2264244865017647490024189 1.7883152298464946028389022 +0.4707031250000000000000000 0.7278209646217063122364266 0.2651728349470678369748100 1.6505979621056592332450919 +0.4746093750000000000000000 0.6807259658693998183309759 0.2982599159264658905676981 1.5242765732851952797943795 +0.4785156250000000000000000 0.6357461906421473241124431 0.3258549588956649589732706 1.4092955024888385029413485 +0.4824218750000000000000000 0.5932046650259398257176713 0.3482468899071876622386412 1.3052896312239139486877093 +0.4863281250000000000000000 0.5532049590237914094004168 0.3655663985216051625748435 1.2115982363513397856991105 +0.4902343750000000000000000 0.5161338046713633831430457 0.3788000523969679567137803 1.1291826399517657097959500 +0.4941406250000000000000000 0.4823949851954695833278208 0.3871258120618497056142360 1.0553587186765358563178552 +0.4980468750000000000000000 0.4558460390889955693438651 0.3945375850868422795691970 0.9998091589755756514179552 +0.5019531250000000000000000 0.4371486510097625233228769 0.3947204166532214397733469 0.9602861664290874843530332 +0.5058593750000000000000000 0.4242999172446545452785926 0.3922033799433585210536535 0.9419310055104703760520124 +0.5097656250000000000000000 0.4228128487430058979335001 0.3929999431624182637534659 0.9392207617955158349687395 +0.5136718750000000000000000 0.4251153218008388856574697 0.3948836237260155979100773 0.9411472283699859886496597 +0.5175781250000000000000000 0.4277005936269117625236902 0.3958523810310665136391606 0.9446818768227451812435902 +0.5214843750000000000000000 0.4282530350942865271512972 0.3949252425744524952477832 0.9467600243392513270634936 +0.5253906250000000000000000 0.4226450027425947553183505 0.3904904216181203646662823 0.9420478604471729244806966 +0.5292968750000000000000000 0.4070531681340678886726892 0.3782581331906534338749282 0.9309577122112770997119924 +0.5332031250000000000000000 0.3773307734301483140626488 0.3506661449935488672480233 0.9179651667033122963701430 +0.5371093750000000000000000 0.3346614804873204174207046 0.3107265714291614355779814 0.9012035017924294733049351 +0.5410156250000000000000000 0.2916643176127485248549931 0.2707895681269908427779569 0.8833206373938021771508033 +0.5449218750000000000000000 0.2632548626066942842882668 0.2437855364464349416930844 0.8688746732656946747397342 +0.5488281250000000000000000 0.2546889805866853762061908 0.2361711675377359265226573 0.8663908188532044585272729 +0.5527343750000000000000000 0.2552610395815202992686466 0.2375484539046876508727735 0.8700784473795228901593646 +0.5566406250000000000000000 0.2590906422533149622289272 0.2416329282588942917175956 0.8741520953349414257971262 +0.5605468750000000000000000 0.2635012830956609541921409 0.2453365590550091457355819 0.8748166683852314218228230 +0.5644531250000000000000000 0.2656280663867535696276434 0.2428734360544065884468523 0.8593868421683731328997169 +0.5683593750000000000000000 0.2457035873840538453549698 0.1908766409676708464271400 0.7264404864060522992730284 +0.5722656250000000000000000 0.1662035912594736486447289 0.0516466669124888561048792 0.3842343464183675116885297 +0.5761718750000000000000000 0.1296953790287760921451365 0.0049305401739191973692344 0.2637071571728111796240057 +0.5800781250000000000000000 0.1254355164395028754409367 0.0004574558381018569612822 0.2512134733801761332649960 +0.5839843750000000000000000 0.1250144904648494981191931 0.0000095165900724555631794 0.2500674352876589012772968 +0.5878906250000000000000000 0.1249882673978954250593176 -0.0000090406215637063253932 0.2499709928623811139303257 +0.5917968750000000000000000 0.1250034781887416623913367 0.0000019152582534139481526 0.2500051271244576600594200 +0.5957031250000000000000000 0.1250012561964644330902985 0.0000014155447066333862568 0.2500035918068072571252003 +0.5996093750000000000000000 0.1249997816527376043316266 -0.0000002049227687500077519 0.2499994448446936079477609 +0.6035156250000000000000000 0.1249998969302311691009777 -0.0000001045614170299025358 0.2499997080949951377970564 +0.6074218750000000000000000 0.1250000342548608645021346 0.0000000315648031156948854 0.2500000911788382573774925 +0.6113281250000000000000000 0.1250000086123145559557912 0.0000000087205193255298292 0.2500000237353831589182107 +0.6152343750000000000000000 0.1249999958530056826111476 -0.0000000038469499762901658 0.2499999889645778683444632 +0.6191406250000000000000000 0.1249999994902118438666605 -0.0000000005597367140156948 0.2499999985639256849800915 +0.6230468750000000000000000 0.1250000004754946436591467 0.0000000004535717752496280 0.2500000012695101081483529 +0.6269531250000000000000000 0.1250000000149833756513118 0.0000000000196345959047052 0.2500000000481404360819226 +0.6308593750000000000000000 0.1249999999482312440512999 -0.0000000000488334589950530 0.2499999998609767348778377 +0.6347656250000000000000000 0.1250000000028708702082270 0.0000000000016145664361033 0.2500000000068846595091543 +0.6386718750000000000000000 0.1250000000051719184490651 0.0000000000052203107022327 0.2500000000139591116443682 +0.6425781250000000000000000 0.1249999999993696014888300 -0.0000000000006156171276454 0.2499999999983957554849923 +0.6464843750000000000000000 0.1249999999994638039124695 -0.0000000000004888142631406 0.2499999999985448584371994 +0.6503906250000000000000000 0.1250000000001122713033652 0.0000000000000852144725153 0.2500000000002948752353404 +0.6542968750000000000000000 0.1250000000000437150315946 0.0000000000000511016414369 0.2500000000001196265309034 +0.6582031250000000000000000 0.1249999999999861916011312 -0.0000000000000146924546603 0.2499999999999650279747243 +0.6621093750000000000000000 0.1249999999999938105066377 -0.0000000000000043720582710 0.2499999999999843458553528 +0.6660156250000000000000000 0.1250000000000011657341759 0.0000000000000008931818248 0.2500000000000039412917374 +0.6699218750000000000000000 0.1250000000000001942890293 0.0000000000000004467833511 0.2500000000000006106226635 +0.6738281250000000000000000 0.1250000000000000000000000 -0.0000000000000001245522204 0.2500000000000000000000000 +0.6777343750000000000000000 0.1250000000000000000000000 0.0000000000000000078159701 0.2500000000000000000000000 +0.6816406250000000000000000 0.1250000000000000000000000 0.0000000000000000029013828 0.2500000000000000000000000 +0.6855468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6894531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6933593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.6972656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7011718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7050781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7089843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7128906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7167968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7207031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7246093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7285156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7324218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7363281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7402343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7441406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7480468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7519531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7558593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7597656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7636718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7675781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7714843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7753906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7792968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7832031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final600.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final600.csv new file mode 100644 index 00000000..aa699db1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final600.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2402343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2441406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2480468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2519531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2558593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2597656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2636718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2675781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2714843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2753906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2792968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2832031250000000000000000 1.0000000000000000000000000 -0.0000000000000000279480143 2.5000000000000004440892099 +0.2871093750000000000000000 1.0000000000000000000000000 0.0000000000000000440536496 2.5000000000000004440892099 +0.2910156250000000000000000 1.0000000000000000000000000 -0.0000000000000001141605329 2.5000000000000004440892099 +0.2949218750000000000000000 1.0000000000000000000000000 -0.0000000000000002948752353 2.5000000000000004440892099 +0.2988281250000000000000000 0.9999999999999955591079015 0.0000000000000042161237464 2.4999999999999866773237045 +0.3027343750000000000000000 0.9999999999999923394611301 0.0000000000000088247039306 2.4999999999999760191826681 +0.3066406250000000000000000 1.0000000000000190958360236 -0.0000000000000249002596320 2.5000000000000723865412056 +0.3105468750000000000000000 1.0000000000000539568389968 -0.0000000000000757523821449 2.5000000000002104982854689 +0.3144531250000000000000000 0.9999999999998856470284636 0.0000000000001265322661463 2.4999999999996145305658501 +0.3183593750000000000000000 0.9999999999994995114604990 0.0000000000006217395783400 2.4999999999982089882166747 +0.3222656250000000000000000 1.0000000000003004263504636 -0.0000000000003172047513544 2.5000000000010040857034710 +0.3261718750000000000000000 1.0000000000034161562467716 -0.0000000000042314963385100 2.5000000000122075682895684 +0.3300781250000000000000000 1.0000000000008359979375427 -0.0000000000014206496719756 2.5000000000035034197765071 +0.3339843750000000000000000 0.9999999999791762128609207 0.0000000000253366962965629 2.4999999999262039196423757 +0.3378906250000000000000000 0.9999999999760434965523359 0.0000000000313669327548874 2.4999999999121462757045720 +0.3417968750000000000000000 1.0000000001035465047038997 -0.0000000001238277761217433 2.5000000003640976409258201 +0.3457031250000000000000000 1.0000000002418441003015914 -0.0000000003040266982168302 2.5000000008700746789713776 +0.3496093750000000000000000 0.9999999996392271439660249 0.0000000004169003567255916 2.4999999987506802412440265 +0.3535156250000000000000000 0.9999999982480149984809259 0.0000000021567413234890857 2.4999999937576040665021537 +0.3574218750000000000000000 1.0000000001303210872549698 -0.0000000000181992308038580 2.5000000002756737060849446 +0.3613281250000000000000000 1.0000000096944343663807331 -0.0000000117430019661431587 2.5000000342889108218003003 +0.3652343750000000000000000 1.0000000104375810217050002 -0.0000000132993459078060240 2.5000000377881574920024832 +0.3691406250000000000000000 0.9999999618140525958764897 0.0000000453978176452096841 2.4999998660620783574870529 +0.3730468750000000000000000 0.9999998989974808738523393 0.0000001240502197044670347 2.4999996405090567641593680 +0.3769531250000000000000000 1.0000000573225291677914583 -0.0000000632629361099647900 2.5000001947634391541441801 +0.3808593750000000000000000 1.0000005580180422182223765 -0.0000006728628420610502609 2.5000019689343688789051612 +0.3847656250000000000000000 1.0000004792991179503047761 -0.0000006023255798095760630 2.5000017244521588466454887 +0.3886718750000000000000000 0.9999980411697507731716428 0.0000023165708060984033738 2.4999931657210825441950419 +0.3925781250000000000000000 0.9999946126244220190315559 0.0000065472085201740442658 2.4999808772171934201367094 +0.3964843750000000000000000 0.9999986959640477790500768 0.0000016834467633820639124 2.4999954656231095917462426 +0.4003906250000000000000000 1.0000157749786040550787902 -0.0000196134172569375113480 2.5000603965210879131575439 +0.4042968750000000000000000 1.0000218663034219357399479 -0.0000271345878647503392850 2.5000797188435850415544337 +0.4082031250000000000000000 0.9999314968825804283980574 0.0000865241600513902322633 2.4997316127732767121472079 +0.4121093750000000000000000 0.9995322924404886899552025 0.0005673731817916946845032 2.4983142925888497387632015 +0.4160156250000000000000000 0.9983435142382044436004662 0.0019684525158684749827909 2.4941859176738008230245214 +0.4199218750000000000000000 0.9952139135836176597749159 0.0056564025750390446375948 2.4832972935547008574985739 +0.4238281250000000000000000 0.9872140163016501768211697 0.0150462839467793742243007 2.4554340065038555707133128 +0.4277343750000000000000000 0.9694523783229851421339163 0.0355704765926646709894854 2.3942800793481824328523544 +0.4316406250000000000000000 0.9420485284965386396649478 0.0662222180408563038112035 2.3018005229061309080407227 +0.4355468750000000000000000 0.9089254622235989344858353 0.1017567163210437997111768 2.1928121031733489587622898 +0.4394531250000000000000000 0.8735034914903681002584790 0.1379211162382651678637302 2.0796288120174275526608199 +0.4433593750000000000000000 0.8376905851906166766696060 0.1724840748411509139259579 1.9687424351559714708059801 +0.4472656250000000000000000 0.8022761024229823068054657 0.2046033266211496337572129 1.8625768887235949478053953 +0.4511718750000000000000000 0.7675821820025611197380044 0.2340093833399693457053559 1.7619339011043912979204151 +0.4550781250000000000000000 0.7337726672151283491274398 0.2606323067622830502720888 1.6670394000667898559697733 +0.4589843750000000000000000 0.7009403579998348954305243 0.2844971130073013498851253 1.5778693746621832438847832 +0.4628906250000000000000000 0.6691448136186227690913597 0.3056707636079982193244575 1.4942889603340010484799905 +0.4667968750000000000000000 0.6384301427551120067249713 0.3242425233393198547027225 1.4161099934025629387690515 +0.4707031250000000000000000 0.6088378556328525315066713 0.3403308021512381764672739 1.3431384065755513912421293 +0.4746093750000000000000000 0.5803818199810932831894661 0.3540435497464735625783305 1.2750955596362991695258415 +0.4785156250000000000000000 0.5530908271683475652125139 0.3655569066562108782036944 1.2117992505073795772574385 +0.4824218750000000000000000 0.5269644472427383874446605 0.3749316389273836258588801 1.1528405703383060032507501 +0.4863281250000000000000000 0.5021001822039400375174978 0.3825010018041500314822656 1.0984998157454861633652854 +0.4902343750000000000000000 0.4787910469554791381696646 0.3879175942557878120631187 1.0485594953174712795629375 +0.4941406250000000000000000 0.4587562358360170455817695 0.3922047786005536385012249 1.0066414950171544973045457 +0.4980468750000000000000000 0.4429499673820090355214063 0.3941149967383168473133992 0.9742336294143066899309247 +0.5019531250000000000000000 0.4313031497446612183566117 0.3944262130598516491453154 0.9521612309049257705240166 +0.5058593750000000000000000 0.4273174316475103484691545 0.3952619000401183524395776 0.9436181178062903462944178 +0.5097656250000000000000000 0.4272607978800721517664840 0.3962626594398042101374813 0.9410984889460024538365701 +0.5136718750000000000000000 0.4278051512815468915285066 0.3964152739430359950745242 0.9422145130390227052430419 +0.5175781250000000000000000 0.4280576241662564229706334 0.3955141368014613023618153 0.9440554750742351508563388 +0.5214843750000000000000000 0.4268625483126358699514924 0.3940752532310126121650740 0.9443235897859115768326888 +0.5253906250000000000000000 0.4251017785054126418842202 0.3932344994804655713416253 0.9424748142820601470859287 +0.5292968750000000000000000 0.4241497992128079319584799 0.3937072937981162534804014 0.9399548339871814928159210 +0.5332031250000000000000000 0.4241386768218832759025361 0.3944548058939182366700038 0.9382021420351972507134519 +0.5371093750000000000000000 0.4240957186484468066645093 0.3945208271709655933889849 0.9380764977662749970477307 +0.5410156250000000000000000 0.4231993119543286385741965 0.3931876443914749663655073 0.9385259810811679148656594 +0.5449218750000000000000000 0.4186855851212692991580866 0.3880318904384538747365241 0.9381684233841455222702166 +0.5488281250000000000000000 0.4023753120631001767293355 0.3728595477544573433270614 0.9313498022618522664828333 +0.5527343750000000000000000 0.3675962165618293919777670 0.3410693283725255708915824 0.9160647488666475712904003 +0.5566406250000000000000000 0.3236231764141079270125090 0.3004803950458727612726761 0.8986291556201890795563259 +0.5605468750000000000000000 0.2837518176693062388338262 0.2632843516310011677816760 0.8811478458602197694204960 +0.5644531250000000000000000 0.2609024583139101793882730 0.2413858644207950154836340 0.8684778390911894740966659 +0.5683593750000000000000000 0.2554292848743376365128199 0.2366306924882555784428462 0.8669251001344202567366892 +0.5722656250000000000000000 0.2565728598568777774069360 0.2380754341372972870960467 0.8688587686339166449300819 +0.5761718750000000000000000 0.2600885185036063140806561 0.2414798943479914139498277 0.8710230947310982907438870 +0.5800781250000000000000000 0.2641460779294945715456322 0.2450757812667960500174757 0.8718915701305097742945804 +0.5839843750000000000000000 0.2671674657281887799165077 0.2476651320907397313408893 0.8723137637460910420728055 +0.5878906250000000000000000 0.2685036136701640652191259 0.2488907909300629994753251 0.8725917500064467313691807 +0.5917968750000000000000000 0.2680846093462203594270932 0.2485595017795336203469958 0.8723670415874057448846202 +0.5957031250000000000000000 0.2658902647547638498082279 0.2461410451492176687526836 0.8701493483771653991709627 +0.5996093750000000000000000 0.2611809599429574801909837 0.2378145984876141039165987 0.8533256129462717387568205 +0.6035156250000000000000000 0.2402758921811070091933971 0.1864164073020452283557802 0.7238785613727320988886049 +0.6074218750000000000000000 0.1654377992364400584701656 0.0512109882189258139306709 0.3842417645992951547029293 +0.6113281250000000000000000 0.1296508534914316834729675 0.0049094867241495279003294 0.2636672399995853566245785 +0.6152343750000000000000000 0.1254339566975293529527136 0.0004560735222351653588360 0.2512100425240856860220617 +0.6191406250000000000000000 0.1250142206169927161507616 0.0000092907677700660793986 0.2500668755214193184066573 +0.6230468750000000000000000 0.1249882860261999073525629 -0.0000090318551594045034961 0.2499709736362990819547036 +0.6269531250000000000000000 0.1250035136839561522581477 0.0000019520825706405724772 0.2500052324763649136407651 +0.6308593750000000000000000 0.1250012666984771647626928 0.0000014269683061149507038 0.2500036224352056302144831 +0.6347656250000000000000000 0.1249997759036892419626241 -0.0000002107408925264247294 0.2499994288841929090949634 +0.6386718750000000000000000 0.1249998940893931875795175 -0.0000001074439117547676606 0.2499997002622270647620439 +0.6425781250000000000000000 0.1250000351470728909841768 0.0000000324002585177100001 0.2500000935855720141098857 +0.6464843750000000000000000 0.1250000091433321747214080 0.0000000092794387428263274 0.2500000251952582130954283 +0.6503906250000000000000000 0.1249999957541644696190630 -0.0000000039495681937395922 0.2499999887040748047795091 +0.6542968750000000000000000 0.1249999994038823308839525 -0.0000000006401092139007865 0.2499999983269665104756996 +0.6582031250000000000000000 0.1250000004870529535239143 0.0000000004598660122034913 0.2500000012994259557252974 +0.6621093750000000000000000 0.1250000000251218212898863 0.0000000000318521665339707 0.2500000000758914597831506 +0.6660156250000000000000000 0.1249999999483542983957918 -0.0000000000495309333696051 0.2499999998615679008828749 +0.6699218750000000000000000 0.1250000000012877476862627 0.0000000000005482949501830 0.2500000000025590640717610 +0.6738281250000000000000000 0.1250000000052051418730770 0.0000000000049782281704343 0.2500000000140213951560497 +0.6777343750000000000000000 0.1249999999994527016822232 -0.0000000000004179954160577 0.2499999999986186327571858 +0.6816406250000000000000000 0.1249999999995213967318719 -0.0000000000004828037229269 0.2499999999987058407757701 +0.6855468750000000000000000 0.1250000000000867084182232 0.0000000000000843082344678 0.2500000000002249311847891 +0.6894531250000000000000000 0.1250000000000426880752968 0.0000000000000390700805042 0.2500000000001166289287369 +0.6933593750000000000000000 0.1249999999999857197563458 -0.0000000000000110060701293 0.2499999999999625577284945 +0.6972656250000000000000000 0.1249999999999969468866823 -0.0000000000000038096340897 0.2499999999999913957715592 +0.7011718750000000000000000 0.1250000000000011102230246 0.0000000000000015212423913 0.2500000000000023869795029 +0.7050781250000000000000000 0.1250000000000001942890293 -0.0000000000000000715575747 0.2500000000000002220446049 +0.7089843750000000000000000 0.1249999999999996391775170 -0.0000000000000001670959667 0.2499999999999989175325510 +0.7128906250000000000000000 0.1250000000000000000000000 -0.0000000000000000515439543 0.2500000000000000000000000 +0.7167968750000000000000000 0.1250000000000000000000000 0.0000000000000000151878510 0.2500000000000000000000000 +0.7207031250000000000000000 0.1250000000000000000000000 -0.0000000000000000017763568 0.2500000000000000000000000 +0.7246093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7285156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7324218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7363281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7402343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7441406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7480468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7519531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7558593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7597656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7636718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7675781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7714843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7753906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7792968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7832031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final800.csv b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final800.csv new file mode 100644 index 00000000..d6241bbd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/field_final800.csv @@ -0,0 +1,256 @@ +0.0019531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0058593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0097656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0136718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0175781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0214843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0253906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0292968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0332031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0371093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0410156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0449218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0488281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0527343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0566406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0605468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0644531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0683593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0722656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0761718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0800781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0839843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0878906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0917968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0957031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.0996093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1035156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1074218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1113281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1152343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1191406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1230468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1269531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1308593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1347656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1386718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1425781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1464843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1503906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1542968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1582031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1621093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1660156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1699218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1738281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1777343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1816406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1855468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1894531250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1933593750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.1972656250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2011718750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2050781250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2089843750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2128906250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2167968750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2207031250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2246093750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2285156250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2324218750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2363281250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2402343750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2441406250000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2480468750000000000000000 1.0000000000000000000000000 0.0000000000000000000000000 2.5000000000000004440892099 +0.2519531250000000000000000 1.0000000000000000000000000 -0.0000000000000000300796425 2.5000000000000004440892099 +0.2558593750000000000000000 1.0000000000000000000000000 0.0000000000000000277111667 2.5000000000000004440892099 +0.2597656250000000000000000 1.0000000000000000000000000 0.0000000000000000535275528 2.5000000000000004440892099 +0.2636718750000000000000000 1.0000000000000000000000000 -0.0000000000000008874678770 2.5000000000000004440892099 +0.2675781250000000000000000 0.9999999999999955591079015 0.0000000000000037547446633 2.4999999999999871214129143 +0.2714843750000000000000000 0.9999999999999822364316060 0.0000000000000198864332409 2.4999999999999364952429914 +0.2753906250000000000000000 0.9999999999999880095913340 0.0000000000000123193899526 2.4999999999999573674358544 +0.2792968750000000000000000 1.0000000000000650590692430 -0.0000000000000840309155592 2.5000000000002366995488501 +0.2832031250000000000000000 1.0000000000000923705556488 -0.0000000000001275528423624 2.5000000000003477218513126 +0.2871093750000000000000000 0.9999999999996542765501317 0.0000000000004018247068416 2.4999999999988000709549851 +0.2910156250000000000000000 0.9999999999990721866183208 0.0000000000011509555974953 2.4999999999966857622268890 +0.2949218750000000000000000 1.0000000000010309531006669 -0.0000000000011836031414229 2.5000000000035651481766763 +0.2988281250000000000000000 1.0000000000062447824689116 -0.0000000000076955158097765 2.5000000000222613039113639 +0.3027343750000000000000000 1.0000000000004767297667740 -0.0000000000011182758422971 2.5000000000024038548929184 +0.3066406250000000000000000 0.9999999999657962490573482 0.0000000000414424259057948 2.4999999998790167765605474 +0.3105468750000000000000000 0.9999999999604294309563102 0.0000000000505776223273338 2.4999999998565400893824062 +0.3144531250000000000000000 1.0000000001392657100751649 -0.0000000001657443938540838 2.5000000004886708815377006 +0.3183593750000000000000000 1.0000000003662030678697192 -0.0000000004527621906428669 2.5000000013074132887425094 +0.3222656250000000000000000 0.9999999997069443091746166 0.0000000003296438388626191 2.4999999989970467240141261 +0.3261718750000000000000000 0.9999999977906153247886323 0.0000000026854186091422106 2.4999999921733371266441281 +0.3300781250000000000000000 0.9999999987388237254748447 0.0000000016533126983612479 2.4999999953729394874812897 +0.3339843750000000000000000 1.0000000091806142688000136 -0.0000000109857311163826415 2.5000000322932312002421895 +0.3378906250000000000000000 1.0000000179330057470394877 -0.0000000220652946360644235 2.5000000638830295329739783 +0.3417968750000000000000000 0.9999999808740960283159893 0.0000000220838405039577332 2.4999999337848226588221223 +0.3457031250000000000000000 0.9999998911601339912635922 0.0000001315420277625396567 2.4999996154132526626767685 +0.3496093750000000000000000 0.9999999303234136105444918 0.0000000882744831398456743 2.4999997484706164563306174 +0.3535156250000000000000000 1.0000003708428191195878298 -0.0000004412320981373340854 2.5000013012570225789943379 +0.3574218750000000000000000 1.0000008425927187083459557 -0.0000010210114685392560482 2.5000029798933156577334103 +0.3613281250000000000000000 0.9999997114950130994159849 0.0000003140535020636546660 2.4999990286673918760129709 +0.3652343750000000000000000 0.9999959402730798085912056 0.0000048479766097292015180 2.4999857497271325001975129 +0.3691406250000000000000000 0.9999938753527745083360401 0.0000074403217754207031024 2.4999782552649971734126666 +0.3730468750000000000000000 1.0000031658969741332754211 -0.0000037690985294972486856 2.5000117278126046116426551 +0.3769531250000000000000000 1.0000228285527494875850607 -0.0000280218772499364924492 2.5000852667327118084017457 +0.3808593750000000000000000 1.0000163332813047922797978 -0.0000200579651256811640719 2.5000573225809969990507398 +0.3847656250000000000000000 0.9998845255471291437743275 0.0001418248333907536540190 2.4995706047875412281200624 +0.3886718750000000000000000 0.9994071458477562508448955 0.0007120976823439641775065 2.4978877990991188440261794 +0.3925781250000000000000000 0.9981157607333668302374008 0.0022355748242246392155919 2.4933925602298923074329196 +0.3964843750000000000000000 0.9949624967806131037306727 0.0059459767279251493632408 2.4824188020306761082167668 +0.4003906250000000000000000 0.9875078206261217461658930 0.0146918599829363588638032 2.4564673462058332908952707 +0.4042968750000000000000000 0.9727759952879300175965227 0.0317272516665391690615650 2.4056963232580770295498951 +0.4082031250000000000000000 0.9514010517951075884823808 0.0558399342090504235969206 2.3331738645953339350569422 +0.4121093750000000000000000 0.9259909756160413785153196 0.0836157638193086444333701 2.2486195419696883845972479 +0.4160156250000000000000000 0.8987772751866507370266390 0.1122938737667017600196928 2.1600518293905661693088405 +0.4199218750000000000000000 0.8710442352245426622658897 0.1403497691321375362427659 2.0719137444055215624416633 +0.4238281250000000000000000 0.8433725073243919512222533 0.1671298763287209498962227 1.9861045886516366376639553 +0.4277343750000000000000000 0.8160175851447091233126230 0.1923787261253469549338035 1.9033676347716812493615635 +0.4316406250000000000000000 0.7891126696471943979815933 0.2159926395002614574192279 1.8240124195568081510998582 +0.4355468750000000000000000 0.7627345126073949987954848 0.2379378316795567882557805 1.7481507868683181516900049 +0.4394531250000000000000000 0.7369277170774867213864923 0.2582205020937237138767273 1.6757799234765740070685069 +0.4433593750000000000000000 0.7117193176817475652740086 0.2768674606203947452520708 1.6068408172166124270319187 +0.4472656250000000000000000 0.6871280140917437329051154 0.2939169130578003774623141 1.5412477283894776558526019 +0.4511718750000000000000000 0.6631677942971155870210964 0.3094141967799124426363733 1.4789007498829946918306177 +0.4550781250000000000000000 0.6398490431558820912272267 0.3234088790253369372074133 1.4196899214654477017205636 +0.4589843750000000000000000 0.6171810298127219374109131 0.3359571307411899354633533 1.3635059778225049331723540 +0.4628906250000000000000000 0.5951691959478043747466813 0.3471124662567131591295322 1.3102245797596969723031179 +0.4667968750000000000000000 0.5738180234390976020009134 0.3569416458077349640909404 1.2597372298136300106108365 +0.4707031250000000000000000 0.5531252453045474304360596 0.3655011653553326689269909 1.2118990121325361464243997 +0.4746093750000000000000000 0.5330782761702897998290496 0.3728625462686794844735516 1.1665785394159267074343234 +0.4785156250000000000000000 0.5136916086664181646526117 0.3790951128285973137366227 1.1236751496757624302347267 +0.4824218750000000000000000 0.4950105163721878476223992 0.3842179937854028892729730 1.0831761745644432615165442 +0.4863281250000000000000000 0.4772910973936302925224595 0.3882999872853734046884711 1.0455716022228656036929806 +0.4902343750000000000000000 0.4610116537713412898646936 0.3913156804412653011482348 1.0115372805690772128883737 +0.4941406250000000000000000 0.4470568703328205995006783 0.3935134716982134350793388 0.9828307488245972001195128 +0.4980468750000000000000000 0.4362845566144645248485290 0.3945030104645111945771419 0.9611721211200491277182323 +0.5019531250000000000000000 0.4297896736310425347404873 0.3950580365052717146667760 0.9485040251825063162272045 +0.5058593750000000000000000 0.4278151670661325955968834 0.3957511930841333680497485 0.9433861027830512391290085 +0.5097656250000000000000000 0.4272223098286358489161785 0.3958493815254214287513435 0.9421749194938271454446976 +0.5136718750000000000000000 0.4270424729929310214693317 0.3952095992926034084824494 0.9426857573681445279234481 +0.5175781250000000000000000 0.4271090911826190827937921 0.3947181707568139796826756 0.9436365503848312963341982 +0.5214843750000000000000000 0.4273882458007015605616630 0.3949694398065673461850622 0.9437348386282081724729665 +0.5253906250000000000000000 0.4273381081210700371819655 0.3957294486839325053928462 0.9425825920547699077189918 +0.5292968750000000000000000 0.4268827222808847521307030 0.3963879062682580944887434 0.9407385543140540651307901 +0.5332031250000000000000000 0.4260093548150680753394681 0.3962875127660557827979915 0.9393963653352707110499864 +0.5371093750000000000000000 0.4248907461341426272660726 0.3951648203187390628876585 0.9390781523442249811850502 +0.5410156250000000000000000 0.4241564496475828671684383 0.3940076519331570659154806 0.9394409197841391279126810 +0.5449218750000000000000000 0.4244935695681181231364576 0.3937016424646549994648126 0.9402690791886619825490357 +0.5488281250000000000000000 0.4252103886491199746799907 0.3939681998986025446285453 0.9411172252384240044520425 +0.5527343750000000000000000 0.4255205952091649646007454 0.3941560266801173995077079 0.9414929124011719441256218 +0.5566406250000000000000000 0.4247976198329196373393302 0.3936904062501340173518827 0.9409449161376525205824350 +0.5605468750000000000000000 0.4219421408114453209137196 0.3914480339346183002113833 0.9391741910904439771812235 +0.5644531250000000000000000 0.4143660202895905753095462 0.3845707423017041270973948 0.9357743492279939623301743 +0.5683593750000000000000000 0.3945379337092448923662857 0.3658241745809228118169187 0.9274129383832254713837528 +0.5722656250000000000000000 0.3567935817376959861668695 0.3307496565742825689326878 0.9114014513944059814321008 +0.5761718750000000000000000 0.3124467379870844996325729 0.2898309988739650178146690 0.8930153479655036363737963 +0.5800781250000000000000000 0.2763603576524578664397325 0.2560874365872536917443369 0.8761397370943067031134888 +0.5839843750000000000000000 0.2595487692355102904429032 0.2401510608806540769677440 0.8669923685749723052396121 +0.5878906250000000000000000 0.2565137650884306008691738 0.2378791783849744934098425 0.8673836785243294045244511 +0.5917968750000000000000000 0.2579811580734805431802670 0.2396519430019923013741590 0.8699238735369145825160331 +0.5957031250000000000000000 0.2613013311879183731001319 0.2429143557901324301795398 0.8721367113949846094911322 +0.5996093750000000000000000 0.2649825004099219394326781 0.2461428682444140869645111 0.8728508415248884544368480 +0.6035156250000000000000000 0.2676161443608187640030849 0.2482418845352054592723334 0.8727074817311284427034934 +0.6074218750000000000000000 0.2684650484070006948300602 0.2489103205491200732080159 0.8725040236604126864250475 +0.6113281250000000000000000 0.2678250451277525145954428 0.2484387263624547592666403 0.8727354642882698687600396 +0.6152343750000000000000000 0.2664498679756195920198536 0.2472444572590924150023994 0.8726532678086398320260741 +0.6191406250000000000000000 0.2649875989234147799500363 0.2459102627957955033988213 0.8722297413192813264615211 +0.6230468750000000000000000 0.2640396973873151975631401 0.2450127807853728634235324 0.8717649451510876001947281 +0.6269531250000000000000000 0.2636763785757725297997922 0.2444552576736343241226024 0.8709375517311280789911621 +0.6308593750000000000000000 0.2635545842717333941962465 0.2436143620146318800046004 0.8677919743046359490890040 +0.6347656250000000000000000 0.2619775160237964306553238 0.2374711216410926029052320 0.8497740000109158531316211 +0.6386718750000000000000000 0.2413913285944523923198801 0.1853928327204293624586029 0.7168828755942097119557843 +0.6425781250000000000000000 0.1649229485353955748649923 0.0500530277121670891249394 0.3807175634428510146989311 +0.6464843750000000000000000 0.1295717881382032476977884 0.0048024368539007237718930 0.2633605165734365094465375 +0.6503906250000000000000000 0.1254274545060614920455322 0.0004491843587477137062121 0.2511913328995378780206238 +0.6542968750000000000000000 0.1250135147886704545250325 0.0000086611520329513906179 0.2500653837551639613323573 +0.6582031250000000000000000 0.1249883674435115499257165 -0.0000089724365947261582017 0.2499709160873879454367597 +0.6621093750000000000000000 0.1250035206356397143867554 0.0000019587849690989103600 0.2500052926860271695908011 +0.6660156250000000000000000 0.1250012635154260365322187 0.0000014256552844427313775 0.2500036180320099332696770 +0.6699218750000000000000000 0.1249997760052245637796275 -0.0000002106772235345090930 0.2499994284170000691247537 +0.6738281250000000000000000 0.1249998941167781846273144 -0.0000001074949998071043505 0.2499997003708289977641499 +0.6777343750000000000000000 0.1250000350138658622434207 0.0000000322850002339928592 0.2500000932272347653473332 +0.6816406250000000000000000 0.1250000091303146154686488 0.0000000092604300874654671 0.2500000251560922648330632 +0.6855468750000000000000000 0.1249999957723960247735207 -0.0000000039297958448850995 0.2499999887541466681017965 +0.6894531250000000000000000 0.1249999994111867379631420 -0.0000000006331746268628539 0.2499999983474065212707416 +0.6933593750000000000000000 0.1250000004850407020473568 0.0000000004584080471659034 0.2500000012939858073934829 +0.6972656250000000000000000 0.1250000000236208552717443 0.0000000000299883310184158 0.2500000000717391146487500 +0.7011718750000000000000000 0.1249999999482958867869087 -0.0000000000494172436008947 0.2499999998613837703942409 +0.7050781250000000000000000 0.1250000000016446566331041 0.0000000000007953286325820 0.2500000000035360603334311 +0.7089843750000000000000000 0.1250000000052030324493302 0.0000000000050429913874458 0.2500000000140193412434542 +0.7128906250000000000000000 0.1249999999994238497613708 -0.0000000000004804604714081 0.2499999999985409449010376 +0.7167968750000000000000000 0.1249999999995041743972024 -0.0000000000004826206101427 0.2499999999986568799403841 +0.7207031250000000000000000 0.1250000000000979771819232 0.0000000000000856323308559 0.2500000000002551292510589 +0.7246093750000000000000000 0.1250000000000419664303308 0.0000000000000432007022747 0.2500000000001145195049901 +0.7285156250000000000000000 0.1249999999999859695565263 -0.0000000000000130916018766 0.2499999999999628352842507 +0.7324218750000000000000000 0.1249999999999959060525967 -0.0000000000000037795248412 0.2499999999999882871470902 +0.7363281250000000000000000 0.1250000000000014988010832 0.0000000000000011884123315 0.2500000000000033306690739 +0.7402343750000000000000000 0.1249999999999999722444244 0.0000000000000001383189859 0.2499999999999996391775170 +0.7441406250000000000000000 0.1249999999999998334665463 -0.0000000000000002926547893 0.2499999999999991673327315 +0.7480468750000000000000000 0.1250000000000000000000000 -0.0000000000000000148621856 0.2500000000000000000000000 +0.7519531250000000000000000 0.1250000000000000000000000 0.0000000000000000139740071 0.2500000000000000000000000 +0.7558593750000000000000000 0.1250000000000000000000000 -0.0000000000000000024868996 0.2500000000000000000000000 +0.7597656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7636718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7675781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7714843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7753906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7792968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7832031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7871093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7910156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7949218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.7988281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8027343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8066406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8105468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8144531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8183593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8222656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8261718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8300781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8339843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8378906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8417968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8457031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8496093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8535156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8574218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8613281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8652343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8691406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8730468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8769531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8808593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8847656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8886718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8925781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.8964843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9003906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9042968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9082031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9121093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9160156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9199218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9238281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9277343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9316406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9355468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9394531250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9433593750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9472656250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9511718750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9550781250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9589843750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9628906250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9667968750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9707031250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9746093750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9785156250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9824218750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9863281250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9902343750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9941406250000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 +0.9980468750000000000000000 0.1250000000000000000000000 0.0000000000000000000000000 0.2500000000000000000000000 diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/data/iter.json b/example/sod-shock-tube/lax/cpp/old/1blocks/data/iter.json new file mode 100644 index 00000000..c892edd2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/data/iter.json @@ -0,0 +1,3 @@ +{ + "iter": 1000 +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod.json new file mode 100644 index 00000000..4afa21a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/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/sod-shock-tube/lax/cpp/old/1blocks/hllc/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.cpp new file mode 100644 index 00000000..b9139854 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.cpp @@ -0,0 +1,843 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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::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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Grid.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/HeatField.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/LogFile.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Parallel.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Post.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Post.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/README.txt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Solver.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/cfd.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heat.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heaticp.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/hxmath.h b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/main.cpp b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod.json b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod.json new file mode 100644 index 00000000..08ca3cb0 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "hllc", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/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/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/1blocks/hllc_debug/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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( 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/sod-shock-tube/lax/cpp/old/2blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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( 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/sod-shock-tube/lax/cpp/old/2blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/2blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.cpp new file mode 100644 index 00000000..58e43d58 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.cpp @@ -0,0 +1,762 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.h new file mode 100644 index 00000000..2e3120c9 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/EulerField.h @@ -0,0 +1,43 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/2blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/2blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Global.cpp new file mode 100644 index 00000000..1c4de49a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Global.cpp @@ -0,0 +1,446 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/2blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Global.h new file mode 100644 index 00000000..b71fcc5b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Global.h @@ -0,0 +1,174 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/lax/cpp/old/2blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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( 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/sod-shock-tube/lax/cpp/old/2blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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( 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/sod-shock-tube/lax/cpp/old/2blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/old/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.cpp new file mode 100644 index 00000000..af744c88 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/lax/cpp/old/2blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/old/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/old/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod.json new file mode 100644 index 00000000..0b1f5ab5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod_plot.py new file mode 100644 index 00000000..b18c08da --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod_plot.py @@ -0,0 +1,168 @@ +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' +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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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/sod-shock-tube/lax/cpp/old/2blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/2blocks/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/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/2blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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( 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/sod-shock-tube/lax/cpp/old/4blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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( 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/sod-shock-tube/lax/cpp/old/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..58e43d58 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.cpp @@ -0,0 +1,762 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.h new file mode 100644 index 00000000..2e3120c9 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/EulerField.h @@ -0,0 +1,43 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/4blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/4blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Global.cpp new file mode 100644 index 00000000..1c4de49a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Global.cpp @@ -0,0 +1,446 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Global.h new file mode 100644 index 00000000..b71fcc5b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Global.h @@ -0,0 +1,174 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/lax/cpp/old/4blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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( 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/sod-shock-tube/lax/cpp/old/4blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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( 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/sod-shock-tube/lax/cpp/old/4blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.cpp new file mode 100644 index 00000000..af744c88 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/lax/cpp/old/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sod.json new file mode 100644 index 00000000..d0a4a607 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "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/sod-shock-tube/lax/cpp/old/4blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sod_plot.py new file mode 100644 index 00000000..b18c08da --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sod_plot.py @@ -0,0 +1,168 @@ +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' +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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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/sod-shock-tube/lax/cpp/old/4blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/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/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01a/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/4blocks/01a/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.cpp new file mode 100644 index 00000000..c1fbf002 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.cpp @@ -0,0 +1,838 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 = 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } +} + +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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.cpp new file mode 100644 index 00000000..63f024f5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.cpp @@ -0,0 +1,447 @@ +#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; +int Global::nt = -1; +int Global::iter = -1; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.h new file mode 100644 index 00000000..60a2c97e --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Global.h @@ -0,0 +1,175 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 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; + 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/sod-shock-tube/lax/cpp/old/4blocks/01a/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Grid.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/HeatField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/LogFile.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Parallel.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Post.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Post.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/README.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.cpp new file mode 100644 index 00000000..636d0183 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.cpp @@ -0,0 +1,746 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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 ]; + 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 = 0; 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 ); +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.h new file mode 100644 index 00000000..6fd957e9 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Solver.h @@ -0,0 +1,49 @@ +#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: + //int nghost; + 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(); +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/sod-shock-tube/lax/cpp/old/4blocks/01a/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01a/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/cfd.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/heat.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/heaticp.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/hxmath.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/main.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/sod.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sod.json new file mode 100644 index 00000000..a8411679 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sod.json @@ -0,0 +1,18 @@ +{ + "istart" : 1, + "total_time" : 0.10, + "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/sod-shock-tube/lax/cpp/old/4blocks/01a/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/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/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01a/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01b/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/4blocks/01b/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.cpp new file mode 100644 index 00000000..a8a839e4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 = 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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( "{:.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" ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.cpp new file mode 100644 index 00000000..33ad8ec5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.cpp @@ -0,0 +1,448 @@ +#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; +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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.h new file mode 100644 index 00000000..46efeb71 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Global.h @@ -0,0 +1,176 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 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/sod-shock-tube/lax/cpp/old/4blocks/01b/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Grid.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/HeatField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/LogFile.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Parallel.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Post.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Post.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/README.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.cpp new file mode 100644 index 00000000..a5b3ca26 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.cpp @@ -0,0 +1,746 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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 ]; + 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 ); +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.h new file mode 100644 index 00000000..6fd957e9 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Solver.h @@ -0,0 +1,49 @@ +#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: + //int nghost; + 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(); +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/sod-shock-tube/lax/cpp/old/4blocks/01b/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01b/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/cfd.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/heat.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/heaticp.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/hxmath.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/main.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/sod.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sod.json new file mode 100644 index 00000000..8d31b79c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sod.json @@ -0,0 +1,18 @@ +{ + "istart" : 1, + "total_time" : 0.10, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 10, + "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/sod-shock-tube/lax/cpp/old/4blocks/01b/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/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/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01b/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/4blocks/01c/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/4blocks/01c/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Grid.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/HeatField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/LogFile.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Parallel.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Post.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Post.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/README.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/4blocks/01c/Solver.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/cfd.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/heat.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/heaticp.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/hxmath.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/main.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/sod.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sod.json new file mode 100644 index 00000000..9e076f75 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 1, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "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/sod-shock-tube/lax/cpp/old/4blocks/01c/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/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/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01c/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/BurgersField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.cpp new file mode 100644 index 00000000..7465218b --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.cpp @@ -0,0 +1,839 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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 +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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; + } + 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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; + + } +} + +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 ( 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; + } + } +} + +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::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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Grid.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Grid.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/HeatField.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/HeatField.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/LogFile.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/LogFile.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Parallel.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Parallel.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Post.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Post.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/README.txt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Solver.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Solver.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Vec1d.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/ZoneState.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/cfd.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heat.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heat_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heaticp.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/hxmath.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/hxmath.h b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/main.cpp b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/plotting2.jl b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod.json b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod.json new file mode 100644 index 00000000..c44d1117 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.1001, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 1, + "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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod_plot.py b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod_plot.py new file mode 100644 index 00000000..e491b448 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod_theory.plt b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/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/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/old/4blocks/01c_aaa/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/BurgersField.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/lax/cpp/parallel/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/EulerField.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/EulerField.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.cpp new file mode 100644 index 00000000..2170954f --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.h new file mode 100644 index 00000000..d9a14eee --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Field.h @@ -0,0 +1,52 @@ +#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 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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Grid.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Grid.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/HeatField.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/HeatField.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/LogFile.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/LogFile.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Parallel.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Parallel.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Post.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Post.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/README.txt b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Solver.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Solver.cpp new file mode 100644 index 00000000..fc492e48 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Solver.cpp @@ -0,0 +1,783 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Solver.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Vec1d.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/ZoneState.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers_plot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/cfd.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/heat.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/heat_plot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/heaticp.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/hxmath.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/hxmath.h b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/main.cpp b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/plot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/plotting2.jl b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod.json b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_plot.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_sort.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_sort_on_xcoor.py b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_theory.plt b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/lax/cpp/parallel/4blocks/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/sod-shock-tube/lax/cpp/parallel/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/lax/cpp/parallel/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/roe/cpp/01/BurgersField.cpp b/example/sod-shock-tube/roe/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/roe/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( 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/sod-shock-tube/roe/cpp/01/BurgersField.h b/example/sod-shock-tube/roe/cpp/01/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/roe/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( 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/sod-shock-tube/roe/cpp/01/CMakeLists.txt b/example/sod-shock-tube/roe/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/roe/cpp/01/CgnsUtil.cpp b/example/sod-shock-tube/roe/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/CgnsUtil.h b/example/sod-shock-tube/roe/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/EulerField.cpp b/example/sod-shock-tube/roe/cpp/01/EulerField.cpp new file mode 100644 index 00000000..5384eb57 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/EulerField.cpp @@ -0,0 +1,626 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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::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 EulerField::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 ]; + } +} + +//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; + + } +} + +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::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; + + Vec1d ps; + ps.Allocate( 0, nx, 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::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; + + ////fluxes at the interface + //VecWrap f; + //f.Allocate( this->nequ, 0, nx, 0 ); + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //Vec1d ps; + //ps.Allocate( ist, ied, 0 ); + + //WaveSpeed( uL, uR, ps ); + + //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::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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/roe/cpp/01/EulerField.h b/example/sod-shock-tube/roe/cpp/01/EulerField.h new file mode 100644 index 00000000..c8c1d3f6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/EulerField.h @@ -0,0 +1,40 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void euler_fluxes( int ist, int ied, VecWrap & u, 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/sod-shock-tube/roe/cpp/01/Field.cpp b/example/sod-shock-tube/roe/cpp/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/roe/cpp/01/Field.h b/example/sod-shock-tube/roe/cpp/01/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/roe/cpp/01/Global.cpp b/example/sod-shock-tube/roe/cpp/01/Global.cpp new file mode 100644 index 00000000..c251d974 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Global.cpp @@ -0,0 +1,440 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/roe/cpp/01/Global.h b/example/sod-shock-tube/roe/cpp/01/Global.h new file mode 100644 index 00000000..3e01e4c1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Global.h @@ -0,0 +1,173 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/roe/cpp/01/Grid.cpp b/example/sod-shock-tube/roe/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Grid.h b/example/sod-shock-tube/roe/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/HeatField.cpp b/example/sod-shock-tube/roe/cpp/01/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/roe/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( 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/sod-shock-tube/roe/cpp/01/HeatField.h b/example/sod-shock-tube/roe/cpp/01/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/roe/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( 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/sod-shock-tube/roe/cpp/01/LogFile.cpp b/example/sod-shock-tube/roe/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/LogFile.h b/example/sod-shock-tube/roe/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/MyCRWenoPlot.py b/example/sod-shock-tube/roe/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/MyWenoPlot.py b/example/sod-shock-tube/roe/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Parallel.cpp b/example/sod-shock-tube/roe/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Parallel.h b/example/sod-shock-tube/roe/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Post.cpp b/example/sod-shock-tube/roe/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Post.h b/example/sod-shock-tube/roe/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/README.txt b/example/sod-shock-tube/roe/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Solver.cpp b/example/sod-shock-tube/roe/cpp/01/Solver.cpp new file mode 100644 index 00000000..a9683ccf --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/roe/cpp/01/Solver.h b/example/sod-shock-tube/roe/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/roe/cpp/01/Vec1d.cpp b/example/sod-shock-tube/roe/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Vec1d.h b/example/sod-shock-tube/roe/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/Weno.cpp b/example/sod-shock-tube/roe/cpp/01/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/01/Weno.h b/example/sod-shock-tube/roe/cpp/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/roe/cpp/01/ZoneState.cpp b/example/sod-shock-tube/roe/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/ZoneState.h b/example/sod-shock-tube/roe/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/burgers.json b/example/sod-shock-tube/roe/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/burgers_ftcs.json b/example/sod-shock-tube/roe/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/burgers_plot.py b/example/sod-shock-tube/roe/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/cfd.json b/example/sod-shock-tube/roe/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/heat.json b/example/sod-shock-tube/roe/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/heat_plot.py b/example/sod-shock-tube/roe/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/heaticp.json b/example/sod-shock-tube/roe/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/hxmath.cpp b/example/sod-shock-tube/roe/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/hxmath.h b/example/sod-shock-tube/roe/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/main.cpp b/example/sod-shock-tube/roe/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/plot.py b/example/sod-shock-tube/roe/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/plotting2.jl b/example/sod-shock-tube/roe/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/sod.json b/example/sod-shock-tube/roe/cpp/01/sod.json new file mode 100644 index 00000000..58301858 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "roe", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/01/sod_plot.py b/example/sod-shock-tube/roe/cpp/01/sod_plot.py new file mode 100644 index 00000000..b18c08da --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/01/sod_plot.py @@ -0,0 +1,168 @@ +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' +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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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/sod-shock-tube/roe/cpp/01/sod_theory.plt b/example/sod-shock-tube/roe/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/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/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/roe/cpp/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/roe/cpp/1blocks/01/BurgersField.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/BurgersField.h b/example/sod-shock-tube/roe/cpp/1blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/CMakeLists.txt b/example/sod-shock-tube/roe/cpp/1blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/roe/cpp/1blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/CgnsUtil.h b/example/sod-shock-tube/roe/cpp/1blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/EulerField.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/roe/cpp/1blocks/01/EulerField.h b/example/sod-shock-tube/roe/cpp/1blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/roe/cpp/1blocks/01/Field.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/roe/cpp/1blocks/01/Field.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/roe/cpp/1blocks/01/Global.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/roe/cpp/1blocks/01/Global.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/roe/cpp/1blocks/01/Grid.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Grid.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/HeatField.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/HeatField.h b/example/sod-shock-tube/roe/cpp/1blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/LogFile.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/LogFile.h b/example/sod-shock-tube/roe/cpp/1blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/MyWenoPlot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Parallel.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Parallel.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Post.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Post.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/README.txt b/example/sod-shock-tube/roe/cpp/1blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Solver.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/roe/cpp/1blocks/01/Solver.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Vec1d.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Vec1d.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/Weno.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/1blocks/01/Weno.h b/example/sod-shock-tube/roe/cpp/1blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/roe/cpp/1blocks/01/ZoneState.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/ZoneState.h b/example/sod-shock-tube/roe/cpp/1blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/burgers.json b/example/sod-shock-tube/roe/cpp/1blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/burgers_ftcs.json b/example/sod-shock-tube/roe/cpp/1blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/burgers_plot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/cfd.json b/example/sod-shock-tube/roe/cpp/1blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/heat.json b/example/sod-shock-tube/roe/cpp/1blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/heat_plot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/heaticp.json b/example/sod-shock-tube/roe/cpp/1blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/hxmath.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/hxmath.h b/example/sod-shock-tube/roe/cpp/1blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/main.cpp b/example/sod-shock-tube/roe/cpp/1blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/plot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/plotting2.jl b/example/sod-shock-tube/roe/cpp/1blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/sod.json b/example/sod-shock-tube/roe/cpp/1blocks/01/sod.json new file mode 100644 index 00000000..4a8256dc --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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" : "roe", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/1blocks/01/sod_plot.py b/example/sod-shock-tube/roe/cpp/1blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/sod_theory.plt b/example/sod-shock-tube/roe/cpp/1blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/1blocks/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/sod-shock-tube/roe/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/roe/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/roe/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/roe/cpp/2blocks/01/BurgersField.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/BurgersField.h b/example/sod-shock-tube/roe/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/CMakeLists.txt b/example/sod-shock-tube/roe/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/roe/cpp/2blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/CgnsUtil.h b/example/sod-shock-tube/roe/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/EulerField.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/roe/cpp/2blocks/01/EulerField.h b/example/sod-shock-tube/roe/cpp/2blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/roe/cpp/2blocks/01/Field.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/roe/cpp/2blocks/01/Field.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/roe/cpp/2blocks/01/Global.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/roe/cpp/2blocks/01/Global.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/roe/cpp/2blocks/01/Grid.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Grid.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/HeatField.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/HeatField.h b/example/sod-shock-tube/roe/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/LogFile.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/LogFile.h b/example/sod-shock-tube/roe/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/MyWenoPlot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Parallel.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Parallel.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Post.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Post.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/README.txt b/example/sod-shock-tube/roe/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Solver.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/roe/cpp/2blocks/01/Solver.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Vec1d.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Vec1d.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/Weno.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/2blocks/01/Weno.h b/example/sod-shock-tube/roe/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/roe/cpp/2blocks/01/ZoneState.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/ZoneState.h b/example/sod-shock-tube/roe/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/burgers.json b/example/sod-shock-tube/roe/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/burgers_ftcs.json b/example/sod-shock-tube/roe/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/burgers_plot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/cfd.json b/example/sod-shock-tube/roe/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/heat.json b/example/sod-shock-tube/roe/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/heat_plot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/heaticp.json b/example/sod-shock-tube/roe/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/hxmath.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/hxmath.h b/example/sod-shock-tube/roe/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/main.cpp b/example/sod-shock-tube/roe/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/plot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/plotting2.jl b/example/sod-shock-tube/roe/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/sod.json b/example/sod-shock-tube/roe/cpp/2blocks/01/sod.json new file mode 100644 index 00000000..b8e99139 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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" : "roe", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/2blocks/01/sod_plot.py b/example/sod-shock-tube/roe/cpp/2blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/sod_theory.plt b/example/sod-shock-tube/roe/cpp/2blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/2blocks/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/sod-shock-tube/roe/cpp/2blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/roe/cpp/2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/roe/cpp/2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/roe/cpp/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/BurgersField.h b/example/sod-shock-tube/roe/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/roe/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/roe/cpp/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/roe/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/EulerField.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/roe/cpp/4blocks/01/EulerField.h b/example/sod-shock-tube/roe/cpp/4blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/roe/cpp/4blocks/01/Field.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/roe/cpp/4blocks/01/Field.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/roe/cpp/4blocks/01/Global.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/roe/cpp/4blocks/01/Global.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/roe/cpp/4blocks/01/Grid.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Grid.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/HeatField.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/HeatField.h b/example/sod-shock-tube/roe/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/LogFile.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/LogFile.h b/example/sod-shock-tube/roe/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Parallel.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Parallel.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Post.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Post.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/README.txt b/example/sod-shock-tube/roe/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Solver.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/roe/cpp/4blocks/01/Solver.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Vec1d.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/Weno.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/4blocks/01/Weno.h b/example/sod-shock-tube/roe/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/roe/cpp/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/ZoneState.h b/example/sod-shock-tube/roe/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/burgers.json b/example/sod-shock-tube/roe/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/roe/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/burgers_plot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/cfd.json b/example/sod-shock-tube/roe/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/heat.json b/example/sod-shock-tube/roe/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/heat_plot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/heaticp.json b/example/sod-shock-tube/roe/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/hxmath.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/hxmath.h b/example/sod-shock-tube/roe/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/main.cpp b/example/sod-shock-tube/roe/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/plot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/plotting2.jl b/example/sod-shock-tube/roe/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/sod.json b/example/sod-shock-tube/roe/cpp/4blocks/01/sod.json new file mode 100644 index 00000000..bbf615d8 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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" : "roe", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/roe/cpp/4blocks/01/sod_plot.py b/example/sod-shock-tube/roe/cpp/4blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/sod_theory.plt b/example/sod-shock-tube/roe/cpp/4blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/cpp/4blocks/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/sod-shock-tube/roe/cpp/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/roe/cpp/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/roe/cpp/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/roe/01/roe.py b/example/sod-shock-tube/roe/python/01/roe.py similarity index 100% rename from example/sod-shock-tube/roe/01/roe.py rename to example/sod-shock-tube/roe/python/01/roe.py diff --git a/example/sod-shock-tube/roe/python/01/sod_theory.plt b/example/sod-shock-tube/roe/python/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/python/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/sod-shock-tube/roe/02/roe.py b/example/sod-shock-tube/roe/python/02/roe.py similarity index 100% rename from example/sod-shock-tube/roe/02/roe.py rename to example/sod-shock-tube/roe/python/02/roe.py diff --git a/example/sod-shock-tube/roe/python/02/sod_theory.plt b/example/sod-shock-tube/roe/python/02/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/python/02/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/sod-shock-tube/roe/03/roe.py b/example/sod-shock-tube/roe/python/03/roe.py similarity index 100% rename from example/sod-shock-tube/roe/03/roe.py rename to example/sod-shock-tube/roe/python/03/roe.py diff --git a/example/sod-shock-tube/roe/python/03/sod_theory.plt b/example/sod-shock-tube/roe/python/03/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/roe/python/03/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/sod-shock-tube/rusanov/cpp/01/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6a263e07 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/BurgersField.cpp @@ -0,0 +1,316 @@ +#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( 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; + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/sod-shock-tube/rusanov/cpp/01/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/01/BurgersField.h new file mode 100644 index 00000000..0ee78b9e --- /dev/null +++ b/example/sod-shock-tube/rusanov/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/sod-shock-tube/rusanov/cpp/01/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/01/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/01/EulerField.cpp new file mode 100644 index 00000000..cf0dad48 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/EulerField.cpp @@ -0,0 +1,270 @@ +#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::Init( 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; + + int nm = 1; + this->utest.Allocate( nm, ist, ied ); + + un.Allocate( ist, ied, 0 ); // numerical solsution at every time step + u.Allocate( ist, ied, 0 ); // temporary array during RK3 integration + res.Allocate( 0, this->nx, 0 ); //N+1 + + 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 EulerField::InviscidResidual( Vec1d & u, Vec1d & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( Vec1d & u, Vec1d & ps ) +{ + 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 EulerField::LaxFriedrichs( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 i = 0; i < nx; ++ i ) + { + res[ i ] -= ( fL[ i + 1 ] - fL[ i ] ) / dx + ( fR[ i + 1 ] - fR[ i ] ) / dx; + } +} + +void EulerField::burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void EulerField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void EulerField::InviscidConservative( Vec1d & u, Vec1d & 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 EulerField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + ; +} + +void EulerField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/sod-shock-tube/rusanov/cpp/01/EulerField.h b/example/sod-shock-tube/rusanov/cpp/01/EulerField.h new file mode 100644 index 00000000..e6bf9796 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + + diff --git a/example/sod-shock-tube/rusanov/cpp/01/Field.cpp b/example/sod-shock-tube/rusanov/cpp/01/Field.cpp new file mode 100644 index 00000000..f975358d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Field.cpp @@ -0,0 +1,234 @@ +#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 i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + for ( int i = 0; i < ni; ++ 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 i = 0; i < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->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 ]; + 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 ) + { + this->u[ ib ] = ub; + } + + this->u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + this->u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + this->u[ ig3 ] = 4.0 * ub - 3.0 * 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/sod-shock-tube/rusanov/cpp/01/Field.h b/example/sod-shock-tube/rusanov/cpp/01/Field.h new file mode 100644 index 00000000..2cb33e98 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ) {}; +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 ); + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap utest; + Vec1d u_e; + Vec1d u, un; + Vec1d res; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/01/Global.cpp b/example/sod-shock-tube/rusanov/cpp/01/Global.cpp new file mode 100644 index 00000000..8cdf6005 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Global.cpp @@ -0,0 +1,435 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/rusanov/cpp/01/Global.h b/example/sod-shock-tube/rusanov/cpp/01/Global.h new file mode 100644 index 00000000..46b8865f --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Global.h @@ -0,0 +1,171 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + 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/sod-shock-tube/rusanov/cpp/01/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Grid.h b/example/sod-shock-tube/rusanov/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/01/HeatField.cpp new file mode 100644 index 00000000..502dbd3b --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/HeatField.cpp @@ -0,0 +1,222 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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; + u.Allocate( ist, ied, 0 ); + un.Allocate( ist, ied, 0 ); + res.Allocate( 0, this->ni, 0 ); //N+1 + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + 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 ); + 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 rr = 0.5 * this->alpha * dt / ( dx * dx ); +// 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 - rr; +// b[ i ] = 10.0 / 12.0 + 2.0 * rr; +// c[ i ] = 1.0 / 12.0 - rr; +// } +// +// a[ 0 ] = 0; +// b[ 0 ] = 1; +// c[ 0 ] = 0; +// +// a[ ni - 1 ] = 0; +// b[ ni - 1 ] = 1; +// c[ ni - 1 ] = 0; +// +// for ( int i = 0; i < ni; ++ i ) +// { +// double aa = 1.0 / 12.0 + rr; +// double bb = 10.0 / 12.0 - 2.0 * rr; +// double cc = 1.0 / 12.0 + rr; +// d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; +// } +// +// //d[ 0 ] = 0; +// //d[ ni - 1 ] = 0; +// +// 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 ); + 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void HeatField::ViscousResidual( Vec1d & u, Vec1d & res ) +{ + double coef = this->alpha / ( dx * dx ); + + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } +} +void HeatField::Rhs( Vec1d & u, Vec1d & 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, Vec1d & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f} {:.16f}\n", x[ i ], u[ i ] ); + } +} diff --git a/example/sod-shock-tube/rusanov/cpp/01/HeatField.h b/example/sod-shock-tube/rusanov/cpp/01/HeatField.h new file mode 100644 index 00000000..3cb910cb --- /dev/null +++ b/example/sod-shock-tube/rusanov/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( Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, Vec1d & u ); +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/01/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/LogFile.h b/example/sod-shock-tube/rusanov/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Parallel.h b/example/sod-shock-tube/rusanov/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Post.cpp b/example/sod-shock-tube/rusanov/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Post.h b/example/sod-shock-tube/rusanov/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/README.txt b/example/sod-shock-tube/rusanov/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/01/Solver.cpp new file mode 100644 index 00000000..2add060d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Solver.cpp @@ -0,0 +1,665 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + 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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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; + + 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; + donordata_for_send[ data_pos + iig ] = field->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; + int donor_data_pos = i * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + double donor_value = donordata[ donor_data_pos + iig ]; + donor_interface->data_recv[ data_pos + iig ] = 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; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int ig_cell = interface->ijk_ghosts[ ijkpos + iig ] - 1; + double donor_value = interface->data_recv[ data_pos + iig ]; + if ( ig == 0 ) + { + double valueb = 0.5 * ( field->u[ ig_cell ] + donor_value ); + field->u[ ig_cell ] = valueb; + } + else + { + field->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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/rusanov/cpp/01/Solver.h b/example/sod-shock-tube/rusanov/cpp/01/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/rusanov/cpp/01/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/01/Vec1d.h new file mode 100644 index 00000000..28c18559 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Vec1d.h @@ -0,0 +1,58 @@ +#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 ]; }; +}; \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/01/Weno.cpp new file mode 100644 index 00000000..ac5ad7ec --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Weno.cpp @@ -0,0 +1,284 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ]; + } +} diff --git a/example/sod-shock-tube/rusanov/cpp/01/Weno.h b/example/sod-shock-tube/rusanov/cpp/01/Weno.h new file mode 100644 index 00000000..61b5dec8 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/Weno.h @@ -0,0 +1,24 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/01/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/burgers.json b/example/sod-shock-tube/rusanov/cpp/01/burgers.json new file mode 100644 index 00000000..b2bf1213 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/cfd.json b/example/sod-shock-tube/rusanov/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/heat.json b/example/sod-shock-tube/rusanov/cpp/01/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/heaticp.json b/example/sod-shock-tube/rusanov/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/hxmath.h b/example/sod-shock-tube/rusanov/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/main.cpp b/example/sod-shock-tube/rusanov/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/plot.py b/example/sod-shock-tube/rusanov/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/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/sod-shock-tube/rusanov/cpp/01/sod.json b/example/sod-shock-tube/rusanov/cpp/01/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/rusanov/cpp/01/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/01/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/01a/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/01a/BurgersField.cpp new file mode 100644 index 00000000..91e01df5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/BurgersField.cpp @@ -0,0 +1,324 @@ +#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( 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( Vec1d & u, Vec1d & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( Vec1d & u, Vec1d & res ) +{ + Vec1d uL; + uL.Allocate( 0, nx, 0 ); + + Vec1d uR; + uR.Allocate( 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 i = 0; i < nx; ++ i ) + { + res[ i ] += ( - u[ i ] * ( u[ i + 1 ] - u[ i - 1 ] ) / dx ); + } + } + else + { + 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( Vec1d & u, Vec1d & ps ) +{ + 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( Vec1d & u, Vec1d & res ) +{ + Vec1d fL; + fL.Allocate( 0, nx, 0 ); + + Vec1d fR; + fR.Allocate( 0, nx, 0 ); + + Vec1d f, fP, fN; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + f.Allocate( ist, ied, 0 ); + fP.Allocate( ist, ied, 0 ); + fN.Allocate( ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + // left and right side fluxes at the interface + 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 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, Vec1d & u, Vec1d & f ) +{ + for ( int i = ist; i <= ied; ++ i ) + { + f[ i ] = 0.5 * u[ i ] * u[ i ]; + } +} + +void BurgersField::Rusanov( Vec1d & u, Vec1d & res ) +{ + Vec1d uL, uR; + uL.Allocate( 0, nx, 0 ); + uR.Allocate( 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 + Vec1d fL, fR; + fL.Allocate( 0, nx, 0 ); + fR.Allocate( 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 ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + + WaveSpeed( u, ps ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( fR[ i ] + fL[ i ] ) - 0.5 * ps[ i ] * ( uR[ i ] - uL[ i ] ); + } + + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } +} + +void BurgersField::InviscidConservative( Vec1d & u, Vec1d & 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( Vec1d & u, Vec1d & res ) +{ + ; +} + +void BurgersField::Rhs( Vec1d & u, Vec1d & 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/sod-shock-tube/rusanov/cpp/01a/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/01a/BurgersField.h new file mode 100644 index 00000000..953933cd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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( Grid * grid ); +public: + void Rhs( Vec1d & u, Vec1d & res ); + void InviscidResidual( Vec1d & u, Vec1d & res ); + void ViscousResidual( Vec1d & u, Vec1d & res ); + void InviscidNonConservative( Vec1d & u, Vec1d & res ); + void InviscidConservative( Vec1d & u, Vec1d & res ); + void WaveSpeed( Vec1d & u, Vec1d & ps ); +public: + void LaxFriedrichs( Vec1d & u, Vec1d & res ); + void Rusanov( Vec1d & u, Vec1d & res ); + void burgers_fluxes( int ist, int ied, Vec1d & u, Vec1d & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/sod-shock-tube/rusanov/cpp/01a/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/01a/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/01a/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/01a/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/01a/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/01a/EulerField.cpp new file mode 100644 index 00000000..a3273711 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/EulerField.cpp @@ -0,0 +1,306 @@ +#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::Init( 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 EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::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 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 ); + + 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 EulerField::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 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 + 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 EulerField::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 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( "{:.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/sod-shock-tube/rusanov/cpp/01a/EulerField.h b/example/sod-shock-tube/rusanov/cpp/01a/EulerField.h new file mode 100644 index 00000000..78441d62 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/EulerField.h @@ -0,0 +1,30 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; +public: + void Init( 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 & 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/sod-shock-tube/rusanov/cpp/01a/Field.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/01a/Field.h b/example/sod-shock-tube/rusanov/cpp/01a/Field.h new file mode 100644 index 00000000..5012b508 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); + void InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/01a/Global.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/rusanov/cpp/01a/Global.h b/example/sod-shock-tube/rusanov/cpp/01a/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/rusanov/cpp/01a/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Grid.h b/example/sod-shock-tube/rusanov/cpp/01a/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/01a/HeatField.cpp new file mode 100644 index 00000000..0f5daf50 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/HeatField.cpp @@ -0,0 +1,203 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( Grid * grid ) +{ + this->ni = grid->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(); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ 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/sod-shock-tube/rusanov/cpp/01a/HeatField.h b/example/sod-shock-tube/rusanov/cpp/01a/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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( 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/sod-shock-tube/rusanov/cpp/01a/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/01a/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/LogFile.h b/example/sod-shock-tube/rusanov/cpp/01a/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01a/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01a/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Parallel.h b/example/sod-shock-tube/rusanov/cpp/01a/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Post.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Post.h b/example/sod-shock-tube/rusanov/cpp/01a/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/README.txt b/example/sod-shock-tube/rusanov/cpp/01a/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Solver.cpp new file mode 100644 index 00000000..d07705b7 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/rusanov/cpp/01a/Solver.h b/example/sod-shock-tube/rusanov/cpp/01a/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/rusanov/cpp/01a/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/01a/Vec1d.h new file mode 100644 index 00000000..47d23577 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Vec1d.h @@ -0,0 +1,67 @@ +#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(); } +}; \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01a/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/01a/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01a/Weno.h b/example/sod-shock-tube/rusanov/cpp/01a/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/01a/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/01a/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/01a/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/burgers.json b/example/sod-shock-tube/rusanov/cpp/01a/burgers.json new file mode 100644 index 00000000..b2bf1213 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01a/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/01a/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/01a/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/cfd.json b/example/sod-shock-tube/rusanov/cpp/01a/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/heat.json b/example/sod-shock-tube/rusanov/cpp/01a/heat.json new file mode 100644 index 00000000..ec47fd0a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/heat.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "cn" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01a/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/01a/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/heaticp.json b/example/sod-shock-tube/rusanov/cpp/01a/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/01a/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/hxmath.h b/example/sod-shock-tube/rusanov/cpp/01a/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/main.cpp b/example/sod-shock-tube/rusanov/cpp/01a/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/plot.py b/example/sod-shock-tube/rusanov/cpp/01a/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/01a/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/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/sod-shock-tube/rusanov/cpp/01a/sod.json b/example/sod-shock-tube/rusanov/cpp/01a/sod.json new file mode 100644 index 00000000..41a170f4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01a/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01a/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/rusanov/cpp/01a/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/01a/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/01b/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/01b/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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( 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/sod-shock-tube/rusanov/cpp/01b/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/01b/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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( 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/sod-shock-tube/rusanov/cpp/01b/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/01b/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/01b/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/01b/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/01b/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/01b/EulerField.cpp new file mode 100644 index 00000000..432076e1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/EulerField.cpp @@ -0,0 +1,490 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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::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 EulerField::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 ]; + } +} + +//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; + + } +} + +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::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; + + ////fluxes at the interface + //VecWrap f; + //f.Allocate( this->nequ, 0, nx, 0 ); + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //Vec1d ps; + //ps.Allocate( ist, ied, 0 ); + + //WaveSpeed( uL, uR, ps ); + + //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::LAX ) ) + { + this->LaxFriedrichs( 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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/rusanov/cpp/01b/EulerField.h b/example/sod-shock-tube/rusanov/cpp/01b/EulerField.h new file mode 100644 index 00000000..23b77965 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/EulerField.h @@ -0,0 +1,38 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void euler_fluxes( int ist, int ied, VecWrap & u, 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/sod-shock-tube/rusanov/cpp/01b/Field.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/01b/Field.h b/example/sod-shock-tube/rusanov/cpp/01b/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/01b/Global.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/rusanov/cpp/01b/Global.h b/example/sod-shock-tube/rusanov/cpp/01b/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/rusanov/cpp/01b/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Grid.h b/example/sod-shock-tube/rusanov/cpp/01b/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/01b/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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( 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/sod-shock-tube/rusanov/cpp/01b/HeatField.h b/example/sod-shock-tube/rusanov/cpp/01b/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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( 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/sod-shock-tube/rusanov/cpp/01b/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/01b/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/LogFile.h b/example/sod-shock-tube/rusanov/cpp/01b/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01b/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01b/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Parallel.h b/example/sod-shock-tube/rusanov/cpp/01b/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Post.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Post.h b/example/sod-shock-tube/rusanov/cpp/01b/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/README.txt b/example/sod-shock-tube/rusanov/cpp/01b/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Solver.cpp new file mode 100644 index 00000000..a9683ccf --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/rusanov/cpp/01b/Solver.h b/example/sod-shock-tube/rusanov/cpp/01b/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/rusanov/cpp/01b/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/01b/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/01b/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01b/Weno.h b/example/sod-shock-tube/rusanov/cpp/01b/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/01b/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/01b/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/01b/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/burgers.json b/example/sod-shock-tube/rusanov/cpp/01b/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/01b/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/01b/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/cfd.json b/example/sod-shock-tube/rusanov/cpp/01b/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/heat.json b/example/sod-shock-tube/rusanov/cpp/01b/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/01b/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/heaticp.json b/example/sod-shock-tube/rusanov/cpp/01b/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/01b/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/hxmath.h b/example/sod-shock-tube/rusanov/cpp/01b/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/main.cpp b/example/sod-shock-tube/rusanov/cpp/01b/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/plot.py b/example/sod-shock-tube/rusanov/cpp/01b/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/01b/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/sod.json b/example/sod-shock-tube/rusanov/cpp/01b/sod.json new file mode 100644 index 00000000..bc887a9c --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 10, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01b/sod_plot.py b/example/sod-shock-tube/rusanov/cpp/01b/sod_plot.py new file mode 100644 index 00000000..c40387fe --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/sod_plot.py @@ -0,0 +1,167 @@ +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 ): + 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.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 = '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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +#nt = 2000 +nt = 2000 + +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 + +mplot = MyPlot() +mplot.PlotCompare(x, q) diff --git a/example/sod-shock-tube/rusanov/cpp/01b/sod_theory.plt b/example/sod-shock-tube/rusanov/cpp/01b/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01b/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/sod-shock-tube/rusanov/cpp/01b/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/rusanov/cpp/01b/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/01b/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/01c/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/01c/BurgersField.cpp new file mode 100644 index 00000000..613624ce --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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( 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/sod-shock-tube/rusanov/cpp/01c/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/01c/BurgersField.h new file mode 100644 index 00000000..8ef11f09 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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( 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/sod-shock-tube/rusanov/cpp/01c/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/01c/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/01c/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/01c/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/01c/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/01c/EulerField.cpp new file mode 100644 index 00000000..432076e1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/EulerField.cpp @@ -0,0 +1,490 @@ +#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::Init( 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 = 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 + + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + gamma = 1.4; // specific gas ratio + + //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::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::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 EulerField::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 ]; + } +} + +//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; + + } +} + +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::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; + + ////fluxes at the interface + //VecWrap f; + //f.Allocate( this->nequ, 0, nx, 0 ); + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //Vec1d ps; + //ps.Allocate( ist, ied, 0 ); + + //WaveSpeed( uL, uR, ps ); + + //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::LAX ) ) + { + this->LaxFriedrichs( 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( "{:.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" ); + } +} + +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 - idir; + 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 - idir; + 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/sod-shock-tube/rusanov/cpp/01c/EulerField.h b/example/sod-shock-tube/rusanov/cpp/01c/EulerField.h new file mode 100644 index 00000000..23b77965 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/EulerField.h @@ -0,0 +1,38 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid ); + 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 ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void euler_fluxes( int ist, int ied, VecWrap & u, 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/sod-shock-tube/rusanov/cpp/01c/Field.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/01c/Field.h b/example/sod-shock-tube/rusanov/cpp/01c/Field.h new file mode 100644 index 00000000..0c225420 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Field.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( 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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/01c/Global.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Global.cpp new file mode 100644 index 00000000..a88d5a11 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Global.cpp @@ -0,0 +1,436 @@ +#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::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; +int Global::nt = -1; +int Global::iter = -1; +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 == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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 ); + + std::vector sub_donordata( sub_donorijk.size() ); + 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/sod-shock-tube/rusanov/cpp/01c/Global.h b/example/sod-shock-tube/rusanov/cpp/01c/Global.h new file mode 100644 index 00000000..90bd2938 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Global.h @@ -0,0 +1,172 @@ +#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 + LAX, //Lax-Friedrichs flux splitting + Rusanov, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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 int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + 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/sod-shock-tube/rusanov/cpp/01c/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Grid.h b/example/sod-shock-tube/rusanov/cpp/01c/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/01c/HeatField.cpp new file mode 100644 index 00000000..b442a706 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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( 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/sod-shock-tube/rusanov/cpp/01c/HeatField.h b/example/sod-shock-tube/rusanov/cpp/01c/HeatField.h new file mode 100644 index 00000000..7a917533 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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( 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/sod-shock-tube/rusanov/cpp/01c/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/01c/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/LogFile.h b/example/sod-shock-tube/rusanov/cpp/01c/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01c/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/01c/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Parallel.h b/example/sod-shock-tube/rusanov/cpp/01c/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Post.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Post.h b/example/sod-shock-tube/rusanov/cpp/01c/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/README.txt b/example/sod-shock-tube/rusanov/cpp/01c/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Solver.cpp new file mode 100644 index 00000000..a9683ccf --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Solver.cpp @@ -0,0 +1,684 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + 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::nequ = 1; + } + 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" ]; + std::cout << "Global::total_time = " << Global::total_time << "\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::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::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::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::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::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::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(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->Init( grid ); + } + + this->Boundary(); + this->UpdateOldField(); +} + +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 = 0; 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() +{ + this->DumpField(); +} + +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; + 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/sod-shock-tube/rusanov/cpp/01c/Solver.h b/example/sod-shock-tube/rusanov/cpp/01c/Solver.h new file mode 100644 index 00000000..8475a426 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Solver.h @@ -0,0 +1,46 @@ +#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: + //int nghost; + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); +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/sod-shock-tube/rusanov/cpp/01c/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/01c/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/01c/Weno.cpp new file mode 100644 index 00000000..cfbf3393 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Weno.cpp @@ -0,0 +1,321 @@ +#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 ); + } +} + +//----------------------------------------------------------------------------- +// 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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01c/Weno.h b/example/sod-shock-tube/rusanov/cpp/01c/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/01c/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/01c/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/01c/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/burgers.json b/example/sod-shock-tube/rusanov/cpp/01c/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/01c/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/01c/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/cfd.json b/example/sod-shock-tube/rusanov/cpp/01c/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/heat.json b/example/sod-shock-tube/rusanov/cpp/01c/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/01c/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/heaticp.json b/example/sod-shock-tube/rusanov/cpp/01c/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/01c/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/hxmath.h b/example/sod-shock-tube/rusanov/cpp/01c/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/main.cpp b/example/sod-shock-tube/rusanov/cpp/01c/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/plot.py b/example/sod-shock-tube/rusanov/cpp/01c/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/01c/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/sod.json b/example/sod-shock-tube/rusanov/cpp/01c/sod.json new file mode 100644 index 00000000..b2f39197 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/sod.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.20, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 2000, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/01c/sod_plot.py b/example/sod-shock-tube/rusanov/cpp/01c/sod_plot.py new file mode 100644 index 00000000..0ca8d7bb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/sod_plot.py @@ -0,0 +1,166 @@ +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 ): + 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.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 = '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) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + +nt = 2000 + +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 + +mplot = MyPlot() +mplot.PlotCompare(x, q) diff --git a/example/sod-shock-tube/rusanov/cpp/01c/sod_theory.plt b/example/sod-shock-tube/rusanov/cpp/01c/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/01c/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/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocks.cgns b/example/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocks.cgns new file mode 100644 index 00000000..ab1dd890 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/01c/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/1blocks/01/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/1blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/1blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/rusanov/cpp/1blocks/01/Field.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/1blocks/01/Field.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/1blocks/01/Global.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/rusanov/cpp/1blocks/01/Global.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/rusanov/cpp/1blocks/01/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Grid.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/HeatField.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/LogFile.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Parallel.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Post.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Post.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/README.txt b/example/sod-shock-tube/rusanov/cpp/1blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/rusanov/cpp/1blocks/01/Solver.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/1blocks/01/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/burgers.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/cfd.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/heat.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/heaticp.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/hxmath.h b/example/sod-shock-tube/rusanov/cpp/1blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/main.cpp b/example/sod-shock-tube/rusanov/cpp/1blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/plot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/1blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/sod.json b/example/sod-shock-tube/rusanov/cpp/1blocks/01/sod.json new file mode 100644 index 00000000..adc313db --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/1blocks/01/sod_plot.py b/example/sod-shock-tube/rusanov/cpp/1blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/sod_theory.plt b/example/sod-shock-tube/rusanov/cpp/1blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/1blocks/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/sod-shock-tube/rusanov/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns b/example/sod-shock-tube/rusanov/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns new file mode 100644 index 00000000..bc79b09c Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/1blocks/01/sodshocktube1d1blocksv1.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/2blocks/01/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/2blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/2blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/rusanov/cpp/2blocks/01/Field.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/2blocks/01/Field.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/2blocks/01/Global.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/rusanov/cpp/2blocks/01/Global.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/rusanov/cpp/2blocks/01/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Grid.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/HeatField.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/LogFile.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Parallel.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Post.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Post.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/README.txt b/example/sod-shock-tube/rusanov/cpp/2blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/rusanov/cpp/2blocks/01/Solver.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/2blocks/01/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/burgers.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/cfd.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/heat.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/heaticp.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/hxmath.h b/example/sod-shock-tube/rusanov/cpp/2blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/main.cpp b/example/sod-shock-tube/rusanov/cpp/2blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/plot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/2blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/sod.json b/example/sod-shock-tube/rusanov/cpp/2blocks/01/sod.json new file mode 100644 index 00000000..bbcaa244 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/2blocks/01/sod_plot.py b/example/sod-shock-tube/rusanov/cpp/2blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/sod_theory.plt b/example/sod-shock-tube/rusanov/cpp/2blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/2blocks/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/sod-shock-tube/rusanov/cpp/2blocks/01/sodshocktube1d2blocks.cgns b/example/sod-shock-tube/rusanov/cpp/2blocks/01/sodshocktube1d2blocks.cgns new file mode 100644 index 00000000..002f9fb2 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/2blocks/01/sodshocktube1d2blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/cpp/4blocks/01/BurgersField.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/BurgersField.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/CMakeLists.txt b/example/sod-shock-tube/rusanov/cpp/4blocks/01/CMakeLists.txt new file mode 100644 index 00000000..5dd1f642 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/CMakeLists.txt @@ -0,0 +1,104 @@ +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 + 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/sod-shock-tube/rusanov/cpp/4blocks/01/CgnsUtil.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/CgnsUtil.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.cpp new file mode 100644 index 00000000..ad371cac --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.cpp @@ -0,0 +1,856 @@ +#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::Init( Grid * grid, std::fstream & file ) +{ + 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 = 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 +} + +void EulerField::InitFieldCommon( 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; + for ( int i = 0; i <= nx; ++ 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 ); + } + + 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::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; + } + } +} + +void EulerField::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 ]; + } +} + +//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::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/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.h new file mode 100644 index 00000000..9e336b7f --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/EulerField.h @@ -0,0 +1,47 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void Init( Grid * grid, std::fstream & file ); + 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 burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + 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/sod-shock-tube/rusanov/cpp/4blocks/01/Field.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Field.cpp new file mode 100644 index 00000000..14a3e667 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Field.cpp @@ -0,0 +1,253 @@ +#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 < ni; ++ 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 < ni; ++ 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 < ni; ++ 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 == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +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 - 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::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/sod-shock-tube/rusanov/cpp/4blocks/01/Field.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Field.h new file mode 100644 index 00000000..12af7ecc --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Field.h @@ -0,0 +1,51 @@ +#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 InterfaceBc( Region & region ); +public: + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/sod-shock-tube/rusanov/cpp/4blocks/01/Global.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Global.cpp new file mode 100644 index 00000000..fc82713a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Global.cpp @@ -0,0 +1,449 @@ +#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 == "upwind" ) + { + this->inviscid = to_int( BasicScheme::UpWind ); + } + 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 ); + } +} + +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/sod-shock-tube/rusanov/cpp/4blocks/01/Global.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Global.h new file mode 100644 index 00000000..f920b693 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Global.h @@ -0,0 +1,177 @@ +#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, // + UpWind, //Lax-Friedrichs flux splitting + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + 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/sod-shock-tube/rusanov/cpp/4blocks/01/Grid.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Grid.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/HeatField.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/HeatField.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/LogFile.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/LogFile.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/MyCRWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/MyWenoPlot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Parallel.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Parallel.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Post.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Post.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/README.txt b/example/sod-shock-tube/rusanov/cpp/4blocks/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Solver.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Solver.cpp new file mode 100644 index 00000000..38031830 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Solver.cpp @@ -0,0 +1,782 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.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( "../sod.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 == "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::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 ]; + 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/sod-shock-tube/rusanov/cpp/4blocks/01/Solver.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Vec1d.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Vec1d.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.cpp new file mode 100644 index 00000000..f3ca8c8c --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.cpp @@ -0,0 +1,325 @@ +#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 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 ) ); + } +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.h new file mode 100644 index 00000000..9b823dc4 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/01/Weno.h @@ -0,0 +1,30 @@ +#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 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 ); + diff --git a/example/sod-shock-tube/rusanov/cpp/4blocks/01/ZoneState.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/ZoneState.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/burgers.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/burgers_ftcs.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/burgers_plot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/cfd.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/heat.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/heat_plot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/heaticp.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/hxmath.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/hxmath.h b/example/sod-shock-tube/rusanov/cpp/4blocks/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/main.cpp b/example/sod-shock-tube/rusanov/cpp/4blocks/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/plot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/plotting2.jl b/example/sod-shock-tube/rusanov/cpp/4blocks/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/sod.json b/example/sod-shock-tube/rusanov/cpp/4blocks/01/sod.json new file mode 100644 index 00000000..f599f5c9 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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" : "rusanov", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/sod-shock-tube/rusanov/cpp/4blocks/01/sod_plot.py b/example/sod-shock-tube/rusanov/cpp/4blocks/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/sod_theory.plt b/example/sod-shock-tube/rusanov/cpp/4blocks/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/cpp/4blocks/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/sod-shock-tube/rusanov/cpp/4blocks/01/sodshocktube1d4blocks.cgns b/example/sod-shock-tube/rusanov/cpp/4blocks/01/sodshocktube1d4blocks.cgns new file mode 100644 index 00000000..87d7dcc9 Binary files /dev/null and b/example/sod-shock-tube/rusanov/cpp/4blocks/01/sodshocktube1d4blocks.cgns differ diff --git a/example/sod-shock-tube/rusanov/01/rusanov.py b/example/sod-shock-tube/rusanov/python/01/rusanov.py similarity index 100% rename from example/sod-shock-tube/rusanov/01/rusanov.py rename to example/sod-shock-tube/rusanov/python/01/rusanov.py diff --git a/example/sod-shock-tube/rusanov/python/01/sod_theory.plt b/example/sod-shock-tube/rusanov/python/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/sod-shock-tube/rusanov/python/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/modern-cfd/CMakeLists.txt b/modern-cfd/CMakeLists.txt index a3e10e1c..e3708a59 100644 --- a/modern-cfd/CMakeLists.txt +++ b/modern-cfd/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required ( VERSION 3.20 ) +cmake_minimum_required ( VERSION 3.31 ) if ( DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE ) message(STATUS "VCPKG_ROOT: $ENV{VCPKG_ROOT}") diff --git a/modern-cfd/README.txt b/modern-cfd/README.txt index a9748504..f93cdb1a 100644 --- a/modern-cfd/README.txt +++ b/modern-cfd/README.txt @@ -2,8 +2,8 @@ cmake ../ -D CMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmak cmake .. -D CMAKE_PREFIX_PATH:PATH=C:/local/Qt/6.3.2/msvc2019_64/ cmake .. -D CMAKE_PREFIX_PATH:PATH=C:/local/Qt/Qt6.4.0/6.4.0/msvc2019_64/ cmake .. -D CMAKE_PREFIX_PATH:PATH=C:/local/Qt/6.7.2/msvc2019_64/ -c:\local\Qt\6.7.2\ -c:\local\Qt\Qt6.4.0\ +cmake .. -D CMAKE_PREFIX_PATH:PATH="C:/local/Qt/6.8.1/msvc2022_64/" + cmake --build . C:\local\Qt\6.3.2\msvc2019_64\bin\windeployqt.exe .\Debug\testprj.exe .\Debug\testprj.exe diff --git a/modern-cfd/src/cgns/include/Cgns_t.h b/modern-cfd/src/cgns/include/Cgns_t.h index 9e497796..329bc985 100644 --- a/modern-cfd/src/cgns/include/Cgns_t.h +++ b/modern-cfd/src/cgns/include/Cgns_t.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/cgns/include/cgnstest.h b/modern-cfd/src/cgns/include/cgnstest.h index 48188538..6e793a1a 100644 --- a/modern-cfd/src/cgns/include/cgnstest.h +++ b/modern-cfd/src/cgns/include/cgnstest.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/cgns/src/Cgns_t.cpp b/modern-cfd/src/cgns/src/Cgns_t.cpp index c254e49f..fd02fdeb 100644 --- a/modern-cfd/src/cgns/src/Cgns_t.cpp +++ b/modern-cfd/src/cgns/src/Cgns_t.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/cgns/src/cgnstest.cpp b/modern-cfd/src/cgns/src/cgnstest.cpp index e7e84b6b..3c0c1f6a 100644 --- a/modern-cfd/src/cgns/src/cgnstest.cpp +++ b/modern-cfd/src/cgns/src/cgnstest.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/geometry/include/Geom.h b/modern-cfd/src/geometry/include/Geom.h index f18719f1..e3ee2422 100644 --- a/modern-cfd/src/geometry/include/Geom.h +++ b/modern-cfd/src/geometry/include/Geom.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/geometry/include/Grid.h b/modern-cfd/src/geometry/include/Grid.h index aef40107..e3311da7 100644 --- a/modern-cfd/src/geometry/include/Grid.h +++ b/modern-cfd/src/geometry/include/Grid.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/geometry/src/Geom.cpp b/modern-cfd/src/geometry/src/Geom.cpp index 06e0d94b..316766dd 100644 --- a/modern-cfd/src/geometry/src/Geom.cpp +++ b/modern-cfd/src/geometry/src/Geom.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/geometry/src/Grid.cpp b/modern-cfd/src/geometry/src/Grid.cpp index eb233a32..e4fafad2 100644 --- a/modern-cfd/src/geometry/src/Grid.cpp +++ b/modern-cfd/src/geometry/src/Grid.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/main/include/Simu.h b/modern-cfd/src/main/include/Simu.h index afd0d850..490ccfab 100644 --- a/modern-cfd/src/main/include/Simu.h +++ b/modern-cfd/src/main/include/Simu.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/main/src/Simu.cpp b/modern-cfd/src/main/src/Simu.cpp index 1a15dfc5..c7e91250 100644 --- a/modern-cfd/src/main/src/Simu.cpp +++ b/modern-cfd/src/main/src/Simu.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/main/src/main.cpp b/modern-cfd/src/main/src/main.cpp index 4586ee0f..504554e4 100644 --- a/modern-cfd/src/main/src/main.cpp +++ b/modern-cfd/src/main/src/main.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/parallel/include/Cmpi.h b/modern-cfd/src/parallel/include/Cmpi.h index 0560fc76..642b7269 100644 --- a/modern-cfd/src/parallel/include/Cmpi.h +++ b/modern-cfd/src/parallel/include/Cmpi.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/parallel/src/Cmpi.cpp b/modern-cfd/src/parallel/src/Cmpi.cpp index dc33b35e..6772b2ad 100644 --- a/modern-cfd/src/parallel/src/Cmpi.cpp +++ b/modern-cfd/src/parallel/src/Cmpi.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/project/include/Project.h b/modern-cfd/src/project/include/Project.h index ebc2c81a..918ea936 100644 --- a/modern-cfd/src/project/include/Project.h +++ b/modern-cfd/src/project/include/Project.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/project/src/Project.cpp b/modern-cfd/src/project/src/Project.cpp index 69dc743c..16606d34 100644 --- a/modern-cfd/src/project/src/Project.cpp +++ b/modern-cfd/src/project/src/Project.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/include/CfdPara.h b/modern-cfd/src/solver/include/CfdPara.h index 72e374d2..0a4eb16d 100644 --- a/modern-cfd/src/solver/include/CfdPara.h +++ b/modern-cfd/src/solver/include/CfdPara.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/include/Solver.h b/modern-cfd/src/solver/include/Solver.h index 90fd7219..f554c2bc 100644 --- a/modern-cfd/src/solver/include/Solver.h +++ b/modern-cfd/src/solver/include/Solver.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/include/SolverDetail.h b/modern-cfd/src/solver/include/SolverDetail.h index c74a6d1b..55e47804 100644 --- a/modern-cfd/src/solver/include/SolverDetail.h +++ b/modern-cfd/src/solver/include/SolverDetail.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/include/SolverDetailCpu.h b/modern-cfd/src/solver/include/SolverDetailCpu.h index bed92862..d983d4f2 100644 --- a/modern-cfd/src/solver/include/SolverDetailCpu.h +++ b/modern-cfd/src/solver/include/SolverDetailCpu.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/include/SolverDetailCuda.h b/modern-cfd/src/solver/include/SolverDetailCuda.h index a8b68e8a..ec4e9887 100644 --- a/modern-cfd/src/solver/include/SolverDetailCuda.h +++ b/modern-cfd/src/solver/include/SolverDetailCuda.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/src/CfdPara.cpp b/modern-cfd/src/solver/src/CfdPara.cpp index b1e35841..c3462160 100644 --- a/modern-cfd/src/solver/src/CfdPara.cpp +++ b/modern-cfd/src/solver/src/CfdPara.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/src/Solver.cpp b/modern-cfd/src/solver/src/Solver.cpp index 8c8a3ae9..32412bb6 100644 --- a/modern-cfd/src/solver/src/Solver.cpp +++ b/modern-cfd/src/solver/src/Solver.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/src/SolverDetail.cpp b/modern-cfd/src/solver/src/SolverDetail.cpp index 5a017fa3..fccf4bf4 100644 --- a/modern-cfd/src/solver/src/SolverDetail.cpp +++ b/modern-cfd/src/solver/src/SolverDetail.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/src/SolverDetailCpu.cpp b/modern-cfd/src/solver/src/SolverDetailCpu.cpp index 1bb89425..8b8e5984 100644 --- a/modern-cfd/src/solver/src/SolverDetailCpu.cpp +++ b/modern-cfd/src/solver/src/SolverDetailCpu.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/solver/src/SolverDetailCuda.cu b/modern-cfd/src/solver/src/SolverDetailCuda.cu index 8eb06dae..eb428354 100644 --- a/modern-cfd/src/solver/src/SolverDetailCuda.cu +++ b/modern-cfd/src/solver/src/SolverDetailCuda.cu @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/tools/include/tools.h b/modern-cfd/src/tools/include/tools.h index fd23c0ca..83e15c34 100644 --- a/modern-cfd/src/tools/include/tools.h +++ b/modern-cfd/src/tools/include/tools.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/visualize/include/Visual.h b/modern-cfd/src/visualize/include/Visual.h index 289ed879..2a0c8d9a 100644 --- a/modern-cfd/src/visualize/include/Visual.h +++ b/modern-cfd/src/visualize/include/Visual.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/src/visualize/src/Visual.cpp b/modern-cfd/src/visualize/src/Visual.cpp index c5ef4cfd..7dab32cd 100644 --- a/modern-cfd/src/visualize/src/Visual.cpp +++ b/modern-cfd/src/visualize/src/Visual.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/ui/CMakeLists.txt b/modern-cfd/ui/CMakeLists.txt index 8f0ac960..4fed4716 100644 --- a/modern-cfd/ui/CMakeLists.txt +++ b/modern-cfd/ui/CMakeLists.txt @@ -1,9 +1,6 @@ -cmake_minimum_required ( VERSION 3.20 ) +cmake_minimum_required ( VERSION 3.31 ) -#set( VCPKG_ROOT "c:/dev/vcpkg" ) -#set( CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" ) - -#project( OneFLOW-UI ) +project( OneFLOW-UI ) set ( GUI_NAME "OneFLOW-UI" ) #message( STATUS "VCPKG_ROOT=${VCPKG_ROOT}") @@ -14,16 +11,26 @@ set ( PRJ_COMPILE_DEFINITIONS ) set ( PRJ_LIBRARIES ) set ( PRJ_INCLUDE_DIRS ) -find_package ( Qt6 COMPONENTS Widgets ) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) +#find_package ( Qt6 REQUIRED COMPONENTS Widgets ) +#find_package ( Qt6 COMPONENTS Widgets ) + + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) find_package ( Qt6 REQUIRED COMPONENTS Sql ) #list ( APPEND PRJ_LIBRARIES Qt6::Core ) list ( APPEND PRJ_LIBRARIES Qt6::Sql ) list ( APPEND PRJ_LIBRARIES Qt6::Widgets ) -#list ( APPEND PRJ_INCLUDE_DIRS "c:\Program Files\MySQL\MySQL Server 8.0\include" ) -list ( APPEND PRJ_LIBRARIES "c:/Program Files/MySQL/MySQL Server 8.0/lib/libmysql.lib" ) - +#list ( APPEND PRJ_INCLUDE_DIRS "C:/Program Files/MySQL/MySQL Server 9.1/include" ) +list ( APPEND PRJ_LIBRARIES "C:/Program Files/MySQL/MySQL Server 9.1/lib/libmysql.lib" ) get_directory_property( my_system_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} BUILDSYSTEM_TARGETS ) get_directory_property( my_import_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} IMPORTED_TARGETS ) @@ -78,7 +85,7 @@ message ( STATUS "OUTPUT_BIN_DIR = ${OUTPUT_BIN_DIR}" ) add_custom_command ( TARGET ${GUI_NAME} POST_BUILD - COMMAND $<$:${windeployqt_debug}>$<$:${windeployqt_release}> $ + COMMAND $<$:${windeployqt_release}>$<$:${windeployqt_release}> $ COMMENT "Run Qt6::windeployqt" ) diff --git a/modern-cfd/ui/MyDataBase.cpp b/modern-cfd/ui/MyDataBase.cpp index 9f51b108..4b47a281 100644 --- a/modern-cfd/ui/MyDataBase.cpp +++ b/modern-cfd/ui/MyDataBase.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2022 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/ui/MyDataBase.h b/modern-cfd/ui/MyDataBase.h index dc20cff2..156f92f3 100644 --- a/modern-cfd/ui/MyDataBase.h +++ b/modern-cfd/ui/MyDataBase.h @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2022 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/ui/README.txt b/modern-cfd/ui/README.txt index 6720db68..0acd2e17 100644 --- a/modern-cfd/ui/README.txt +++ b/modern-cfd/ui/README.txt @@ -1,5 +1,8 @@ cmake ../ -D CMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" +qt6.8 +cmake .. -DCMAKE_PREFIX_PATH:PATH="C:/local/Qt/6.8.1/msvc2022_64" + The package python3 is compatible with built-in CMake targets: find_package(Python3 COMPONENTS Development REQUIRED) diff --git a/modern-cfd/ui/main.cpp b/modern-cfd/ui/main.cpp index c3775ac5..7f68aab8 100644 --- a/modern-cfd/ui/main.cpp +++ b/modern-cfd/ui/main.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2022 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/modern-cfd/ui/mainwindow.cpp b/modern-cfd/ui/mainwindow.cpp index 52b9ae25..605a2be1 100644 --- a/modern-cfd/ui/mainwindow.cpp +++ b/modern-cfd/ui/mainwindow.cpp @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*\ OneFLOW - LargeScale Multiphysics Scientific Simulation Environment -Copyright (C) 2017-2022 He Xin and the OneFLOW contributors. +Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW. diff --git a/test/test.py b/test/test.py index a26af8c0..2b1df9e5 100644 --- a/test/test.py +++ b/test/test.py @@ -2,7 +2,7 @@ ''' --------------------------------------------------------------------------- OneFLOW - LargeScale Multiphysics Scientific Simulation Environment - Copyright (C) 2017-2024 He Xin and the OneFLOW contributors. + Copyright (C) 2017-2025 He Xin and the OneFLOW contributors. ------------------------------------------------------------------------------- License This file is part of OneFLOW.