diff --git a/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt b/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/1d-linear-convection/eno2/fortran/01/README.txt b/example/1d-linear-convection/eno2/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 b/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..7106d53c --- /dev/null +++ b/example/1d-linear-convection/eno2/fortran/01/enoburgers.f90 @@ -0,0 +1,267 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time, xlen + xlen = 2.0 + dx = xlen / nx + dt = dx * 0.5 + write(*,*) 'nx=',nx + write(*,*) 'dx=',dx + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp b/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/BurgersField.h b/example/1d-linear-convection/eno3/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt b/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cbc3f9bb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CMakeLists.txt @@ -0,0 +1,106 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Eno.h Eno.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..4a4eddfb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.cpp @@ -0,0 +1,287 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "Eno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::ENO ) ) + { + enoL( nx, u, uL ); + enoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + //double coef = this->alpha / ( dx * dx ); + //for ( int m = 0; m < nequ; ++ m ) + //{ + // Vec1d & u = this->u.vec( m ); + // Vec1d & res = this->res.vec( m ); + // for ( int i = 0; i < ni; ++ i ) + // { + // res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + // } + //} +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Eno.cpp b/example/1d-linear-convection/eno3/cpp/01/Eno.cpp new file mode 100644 index 00000000..deae576a --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Eno.cpp @@ -0,0 +1,135 @@ +#include "Eno.h" + +//std::vector> enocoef = { +// { 11.0/6, -7.0/6, 1.0/3 } +// { 1.0/3, 5.0/6, -1.0/6 }, +// { -1.0/6, 5.0/6, 1.0/3 }, +// { 1.0/3, -7.0/6, 11.0/6 } +//}; + +std::vector> enocoef = { + { 3.0/2, -1.0/2 }, + { 1.0/2, 1.0/2 }, + { -1.0/2, 3.0/2 } +}; + +void enoL( int N, Vec1d & u, Vec1d & f ) +{ + int ighost = 3; + int iorder = 2; + int ist = 0 - ighost; + int ied = N - 1 + ighost; + + VecWrap dd; + dd.Allocate( iorder, ist, ied, 0 ); + + std::vector ir( N + 1 ); + + for ( int j = -ighost; j < N + ighost; ++j ) + { + dd[ 0 ][ j ] = u[ j ]; + } + + for ( int i = 1; i < iorder; ++ i ) + { + for ( int j = -ighost; j < N + ighost - 1; ++j ) + { + dd[ i ][ j ] = dd[ i - 1 ][ j + 1 ] - dd[ i - 1 ][ j ]; + } + } + + for ( int j = 0; j <= N; ++ j ) + { + ir[ j ] = j; + for ( int i = 1; i < iorder; ++ i ) + { + if ( std::abs( dd[ i ][ ir[ j ] - 1 ] ) <= std::abs( dd[ i ][ ir[ j ] ] ) ) + { + ir[ j ] = ir[ j ] - 1; + } + } + } + + // reconstruction u(j+1_2) + for ( int i = 0; i <= N; ++ i ) + { + int kk = ir[ i ]; + int l = i - kk; + int L = l + 1; + f[ i ] = 0; + for ( int m = 0; m < iorder; ++ m ) + { + f[ i ] += u[ kk + m ] * enocoef[ L ][ m ]; + } + } +} + +void enoR( int N, Vec1d & u, Vec1d & f ) +{ + int ighost = 3; + int iorder = 2; + int ist = 0 - ighost; + int ied = N - 1 + ighost; + + VecWrap dd; + dd.Allocate( iorder, ist, ied, 0 ); + + std::vector ir( N + 1 ); + + for ( int j = -ighost; j < N + ighost; ++j ) + { + dd[ 0 ][ j ] = u[ j ]; + } + + for ( int i = 1; i < iorder; ++ i ) + { + for ( int j = -ighost; j < N + ighost - 1; ++j ) + { + dd[ i ][ j ] = dd[ i - 1 ][ j + 1 ] - dd[ i - 1 ][ j ]; + } + } + + for ( int j = 0; j <= N; ++ j ) + { + ir[ j ] = j + 1; + for ( int i = 1; i < iorder; ++ i ) + { + if ( std::abs( dd[ i ][ ir[ j ] - 1 ] ) <= std::abs( dd[ i ][ ir[ j ] ] ) ) + { + ir[ j ] = ir[ j ] - 1; + } + } + } + + // reconstruction u(j+1_2) + for ( int i = 0; i <= N; ++ i ) + { + int kk = ir[ i ]; + int l = i - kk; + int L = l + 1; + f[ i ] = 0; + for ( int m = 0; m < iorder; ++ m ) + { + f[ i ] += u[ kk + m ] * enocoef[ L ][ m ]; + } + } +} + +void enoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + enoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void enoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + enoR( ni, u.vec( m ), f.vec( m ) ); + } +} + diff --git a/example/1d-linear-convection/eno3/cpp/01/Eno.h b/example/1d-linear-convection/eno3/cpp/01/Eno.h new file mode 100644 index 00000000..7b2c1c11 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Eno.h @@ -0,0 +1,7 @@ +#pragma once +#include "Vec1d.h" + +void enoL( int N, Vec1d & u, Vec1d & f ); +void enoR( int N, Vec1d & u, Vec1d & f ); +void enoL( int ni, VecWrap & u, VecWrap & f ); +void enoR( int ni, VecWrap & u, VecWrap & f ); \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp b/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/EulerField.h b/example/1d-linear-convection/eno3/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/eno3/cpp/01/Field.cpp b/example/1d-linear-convection/eno3/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Field.h b/example/1d-linear-convection/eno3/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Global.cpp b/example/1d-linear-convection/eno3/cpp/01/Global.cpp new file mode 100644 index 00000000..f6f55f50 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Global.cpp @@ -0,0 +1,465 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "eno3" ) + { + this->reconstruction = to_int( BasicScheme::ENO ); + } + else if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Global.h b/example/1d-linear-convection/eno3/cpp/01/Global.h new file mode 100644 index 00000000..55498419 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Global.h @@ -0,0 +1,180 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + ENO, //Weighted Essentially Non-oscillatory + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/eno3/cpp/01/Grid.cpp b/example/1d-linear-convection/eno3/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Grid.h b/example/1d-linear-convection/eno3/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp b/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/HeatField.h b/example/1d-linear-convection/eno3/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..7efc5d78 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plot.py @@ -0,0 +1,70 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +#total_t = 0.625 +total_t = 0.025 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Linear Convection_plotBAK.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp b/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/eno3/cpp/01/LogFile.h b/example/1d-linear-convection/eno3/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp b/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Parallel.h b/example/1d-linear-convection/eno3/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/Post.cpp b/example/1d-linear-convection/eno3/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Post.h b/example/1d-linear-convection/eno3/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/eno3/cpp/01/README.txt b/example/1d-linear-convection/eno3/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/eno3/cpp/01/Solver.cpp b/example/1d-linear-convection/eno3/cpp/01/Solver.cpp new file mode 100644 index 00000000..9b175c8d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Solver.cpp @@ -0,0 +1,795 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::ENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) + ) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Solver.h b/example/1d-linear-convection/eno3/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp b/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/eno3/cpp/01/Vec1d.h b/example/1d-linear-convection/eno3/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Weno.cpp b/example/1d-linear-convection/eno3/cpp/01/Weno.cpp new file mode 100644 index 00000000..2a6402d0 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Weno.cpp @@ -0,0 +1,399 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double beta1 = SQR( v2 - v1 ); + double beta2 = SQR( v3 - v2 ); + + double d1 = 2.0 / 3.0; + double d2 = 1.0 / 3.0; + + // computing nonlinear weights w1, w2, w3 + double c1 = d1 / ( SQR( beta1 + eps ) ); + double c2 = d2 / ( SQR( beta2 + eps ) ); + + double w1 = c1 / ( c1 + c2 ); + double w2 = c2 / ( c1 + c2 ); + + // candiate stencils + double q1 = - v1 / 2.0 + 3.0 / 2.0 * v2; + double q2 = v2 / 2.0 + v3 / 2.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 ); + + return f; +} + +double wcR3( double v1, double v2, double v3 ) +{ + // reconstructed value at interface + double f = 0.0; + + return f; +} + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/Weno.h b/example/1d-linear-convection/eno3/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp b/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/eno3/cpp/01/ZoneState.h b/example/1d-linear-convection/eno3/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers.json b/example/1d-linear-convection/eno3/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py b/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/cfd.json b/example/1d-linear-convection/eno3/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/heat.json b/example/1d-linear-convection/eno3/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/heat_plot.py b/example/1d-linear-convection/eno3/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/heaticp.json b/example/1d-linear-convection/eno3/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp b/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/hxmath.h b/example/1d-linear-convection/eno3/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvection.json b/example/1d-linear-convection/eno3/cpp/01/linearconvection.json new file mode 100644 index 00000000..3ecf618c --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.025, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "eno3", + "reconstruction" : "eno3", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns new file mode 100644 index 00000000..9bd44946 Binary files /dev/null and b/example/1d-linear-convection/eno3/cpp/01/linearconvection1d.cgns differ diff --git a/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json b/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json new file mode 100644 index 00000000..ceb082b6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/linearconvectionBAK.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "eno3", + "reconstruction" : "eno3", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/main.cpp b/example/1d-linear-convection/eno3/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/eno3/cpp/01/plot.py b/example/1d-linear-convection/eno3/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/eno3/cpp/01/plotting2.jl b/example/1d-linear-convection/eno3/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/eno3/cpp/01/sod.json b/example/1d-linear-convection/eno3/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_plot.py b/example/1d-linear-convection/eno3/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_sort.py b/example/1d-linear-convection/eno3/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt b/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/eno3/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt b/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cdd5e14a --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CMakeLists.txt @@ -0,0 +1,105 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..6b06414c --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.cpp @@ -0,0 +1,281 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp b/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/EulerField.h b/example/1d-linear-convection/ftbs/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Field.cpp b/example/1d-linear-convection/ftbs/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Field.h b/example/1d-linear-convection/ftbs/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Global.cpp b/example/1d-linear-convection/ftbs/cpp/01/Global.cpp new file mode 100644 index 00000000..3f560f56 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Global.cpp @@ -0,0 +1,461 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Global.h b/example/1d-linear-convection/ftbs/cpp/01/Global.h new file mode 100644 index 00000000..f89bc3c0 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Global.h @@ -0,0 +1,179 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp b/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Grid.h b/example/1d-linear-convection/ftbs/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp b/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/HeatField.h b/example/1d-linear-convection/ftbs/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Linear Convection_plot.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp b/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/LogFile.h b/example/1d-linear-convection/ftbs/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp b/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Parallel.h b/example/1d-linear-convection/ftbs/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/Post.cpp b/example/1d-linear-convection/ftbs/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Post.h b/example/1d-linear-convection/ftbs/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/ftbs/cpp/01/README.txt b/example/1d-linear-convection/ftbs/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp b/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp new file mode 100644 index 00000000..45259b3c --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Solver.cpp @@ -0,0 +1,793 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Solver.h b/example/1d-linear-convection/ftbs/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp b/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp new file mode 100644 index 00000000..c24809de --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Weno.cpp @@ -0,0 +1,363 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/Weno.h b/example/1d-linear-convection/ftbs/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers.json b/example/1d-linear-convection/ftbs/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py b/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/cfd.json b/example/1d-linear-convection/ftbs/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/heat.json b/example/1d-linear-convection/ftbs/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py b/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/heaticp.json b/example/1d-linear-convection/ftbs/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp b/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/hxmath.h b/example/1d-linear-convection/ftbs/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json b/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json new file mode 100644 index 00000000..9491dce2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "upwind1", + "reconstruction" : "upwind1", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns new file mode 100644 index 00000000..9bd44946 Binary files /dev/null and b/example/1d-linear-convection/ftbs/cpp/01/linearconvection1d.cgns differ diff --git a/example/1d-linear-convection/ftbs/cpp/01/main.cpp b/example/1d-linear-convection/ftbs/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/ftbs/cpp/01/plot.py b/example/1d-linear-convection/ftbs/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl b/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod.json b/example/1d-linear-convection/ftbs/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py b/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py b/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt b/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/ftbs/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/ftbs/python/01/ftbs.py b/example/1d-linear-convection/ftbs/python/01/ftbs.py new file mode 100644 index 00000000..8d309a89 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01/ftbs.py @@ -0,0 +1,17 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print(u) + +pyplot.plot(numpy.linspace(0, 2, nx), u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01a/ftbs.py b/example/1d-linear-convection/ftbs/python/01a/ftbs.py new file mode 100644 index 00000000..12837e6e --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01a/ftbs.py @@ -0,0 +1,27 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +pyplot.plot(numpy.linspace(0, 2, nx), u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01b/ftbs.py b/example/1d-linear-convection/ftbs/python/01b/ftbs.py new file mode 100644 index 00000000..69f21b40 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01b/ftbs.py @@ -0,0 +1,39 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +u = numpy.ones(nx) #numpy function ones() +u[int(.5 / dx):int(1 / dx + 1)] = 2 #setting u = 2 between 0.5 and 1 as per our I.C.s +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +utheory = numpy.ones(nx) + +x = numpy.linspace(0, 2, nx) + +pyplot.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +pyplot.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +pyplot.xlabel("$x$") +pyplot.ylabel("$u$") +pyplot.title("Solution field") +pyplot.legend() +pyplot.tight_layout() + +#pyplot.plot(x, u); +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01c/ftbs.py b/example/1d-linear-convection/ftbs/python/01c/ftbs.py new file mode 100644 index 00000000..8c2b7984 --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01c/ftbs.py @@ -0,0 +1,50 @@ +# Remember: comments in python are denoted by the pound sign +import numpy #here we load numpy +from matplotlib import pyplot #here we load matplotlib +import time, sys #and load some utilities + + +def set_fuction(u, ct) : + for i in range(nx): + xm = i * dx + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +total_t = dt * nt +utheory = numpy.ones(nx) +x = numpy.linspace(0, 2, nx) +print('x=',x) +u = numpy.ones(nx) #numpy function ones() + +set_fuction(u,0) +set_fuction(utheory,c * total_t) + +print('int(.5 / dx)=',int(.5 / dx)) +print('int(1 / dx + 1)=',int(1 / dx + 1)) +print(u) +print(utheory) + +un = numpy.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + #for i in range(nx): ## ... uncommenting this line and see what happens! + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +pyplot.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +pyplot.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +pyplot.xlabel("$x$") +pyplot.ylabel("$u$") +pyplot.title("Solution field") +pyplot.legend() +pyplot.tight_layout() +pyplot.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/ftbs/python/01d/ftbs.py b/example/1d-linear-convection/ftbs/python/01d/ftbs.py new file mode 100644 index 00000000..5eed5acb --- /dev/null +++ b/example/1d-linear-convection/ftbs/python/01d/ftbs.py @@ -0,0 +1,41 @@ +import numpy as np +import matplotlib.pyplot as plt +import time, sys #and load some utilities + +def set_fuction(u, ct) : + for i in range(nx): + xm = i * dx + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +nx = 41 # try changing this number from 41 to 81 and Run All ... what happens? +dx = 2 / (nx-1) +nt = 25 #nt is the number of timesteps we want to calculate +dt = .025 #dt is the amount of time each timestep covers (delta t) +c = 1 #assume wavespeed of c = 1 + +total_t = dt * nt +utheory = np.ones(nx) +x = np.linspace(0, 2, nx) +u = np.ones(nx) + +set_fuction(u,0) +set_fuction(utheory,c * total_t) + +un = np.ones(nx) #initialize a temporary array + +for n in range(nt): #loop for values of n from 0 to nt, so it will run nt times + un = u.copy() ##copy the existing values of u into un + for i in range(1, nx): ## you can try commenting this line and... + u[i] = un[i] - c * dt / dx * (un[i] - un[i-1]) + +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="FTBS scheme") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp b/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp new file mode 100644 index 00000000..6af041ac --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/BurgersField.cpp @@ -0,0 +1,366 @@ +#include "BurgersField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void BurgersField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = 0.0001; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * x[ i ] ); + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); + } + + } + + + int kkk = 1; +} + +void BurgersField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void BurgersField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + if ( Global::scheme.inviscid == to_int( BasicScheme::CENTER ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + Res[ i ] += ( - U[ i ] * ( U[ i + 1 ] - U[ i - 1 ] ) / dx ); + } + } + } + else + { + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & U = u.vec( m ); + Vec1d & Res = res.vec( m ); + Vec1d & UL = uL.vec( m ); + Vec1d & UR = uR.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + if ( U[ i ] >= 0.0 ) + { + Res[ i ] += ( - U[ i ] * ( UL[ i + 1 ] - UL[ i ] ) / dx ); + } + else + { + Res[ i ] += ( - U[ i ] * ( UR[ i + 1 ] - UR[ i ] ) / dx ); + } + } + } + } +} + +void BurgersField::WaveSpeed( VecWrap & um, VecWrap & psm ) +{ + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = um.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + ps[ i ] = std::max( { std::abs( u[ i - 2 ] ), std::abs( u[ i - 1 ] ), std::abs( u[ i ] ), std::abs( u[ i + 1 ] ), std::abs( u[ i + 2 ] ) } ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } + } +} + +void BurgersField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + burgers_fluxes( ist, ied, u, f ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & FP = fP.vec( m ); + Vec1d & FN = fN.vec( m ); + Vec1d & F = f.vec( m ); + Vec1d & ps = psm.vec( m ); + for ( int i = ist; i <= ied; ++ i ) + { + FP[ i ] = 0.5 * ( F[ i ] + ps[ i ] * u[ i ] ); + FN[ i ] = 0.5 * ( F[ i ] - ps[ i ] * u[ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } +} + +void BurgersField::burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ) +{ + Vec1d & F = f.vec(); + Vec1d & U = u.vec(); + for ( int i = ist; i <= ied; ++ i ) + { + F[ i ] = 0.5 * U[ i ] * U[ i ]; + } +} + +void BurgersField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + burgers_fluxes( 0, nx, uL, fL ); + burgers_fluxes( 0, nx, uR, fR ); + + VecWrap psm; + psm.Allocate( this->nequ, ist, ied, 0 ); + + WaveSpeed( u, psm ); + + //fluxes at the interface + Vec1d f; + f.Allocate( 0, nx, 0 ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & qL = uL.vec( m ); + Vec1d & qR = uR.vec( m ); + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & ps = psm.vec( m ); + + for ( int i = 0; i <= nx; ++ i ) + { + f[ i ] = 0.5 * ( FR[ i ] + FL[ i ] ) - 0.5 * ps[ i ] * ( qR[ i ] - qL[ i ] ); + } + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( f[ i + 1 ] - f[ i ] ) / dx; + } + } + +} + + +void BurgersField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void BurgersField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void BurgersField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void BurgersField::UpdateOldField() +{ + this->un = this->u; +} + +void BurgersField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } + +} + +void BurgersField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void BurgersField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/BurgersField.h b/example/1d-linear-convection/weno3/cpp/01/BurgersField.h new file mode 100644 index 00000000..bd07a1f2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/BurgersField.h @@ -0,0 +1,31 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class BurgersField : public Field +{ +public: + int nt; + double dx; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & um, VecWrap & psm ); +public: + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void burgers_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + + diff --git a/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt b/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt new file mode 100644 index 00000000..cdd5e14a --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CMakeLists.txt @@ -0,0 +1,105 @@ +cmake_minimum_required(VERSION 3.31) + +project( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +message ( STATUS "EIGEN3_INCLUDE_DIR = ${EIGEN3_INCLUDE_DIR}" ) + +find_package(nlohmann_json) + +list ( APPEND PRJ_LIBRARIES nlohmann_json::nlohmann_json ) + +find_package ( MPI ) + +message ( STATUS "MPI_FOUND=${MPI_FOUND}" ) +message ( STATUS "MPI_CXX_INCLUDE_DIRS=${MPI_CXX_INCLUDE_DIRS}" ) +message ( STATUS "MPI_LIBRARIES=${MPI_LIBRARIES}" ) +if ( MPI_FOUND ) + list ( APPEND PRJ_INCLUDE_DIRS ${MPI_CXX_INCLUDE_DIRS} ) + list ( APPEND PRJ_LIBRARIES ${MPI_LIBRARIES} ) +endif () + +list ( APPEND PRJ_LIBRARIES MPI::MPI_C ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +list ( APPEND PRJ_COMPILE_DEFINITIONS HX_PARALLEL ) + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} +) + +set( PROJECT_SOURCES + main.cpp + Vec1d.h Vec1d.cpp + CgnsUtil.h CgnsUtil.cpp + ConvectionField.h ConvectionField.cpp + Field.h Field.cpp + BurgersField.h BurgersField.cpp + EulerField.h EulerField.cpp + HeatField.h HeatField.cpp + Global.h Global.cpp + Grid.h Grid.cpp + hxmath.h hxmath.cpp + LogFile.h LogFile.cpp + Parallel.h Parallel.cpp + Post.h Post.cpp + Solver.h Solver.cpp + Weno.h Weno.cpp + ZoneState.h ZoneState.cpp +) + +message( STATUS "PROJECT_NAME = ${PROJECT_NAME}") +message( STATUS "PROJECT_SOURCES = ${PROJECT_SOURCES}") + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PROJECT_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp new file mode 100644 index 00000000..0e10b205 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.cpp @@ -0,0 +1,584 @@ +#include "CgnsUtil.h" +#include "Global.h" +#include "Grid.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "cgnslib.h" +#include +#include + +BaseZoneList global_zone_names; + +void ReadCgnsGridBaseZone( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + + HXBcastData( &nzones, 1, Parallel::serverid ); + + ZoneState::nZones = nzones; + ZoneState::pids.resize( nzones ); + ZoneState::g2lzoneids.resize( nzones ); + std::vector pcount( Parallel::nProc, 0 ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int zone_pid = iZone % Parallel::nProc; + ZoneState::pids[ iZone ] = zone_pid; + ZoneState::g2lzoneids[ iZone ] = pcount[ zone_pid ]; + pcount[ zone_pid ] ++; + } + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << "\n"; + + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXBcastData( &index_dim, 1, Parallel::serverid ); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + + std::vector isize( index_dim * 3 ); + + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + HXBcastData( zonename, 33, Parallel::serverid ); + HXBcastData( isize.data(), isize.size(), Parallel::serverid); + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + + BaseZone baseZone; + baseZone.zone_name = zonename; + + global_zone_names.AddBaseZone( baseZone ); + } + } + + if ( Parallel::IsServer() ) + { + cg_close( fileId ); + } +} + +void ReadCgnsGrid( const std::string & filename ) +{ + int fileId = -1; + if ( Parallel::IsServer() ) + { + cg_open( filename.c_str(), CG_MODE_READ, &fileId ); + std::cout << "fileId = " << fileId << "\n"; + } + + int nbases = -1; + if ( Parallel::IsServer() ) + { + cg_nbases( fileId, &nbases ); + } + HXBcastData( &nbases, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbases = " << nbases << "\n"; + + for ( int iBase = 0; iBase < nbases; ++ iBase ) + { + char basename[ 33 ]; + int baseId = iBase + 1; + int icelldim = -1; + int iphysdim = -1; + if ( Parallel::IsServer() ) + { + cg_base_read( fileId, baseId, basename, &icelldim, &iphysdim ); + } + + HXBcastData( &icelldim, 1, Parallel::serverid ); + HXBcastData( &iphysdim, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + Global::cell_dim = icelldim; + Global::phys_dim = iphysdim; + + int nzones = -1; + if ( Parallel::IsServer() ) + { + cg_nzones( fileId, baseId, &nzones ); + } + HXBcastData( &nzones, 1, Parallel::serverid ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nzones = " << nzones << "\n"; + + for ( int iZone = 0; iZone < nzones; ++ iZone ) + { + int zoneId = iZone + 1; + int index_dim = -1; + if ( Parallel::IsServer() ) + { + cg_index_dim( fileId, baseId, zoneId, &index_dim ); + } + HXSendRecvData( &index_dim, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "index_dim = " << index_dim << "\n"; + } + + std::vector isize; + char zonename[ 33 ]; + if ( Parallel::IsServer() ) + { + isize.resize( index_dim * 3 ); + cg_zone_read( fileId, baseId, zoneId, zonename, isize.data() ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + isize.resize( index_dim * 3 ); + } + + HXSendRecvData( zonename, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( isize.data(), index_dim * 3, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zonename = " << zonename << "\n"; + + for ( int i = 0; i < isize.size(); ++ i ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "i = " << i << " isize = " << isize[ i ] << "\n"; + } + } + + std::vector irmin; + std::vector irmax; + int nNodes = 1; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + irmin.resize( index_dim ); + irmax.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + /* lower range index */ + irmin[ m ] = 1; + /* upper range index of vertices */ + irmax[ m ] = isize[ m ]; + nNodes *= irmax[ m ]; + } + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nNodes = " << nNodes << "\n"; + } + + ZoneType_t zoneType; + if ( Parallel::IsServer() ) + { + cg_zone_type( fileId, baseId, zoneId, &zoneType ); + } + HXSendRecvData( &zoneType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneType = " << zoneType << " ZoneTypeName = " << ZoneTypeName[ zoneType ] << "\n"; + } + + Zone * zone = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zone = new Zone(); + Global::zones.push_back( zone ); + LocalZone::global_zoneids.push_back( iZone ); + LocalZone::nZones = LocalZone::global_zoneids.size(); + for ( int m = 0; m < index_dim; ++ m ) + { + zone->nijk.push_back( isize[ m ] ); + } + } + + Grid * grid = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + grid = new Grid(); + Global::grids.push_back( grid ); + } + + BaseZone baseZone; + + int gZoneId = -1; + if ( Parallel::IsServer() ) + { + baseZone.zone_name = zonename; + gZoneId = global_zone_names.FindBaseZone( baseZone ); + } + + HXSendRecvData( &gZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "gZoneId = " << gZoneId << "\n"; + } + + int ncoords = -1; + if ( Parallel::IsServer() ) + { + cg_ncoords( fileId, baseId, zoneId, &ncoords ); + } + HXSendRecvData( &ncoords, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ncoords = " << ncoords << "\n"; + } + + for ( int icoord = 0; icoord < ncoords; ++ icoord ) + { + int coorId = icoord + 1; + DataType_t dataType; + char coordname[ 33 ]; + if ( Parallel::IsServer() ) + { + cg_coord_info( fileId, baseId, zoneId, coorId, &dataType, coordname ); + } + HXSendRecvData( coordname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &dataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "coordname = " << coordname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "dataType = " << dataType << " DataTypeName = " << DataTypeName[ dataType ] << "\n"; + } + + std::vector coord; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + coord.resize( nNodes * sizeof( double ) ); + } + + if ( Parallel::IsServer() ) + { + cg_coord_read( fileId, baseId, zoneId, coordname, dataType, irmin.data(), irmax.data(), coord.data() ); + } + + HXSendRecvData( coord.data(), coord.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + Coor * coor = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + coor = new Coor(); + zone->coors.push_back( coor ); + coor->coorname = coordname; + coor->nNodes = nNodes; + coor->coord = coord; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + coor->DumpCoor(); + + if ( icoord == 0 ) + { + grid->Allocate( nNodes ); + coor->DumpCoorX( grid->x ); + } + } + } + + int nbocos = -1; + if ( Parallel::IsServer() ) + { + cg_nbocos( fileId, baseId, zoneId, &nbocos ); + } + HXSendRecvData( &nbocos, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbocos = " << nbocos << "\n"; + } + + for ( int iboco = 0; iboco < nbocos; ++ iboco ) + { + int bccoId = iboco + 1; + GridLocation_t location; + if ( Parallel::IsServer() ) + { + cg_boco_gridlocation_read( fileId, baseId, zoneId, bccoId, &location ); + } + HXSendRecvData( &location, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iboco = " << iboco << " location = " << location << " GridLocationName = " << GridLocationName[location] << "\n"; + } + + char boconame[ 33 ]; + BCType_t bocotype; + PointSetType_t ptset_type; + cgsize_t npnts = 0; + //std::vector normalIndex( index_dim, -1 ); + std::vector normalIndex; + cgsize_t normalListSize = 0; + DataType_t normalDataType; + int ndataset = -1; + if ( Parallel::IsServer() ) + { + normalIndex.resize( index_dim ); + cg_boco_info( fileId, baseId, zoneId, bccoId, boconame, &bocotype, &ptset_type, + &npnts, normalIndex.data(), &normalListSize, &normalDataType, &ndataset ); + } + + if ( ZoneState::IsValid( iZone ) ) + { + normalIndex.resize( index_dim ); + } + + HXSendRecvData( boconame, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &bocotype, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ptset_type, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &npnts, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalDataType, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &normalListSize, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( normalIndex.data(), index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( &ndataset, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "boconame = " << boconame << " bocotype = " << bocotype << " BCTypeName = " << BCTypeName[ bocotype ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ptset_type = " << ptset_type << " PointSetTypeName = " << PointSetTypeName[ptset_type] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "npnts = " << npnts << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalListSize = " << normalListSize << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalDataType = " << normalDataType << " DataTypeName = " << DataTypeName[ normalDataType ] << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "normalIndex = "; + for ( int i = 0; i < index_dim; ++ i ) + { + std::cout << normalIndex[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "ndataset = " << ndataset << "\n"; + } + + std::vector normalList; + std::vector pnts; + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + if ( normalDataType == DataTypeNull ) + { + normalList.resize( sizeof( int ) ); + } + else + { + int nSize = nNodes * index_dim * sizeof( double ); + normalList.resize( nSize ); + } + pnts.resize( npnts * index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_boco_read( fileId, baseId, zoneId, bccoId, pnts.data(), normalList.data() ); + } + + HXSendRecvData( pnts.data(), npnts * index_dim, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "pnts = "; + for ( int i = 0; i < pnts.size(); ++ i ) + { + std::cout << pnts[ i ] << " "; + } + std::cout << "\n"; + } + HXSendRecvData( normalList.data(), normalList.size(), Parallel::serverid, ZoneState::GetProcID(iZone)); + + ZoneBc * zonebc = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc = new ZoneBc(); + zone->bccos.push_back( zonebc ); + zonebc->bcType = bocotype; + for ( int i = 0; i < pnts.size(); ++ i ) + { + zonebc->pnts.push_back( pnts[ i ] ); + } + } + } + int n1to1 = -1; + if ( Parallel::IsServer() ) + { + cg_n1to1( fileId, baseId, zoneId, &n1to1 ); + } + + HXSendRecvData( &n1to1, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "n1to1 = " << n1to1 << "\n"; + } + + for ( int i1to1 = 0; i1to1 < n1to1; ++ i1to1 ) + { + int i1to1Id = i1to1 + 1; + + char connectname[ 33 ]; + char donorname[ 33 ]; + cgsize_t npnts = 2; + std::vector range; + std::vector donor_range; + std::vector transform; + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + range.resize( npnts * index_dim ); + donor_range.resize( npnts * index_dim ); + transform.resize( index_dim ); + } + + if ( Parallel::IsServer() ) + { + cg_1to1_read( fileId, baseId, zoneId, i1to1Id, connectname, donorname, range.data(), donor_range.data(), transform.data() ); + } + + HXSendRecvData( connectname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donorname, 33, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( range.data(), range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( donor_range.data(), donor_range.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + HXSendRecvData( transform.data(), transform.size(), Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + if ( ZoneState::IsValid( iZone ) || Parallel::IsServer() ) + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "connectname = " << connectname << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donorname = " << donorname << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "range = "; + for ( int i = 0; i < range.size(); ++ i ) + { + std::cout << range[ i ] << " "; + } + std::cout << "\n"; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "donor_range = "; + for ( int i = 0; i < donor_range.size(); ++ i ) + { + std::cout << donor_range[ i ] << " "; + } + std::cout << "\n"; + + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "transform = "; + for ( int i = 0; i < transform.size(); ++ i ) + { + std::cout << transform[ i ] << " "; + } + std::cout << "\n"; + } + + int gDonorZoneId = -1; + if ( Parallel::IsServer() ) + { + BaseZone baseZoneDonor; + baseZoneDonor.zone_name = donorname; + + gDonorZoneId = global_zone_names.FindBaseZone( baseZoneDonor ); + } + + HXSendRecvData( &gDonorZoneId, 1, Parallel::serverid, ZoneState::GetProcID( iZone ) ); + + ZoneBc1To1 * zonebc_1to1 = nullptr; + if ( ZoneState::IsValid( iZone ) ) + { + zonebc_1to1 = new ZoneBc1To1(); + zone->bc1to1s.push_back( zonebc_1to1 ); + zonebc_1to1->zoneid = gZoneId; + zonebc_1to1->transform = transform; + zonebc_1to1->donor_zoneid = gDonorZoneId; + + for ( int i = 0; i < range.size(); ++ i ) + { + zonebc_1to1->pnts.push_back( range[ i ] ); + zonebc_1to1->donor_pnts.push_back( donor_range[ i ] ); + } + } + } + } + } + + { + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Global::zones.size() = " << Global::zones.size() << "\n"; + } + + cg_close( fileId ); +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h new file mode 100644 index 00000000..dba4a529 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/CgnsUtil.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +class BaseZone +{ +public: + //int baseId; + std::string zone_name; + bool operator < ( const BaseZone & rhs ) const + { + //if ( this->baseId != rhs.baseId ) + //{ + // return this->baseId < rhs.baseId; + //} + + return this->zone_name < rhs.zone_name; + } +}; + +class BaseZoneList +{ +public: + std::map basezone_map; +public: + void AddBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter; + iter = basezone_map.find( baseZone ); + if ( iter == basezone_map.end() ) + { + int id = basezone_map.size(); + basezone_map.insert( std::make_pair( baseZone, id ) ); + } + } + + int FindBaseZone( const BaseZone & baseZone ) + { + std::map::iterator iter = basezone_map.find( baseZone ); + if ( iter != basezone_map.end() ) + { + return iter->second; + } + return -1; + } +}; + +void ReadCgnsGridBaseZone( const std::string & filename ); +void ReadCgnsGrid( const std::string & filename ); \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp new file mode 100644 index 00000000..6b06414c --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.cpp @@ -0,0 +1,281 @@ +#include "ConvectionField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include +#include + +void ConvectionField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + this->c = 1.0; +} + +void ConvectionField::InitFieldAsRestart( Grid * grid ) +{ + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + Vec1d & x = grid->x; + for ( int i = 0; i < ni; ++ i ) + { + if ( x[ i ] >= 0.5 && x[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] >= 0.5 && xcc[ i ] <= 1.0 ) + { + u[ i ] = 2; + } + else + { + u[ i ] = 1; + } + } + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void ConvectionField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double um = std::atof( row[ 1 ].data() ); + this->u[ 0 ][ i ] = um; + } + int kkk = 1; +} + +void ConvectionField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void ConvectionField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < nx; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < nx; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ nx ] + 2 * rr * ( u[ nx - 2 ] - 2 * u[ nx - 1 ] + u[ nx ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ nx - 1 ] -= c[ nx - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < nx; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void ConvectionField::UpdateOldField() +{ + this->un = this->u; +} + +void ConvectionField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + if ( Global::iconservation == 0 ) + { + this->InviscidNonConservative( u, res ); + } + else + { + this->InviscidConservative( u, res ); + } +} + +void ConvectionField::InviscidNonConservative( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::UpWind1 ) ) + { + Upwind1L( nx, u, uL ); + Upwind1R( nx, u, uR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + Vec1d & u_L = uL.vec( m ); + Vec1d & u_R = uR.vec( m ); + double cp = 0.5 * ( c + std::abs( c ) ); + double cn = 0.5 * ( c - std::abs( c ) ); + for ( int i = 0; i < nx; ++ i ) + { + double fip = cp * u_L[ i + 1 ] + cn * u_R[ i + 1 ]; + double fim = cp * u_L[ i ] + cn * u_R[ i ]; + res[ i ] += - ( fip - fim ) / dx; + } + } +} + +void ConvectionField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ +} + +void ConvectionField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void ConvectionField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void ConvectionField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void ConvectionField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.25f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h new file mode 100644 index 00000000..ef8848e2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ConvectionField.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class ConvectionField : public Field +{ +public: + int nt; + double dx; + double c; + double alpha, beta; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void InviscidNonConservative( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp b/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp new file mode 100644 index 00000000..fa1ef8ca --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/EulerField.cpp @@ -0,0 +1,818 @@ +#include "EulerField.h" +#include "Weno.h" +#include "hxmath.h" +#include "Global.h" +#include "Grid.h" +#include "cgnslib.h" +#include +#include +#include +#include +#include + +void EulerField::InitFieldCommon( Grid * grid ) +{ + this->grid = grid; + this->nequ = Global::nequ; + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = Global::dt; + this->nt = std::round( Global::total_time / dt ); + + std::print( "ni={}\n", ni ); + std::print( "dt={}\n", dt ); + std::print( "dx={}\n", dx ); + std::print( "nt={}\n", nt ); + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + gamma = 1.4; // specific gas ratio +} + +void EulerField::InitFieldAsRestart( Grid * grid ) +{ + this->InitSodShockTube( grid ); +} + +void EulerField::InitSodShockTube( Grid * grid ) +{ + //Sod's Riemann problem + // Left side + double rhoL = 1.0; + double uL = 0.0; + double pL = 1.0; + // Right side + double rhoR = 0.125; + double uR = 0.0; + double pR = 0.1; + + double xc = 0.5; //seperator location + + if ( Global::ifinite_volume == 0 ) + { + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + Vec1d & q0 = this->u.vec( 0 ); + Vec1d & q1 = this->u.vec( 1 ); + Vec1d & q2 = this->u.vec( 2 ); + + double rho, u, p, e; + //i=0,1,...,nx-1 + for ( int i = 0; i < nic; ++ i ) + { + if ( xcc[ i ] > xc ) + { + rho = rhoR; + u = uR; + p = pR; + } + else + { + rho = rhoL; + u = uL; + p = pL; + } + e = p / ( rho * ( gamma - 1.0 ) ) + 0.5 * u * u; + + //conservative variables + q0[ i ] = rho; + q1[ i ] = rho * u; + q2[ i ] = rho * e; + } + } + + int kkk = 1; +} + +void EulerField::ReadFlowField( std::fstream & file, Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->ReadFlowField( file, grid->xcc, u ); + } + else + { + this->ReadFlowField( file, grid->x, u ); + } +} + +void EulerField::ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + std::string line; + std::getline( file, line ); + std::stringstream ss( line ); + std::string item; + std::vector row; + while ( std::getline(ss, item, ' ') ) + { + row.push_back( item ); + } + double rho = std::atof( row[ 1 ].data() ); + double rhou = std::atof( row[ 2 ].data() ); + double rhoe = std::atof( row[ 3 ].data() ); + this->u[ 0 ][ i ] = rho; + this->u[ 1 ][ i ] = rhou; + this->u[ 2 ][ i ] = rhoe; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + } + int kkk = 1; +} + +void EulerField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + this->InviscidConservative( u, res ); +} + +void EulerField::WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + for ( int i = 0; i <= nx; ++ i ) + { + // left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm1 * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + // Right state; + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm1 * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double ubar = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hbar = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } + + for ( int i = ps.ist; i < 0; ++ i ) + { + ps[ i ] = ps[ 0 ]; + } + + for ( int i = nx + 1; i <= ps.ied; ++ i ) + { + ps[ i ] = ps[ nx ]; + } +} + +void EulerField::LaxWaveSpeed( VecWrap & q, Vec1d & ps ) +{ + //spectral radius of Jacobian + double gm1 = gamma - 1.0; + int ist = ps.ist; + int ied = ps.ied; + for ( int i = ist; i <= ied; ++ i ) + { + // left state + double rhom = q[ 0 ][ i ]; + double um = q[ 1 ][ i ] / rhom; + double em = q[ 2 ][ i ] / rhom; + double pm = gm1 * ( rhom * em - 0.5 * rhom * ( um * um ) ); + double hm = em + pm / rhom; + + double ubar = std::sqrt( std::abs( rhom ) ) * um; + double hbar = std::sqrt( std::abs( rhom ) ) * hm; + double cbar = std::sqrt( std::abs( gm1 * ( hbar - 0.5 * ubar * ubar ) ) ); + + ps[ i ] = std::abs( cbar + ubar ); + } +} + +void EulerField::LaxFriedrichs( VecWrap & u, VecWrap & res ) +{ + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + VecWrap f, fP, fN; + + f.Allocate( this->nequ, ist, ied, 0 ); + fP.Allocate( this->nequ, ist, ied, 0 ); + fN.Allocate( this->nequ, ist, ied, 0 ); + + euler_fluxes( ist, ied, u, f ); + + Vec1d ps; + ps.Allocate( ist, ied, 0 ); + LaxWaveSpeed( u, ps ); + + // left and right side fluxes at the interface + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = ist; i <= ied; ++ i ) + { + fP[ m ][ i ] = 0.5 * ( f[ m ][ i ] + ps[ i ] * u[ m ][ i ] ); + fN[ m ][ i ] = 0.5 * ( f[ m ][ i ] - ps[ i ] * u[ m ][ i ] ); + } + } + + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, fP, fL ); + crwenoR( nx, fN, fR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, fP, fL ); + wenoR( nx, fN, fR ); + } + + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & FL = fL.vec( m ); + Vec1d & FR = fR.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < nx; ++ i ) + { + res[ i ] -= ( FL[ i + 1 ] - FL[ i ] ) / dx + ( FR[ i + 1 ] - FR[ i ] ) / dx; + } + } + +} + +//Calculate fluxes +void EulerField::euler_fluxes( int ist, int ied, VecWrap & q, VecWrap & f ) +{ + //i=0,1,...,nx + for ( int i = ist; i <= ied; ++ i ) + { + double rho = q[ 0 ][ i ]; + double rhou = q[ 1 ][ i ]; + double rhoe = q[ 2 ][ i ]; + double p = ( gamma - 1.0 ) * ( rhoe - 0.5 * SQR( rhou ) / rho ); + f[ 0 ][ i ] = rhou; + f[ 1 ][ i ] = rhou * rhou / rho + p; + f[ 2 ][ i ] = rhou * rhoe / rho + p * rhou / rho; + if ( std::isnan( rho ) ) + { + int kkk = 1; + } + + } +} + +void EulerField::rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + Vec1d ps; + ps.Allocate( 0, nx, 0 ); + + WaveSpeed( qL, qR, ps ); + + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i <= nx; ++ i ) + { + //Interface fluxes (Rusanov) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * ps[ i ] * ( qR[ m ][ i ] - qL[ m ][ i ] ); + } + } +} + +void EulerField::hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector Ds( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //left state + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + double cL = std::sqrt( std::abs( gamma * pL / rhoL ) ); + + //right state + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + double cR = std::sqrt( std::abs( gamma * pR / rhoR ) ); + + //compute SL and Sr + double SL = std::min( uL, uR ) - std::max( cL, cR ); + double SR = std::max( uL, uR ) + std::max( cL, cR ); + + //compute compound speed + double term1 = pR - pL + rhoL * uL * ( SL - uL ) - rhoR * uR * ( SR - uR ); + double term2 = rhoL * ( SL - uL ) - rhoR * ( SR - uR ); + double SP = term1 / term2; //never get zero; + + //compute compound pressure + double PLR = 0.5 * ( pL + pR + rhoL * ( SL - uL ) * ( SP - uL ) + rhoR * ( SR - uR ) * ( SP - uR ) ); + + //compute D + Ds[ 0 ] = 0.0; + Ds[ 1 ] = 1.0; + Ds[ 2 ] = SP; + + if ( std::isnan( fL[ 0 ][ i ] ) || std::isnan( fR[ 0 ][ i ] ) ) + { + int kkk = 1; + } + + if ( SL >= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fL[ m ][ i ]; + } + } + else if ( SR <= 0.0 ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = fR[ m ][ i ]; + } + } + else if ( ( SP >= 0.0 ) && ( SL <= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SL * qL[ m ][ i ] - fL[ m ][ i ] ) + SL * PLR * Ds[ m ] ) / ( SL - SP ); + } + } + else if ( ( SP <= 0.0 ) && ( SR >= 0.0 ) ) + { + for ( int m = 0; m < nequ; ++ m ) + { + f[ m ][ i ] = ( SP * ( SR * qR[ m ][ i ] - fR[ m ][ i ] ) + SR * PLR * Ds[ m ] ) / ( SR - SP ); + } + } + } +} + +void EulerField::roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ) +{ + std::vector dd( 3, 0 ); + std::vector dF( 3, 0 ); + std::vector dQ( 3, 0 ); + double gm = gamma - 1.0; + + // i=0,1,...,nx + for ( int i = 0; i <= nx; ++ i ) + { + //Left and right states: + double rhoL = qL[ 0 ][ i ]; + double uL = qL[ 1 ][ i ] / rhoL; + double eL = qL[ 2 ][ i ] / rhoL; + double pL = gm * ( rhoL * eL - 0.5 * rhoL * ( uL * uL ) ); + double hL = eL + pL / rhoL; + + double rhoR = qR[ 0 ][ i ]; + double uR = qR[ 1 ][ i ] / rhoR; + double eR = qR[ 2 ][ i ] / rhoR; + double pR = gm * ( rhoR * eR - 0.5 * rhoR * ( uR * uR ) ); + double hR = eR + pR / rhoR; + + double alpha = 1.0 / ( std::sqrt( std::abs( rhoL ) ) + std::sqrt( std::abs( rhoR ) ) ); + + double uu = ( std::sqrt( std::abs( rhoL ) ) * uL + std::sqrt( std::abs( rhoR ) ) * uR ) * alpha; + double hh = ( std::sqrt( std::abs( rhoL ) ) * hL + std::sqrt( std::abs( rhoR ) ) * hR ) * alpha; + double aa = std::sqrt( std::abs( gm * ( hh - 0.5 * uu * uu ) ) ); + + double D11 = std::abs( uu ); + double D22 = std::abs( uu + aa ); + double D33 = std::abs( uu - aa ); + + double beta = 0.5 / ( aa * aa ); + double phi2 = 0.5 * gm * uu * uu; + + //Right eigenvector matrix + double R11 = 1.0; + double R21 = uu; + double R31 = phi2 / gm; + double R12 = beta; + double R22 = beta * ( uu + aa ); + double R32 = beta * ( hh + uu * aa ); + double R13 = beta; + double R23 = beta * ( uu - aa ); + double R33 = beta * ( hh - uu * aa ); + + //Left eigenvector matrix + double L11 = 1.0 - phi2 / ( aa * aa ); + double L12 = gm * uu / ( aa * aa ); + double L13 = -gm / ( aa * aa ); + + double L21 = phi2 - uu * aa; + double L22 = - gm * uu + aa; + double L23 = gm; + + double L31 = phi2 + uu * aa; + double L32 = - gm * uu - aa; + double L33 = gm; + + for ( int m = 0; m < nequ; ++ m ) + { + dQ[ m ] = qR[ m ][ i ] - qL[ m ][ i ]; + } + + dd[ 0 ] = D11 * ( L11 * dQ[ 0 ] + L12 * dQ[ 1 ] + L13 * dQ[ 2 ] ); + dd[ 1 ] = D22 * ( L21 * dQ[ 0 ] + L22 * dQ[ 1 ] + L23 * dQ[ 2 ] ); + dd[ 2 ] = D33 * ( L31 * dQ[ 0 ] + L32 * dQ[ 1 ] + L33 * dQ[ 2 ] ); + + dF[ 0 ] = R11 * dd[ 0 ] + R12 * dd[ 1 ] + R13 * dd[ 2 ]; + dF[ 1 ] = R21 * dd[ 0 ] + R22 * dd[ 1 ] + R23 * dd[ 2 ]; + dF[ 2 ] = R31 * dd[ 0 ] + R32 * dd[ 1 ] + R33 * dd[ 2 ]; + + for ( int m = 0; m < nequ; ++ m ) + { + //Interface fluxes (Roe) + f[ m ][ i ] = 0.5 * ( fR[ m ][ i ] + fL[ m ][ i ] ) - 0.5 * dF[ m ]; + } + } +} + +void EulerField::Hllc( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + hllc_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + if ( std::isnan( res[ m ][ i ] ) ) + { + int kkk = 1; + } + } + } +} + +void EulerField::Roe( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using Roe scheme(flux at interface) + roe_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::Rusanov( VecWrap & u, VecWrap & res ) +{ + VecWrap uL, uR; + uL.Allocate( this->nequ, 0, nx, 0 ); + uR.Allocate( this->nequ, 0, nx, 0 ); + + //WENO Reconstruction + if ( Global::scheme.reconstruction == to_int( BasicScheme::CRWENO ) ) + { + crwenoL( nx, u, uL ); + crwenoR( nx, u, uR ); + } + else if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) ) + { + wenoL( nx, u, uL ); + wenoR( nx, u, uR ); + } + + //left and right side fluxes at the interface + VecWrap fL, fR; + fL.Allocate( this->nequ, 0, nx, 0 ); + fR.Allocate( this->nequ, 0, nx, 0 ); + + int ist = 0 - Global::nghost; + int ied = this->nx - 1 + Global::nghost; + + //Computing fluxes + euler_fluxes( 0, nx, uL, fL ); + euler_fluxes( 0, nx, uR, fR ); + + //fluxes at the interface + VecWrap f; + f.Allocate( this->nequ, 0, nx, 0 ); + + //compute Riemann solver using HLLC scheme + rusanov_flux( uL, uR, fL, fR, f ); + + //Interface fluxes (Rusanov) + for ( int m = 0; m < nequ; ++ m ) + { + for ( int i = 0; i < nx; ++ i ) + { + res[ m ][ i ] -= ( f[ m ][ i + 1 ] - f[ m ][ i ] ) / dx; + } + } + +} + +void EulerField::InviscidConservative( VecWrap & u, VecWrap & res ) +{ + if ( Global::scheme.inviscid == to_int( BasicScheme::HLLC ) ) + { + this->Hllc( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::LAX ) ) + { + this->LaxFriedrichs( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Roe ) ) + { + this->Roe( u, res ); + } + else if ( Global::scheme.inviscid == to_int( BasicScheme::Rusanov ) ) + { + this->Rusanov( u, res ); + } + } + +void EulerField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void EulerField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + if ( Global::iviscous > 0 ) + { + ViscousResidual( u, res ); + } + } + +void EulerField::UpdateOldField() +{ + this->un = this->u; +} + +void EulerField::DumpField( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +void EulerField::PostProcess( Grid * grid ) +{ + if ( Global::ifinite_volume == 1 ) + { + this->DumpField( grid->xcc, u ); + } + else + { + this->DumpField( grid->x, u ); + } +} + +//void EulerField::DumpField( Vec1d & x, VecWrap & u ) +//{ +// for ( int i = 0; i < x.size(); ++ i ) +// { +// Global::file_string += std::format( "{:.25f}", x[ i ] ); +// for ( int m = 0; m < nequ; ++ m ) +// { +// Vec1d & u = this->u.vec( m ); +// Global::file_string += std::format( " {:.25f}", u[ i ] ); +// } +// Global::file_string += std::format( "\n" ); +// } +//} + +void EulerField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.25f}", x[ i ] ); + double rho = u[ 0 ][ i ]; + double rhou = u[ 1 ][ i ]; + double rhoe = u[ 2 ][ i ]; + double um = rhou / rho; + Global::file_string += std::format( " {:.25f}", rho ); + Global::file_string += std::format( " {:.25f}", rhou ); + Global::file_string += std::format( " {:.25f}", rhoe ); + Global::file_string += std::format( " {:.25f}", um ); + + Global::file_string += std::format( "\n" ); + } +} + +void EulerField::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCExtrapolate || bcType == BCOutflow ) + { + this->OutflowBc( region ); + } +} + +void EulerField::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} + +void EulerField::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig1 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig2 ] = u[ m ][ in ]; + } + + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + for ( int m = 0; m < nequ; ++ m ) + { + u[ m ][ ig3 ] = u[ m ][ in ]; + } + } + } + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/EulerField.h b/example/1d-linear-convection/weno3/cpp/01/EulerField.h new file mode 100644 index 00000000..7e71cfdc --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/EulerField.h @@ -0,0 +1,45 @@ +#pragma once +#include "Vec1d.h" +#include "Field.h" +#include + +class EulerField : public Field +{ +public: + int nt; + double dx; + double gamma; +public: + void InitFieldCommon( Grid * grid ) override; + void InitFieldAsRestart( Grid * grid ) override; + void ReadFlowField( std::fstream & file, Grid * grid ) override; + void ReadFlowField( std::fstream & file, Vec1d & x, VecWrap & u ); + void InitSodShockTube( Grid * grid ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void InviscidConservative( VecWrap & u, VecWrap & res ); + void WaveSpeed( VecWrap & qL, VecWrap & qR, Vec1d & ps ); + void LaxWaveSpeed( VecWrap & q, Vec1d & ps ); +public: + void Hllc( VecWrap & u, VecWrap & res ); + void LaxFriedrichs( VecWrap & u, VecWrap & res ); + void Roe( VecWrap & u, VecWrap & res ); + void Rusanov( VecWrap & u, VecWrap & res ); + void euler_fluxes( int ist, int ied, VecWrap & u, VecWrap & f ); + void hllc_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void roe_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); + void rusanov_flux( VecWrap & qL, VecWrap & qR, VecWrap & fL, VecWrap & fR, VecWrap & f ); +public: + void UpdateOldField(); + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +public: + void Boundary( Region & region, int bcType ); + void InflowBc( Region & region ); + void OutflowBc( Region & region ); +}; + + diff --git a/example/1d-linear-convection/weno3/cpp/01/Field.cpp b/example/1d-linear-convection/weno3/cpp/01/Field.cpp new file mode 100644 index 00000000..e18c65a4 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Field.cpp @@ -0,0 +1,342 @@ +#include "Field.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void Field::CrankNicolsonSeries( Zone * zone ) +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::CN: + this->CN( zone ); + break; + case BasicScheme::ICP: + this->ICP( zone ); + break; + default: + this->CN( zone ); + } +} + +void Field::RungeKutta( Zone * zone, int nStage, int istage ) +{ + if ( nStage == 1 ) + { + this->RungeKutta1( zone, istage ); + } + else if ( nStage == 3 ) + { + this->RungeKutta3( zone, istage ); + } +} + +void Field::RungeKutta1( Zone * zone, int istage ) +{ + this->RungeKutta3Stage0( zone ); +} + +void Field::RungeKutta3( Zone * zone, int istage ) +{ + if ( istage == 0 ) + { + this->RungeKutta3Stage0( zone ); + return; + } + + if ( istage == 1 ) + { + this->RungeKutta3Stage1( zone ); + return; + } + + if ( istage == 2 ) + { + this->RungeKutta3Stage2( zone ); + return; + } +} + +void Field::RungeKutta3Stage0( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage1( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = 0.75 * un[ i ] + 0.25 * u[ i ] + 0.25 * dt * res[ i ]; + } + } +} + +void Field::RungeKutta3Stage2( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + + double c1 = 1.0 / 3.0; + double c2 = 2.0 / 3.0; + double c3 = 2.0 / 3.0; + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & un = this->un.vec( m ); + Vec1d & res = this->res.vec( m ); + + for ( int i = 0; i < this->nx; ++ i ) + { + u[ i ] = c1 * un[ i ] + c2 * u[ i ] + c3 * dt * res[ i ]; + } + } +} + +void Field::PhysicalBoundary( Zone * zone ) +{ + int nbccos = zone->bccos.size(); + for ( int ibcco = 0; ibcco < nbccos; ++ ibcco ) + { + ZoneBc * zonebc = zone->bccos[ ibcco ]; + Region region; + region.SetRegion( zonebc->pnts ); + Boundary( region, zonebc->bcType ); + } +} + +void Field::InterfaceBoundary( Zone * zone ) +{ + int nbc1to1s = zone->bc1to1s.size(); + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + Region region; + region.SetRegion( bc1to1->pnts ); + this->InterfaceBc( region ); + } +} + +void Field::Boundary( Region ®ion, int bcType ) +{ + if ( bcType == BCInflow ) + { + this->InflowBc( region ); + } + else if ( bcType == BCOutflow ) + { + this->OutflowBc( region ); + } + else if ( bcType == BCExtrapolate ) + { + this->ExtrapolateBc( region ); + } + else if ( bcType == BCDirichlet ) + { + this->DirichletBc( region ); + } +} + +void Field::DirichletBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::InflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib - idir; + + int ig1 = ib + idir; + double ub = 0.0; + double uin = u[ in ]; + + if ( Global::ifinite_volume == 0 ) + { + u[ ib ] = ub; + } + + u[ ig1 ] = 2.0 * ub - 1.0 * uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = 3.0 * ub - 2.0 * uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = 4.0 * ub - 3.0 * uin; + } + } + } +} + +void Field::OutflowBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + Vec1d & u = this->u.vec(); + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::ExtrapolateBc( Region ®ion ) +{ + int index_dim = region.start.size(); + if ( index_dim != 1 ) return; + int st = region.start[ 0 ]; + int ed = region.end[ 0 ]; + + Vec1d & u = this->u.vec(); + + for ( int i = st; i <= ed; ++ i ) + { + int idir = 1; + int ib = i - 1; //index from 0 + if ( i == 1 ) + { + idir = -1; + } + else + { + ib -= Global::ifinite_volume; + } + int in = ib; + + int ig1 = ib + idir; + double uin = u[ in ]; + + u[ ig1 ] = uin; + + if ( Global::nghost >= 2 ) + { + int ig2 = ig1 + idir; + u[ ig2 ] = uin; + if ( Global::nghost >= 3 ) + { + int ig3 = ig2 + idir; + u[ ig3 ] = uin; + } + } + } +} + +void Field::InterfaceBc( Region & region ) +{ + //int index_dim = region.start.size(); + //if ( index_dim != 1 ) return; + //int st = region.start[ 0 ]; + //int ed = region.end[ 0 ]; + //for ( int i = st; i <= ed; ++ i ) + //{ + // int ib = i - 1; //index from 0 + + // double value = 0.25 * ( 2 * this->u[ ib ] + this->u[ ib + 1 ] + this->u[ ib - 1 ] ); + // this->u[ ib ] = value; + //} +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Field.h b/example/1d-linear-convection/weno3/cpp/01/Field.h new file mode 100644 index 00000000..ed1b3773 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Field.h @@ -0,0 +1,54 @@ +#pragma once +#include +#include +#include "Vec1d.h" + +class Zone; +class Grid; +class Region; + +class Field +{ +public: + Field() {} + virtual ~Field() {}; +public: + virtual void Init( std::fstream & file, Grid * grid ) {} + virtual void InitFieldCommon( Grid * grid ) {} + virtual void InitFieldAsRestart( Grid * grid ) {} + virtual void ReadFlowField( std::fstream & file, Grid * grid ) {} + virtual void UpdateOldField() {} + virtual void FTCS( Zone * zone ) {} + virtual void CrankNicolsonSeries( Zone * zone ); + virtual void CN( Zone * zone ) {}; + virtual void ICP( Zone * zone ) {} + virtual void DumpField( Grid * grid ) {} + virtual void PostProcess( Grid * grid ) {} + virtual void Rhs( Vec1d & u, Vec1d & r ) {}; + virtual void Rhs( VecWrap & u, VecWrap & r ) {}; +public: + void RungeKutta( Zone * zone, int nStage, int istage ); + void RungeKutta1( Zone * zone, int istage ); + void RungeKutta3( Zone * zone, int istage ); + void RungeKutta3Stage0( Zone * zone ); + void RungeKutta3Stage1( Zone * zone ); + void RungeKutta3Stage2( Zone * zone ); +public: + void PhysicalBoundary( Zone * zone ); + void InterfaceBoundary( Zone * zone ); + virtual void Boundary( Region & region, int bcType ); + virtual void InflowBc( Region & region ); + virtual void OutflowBc( Region & region ); + virtual void DirichletBc( Region & region ); + virtual void ExtrapolateBc( Region & region ); + virtual void InterfaceBc( Region & region ); +public: + Grid * grid; + VecWrap u, un; + VecWrap res; + int nequ = 1; + int ni ,nic; //nnode, ncell; + int nx; + double dt; +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/Global.cpp b/example/1d-linear-convection/weno3/cpp/01/Global.cpp new file mode 100644 index 00000000..3f560f56 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Global.cpp @@ -0,0 +1,461 @@ +#include "Global.h" +#include "Grid.h" +#include "ZoneState.h" +#include "Parallel.h" +#include + +std::vector Global::grids; +std::vector Global::fields; + +Scheme Global::scheme; +GoverningEquation Global::governing_equation; +int Global::istart = 0; +int Global::iviscous = 0; +int Global::iconservation = 1; +int Global::nsave = -1; +int Global::idump_initial_field = -1; +int Global::ifinite_volume = 1; +double Global::total_time = 0.0; +double Global::dt = 0.1; +int Global::nt = -1; +int Global::iter = -1; +int Global::iter_start = 0; +int Global::cell_dim = -1; +int Global::phys_dim = -1; +int Global::nghost = -1; +int Global::nequ = -1; +std::string Global::file_string=""; + +std::vector Global::zones; +std::vector Global::interfaces; + +std::map Global::faceMap; +std::map Global::facePairMap; +std::vector Global::facePairList; +std::vector Global::mpi_facePairList; + +std::vector> Global::donor_zone_sets; +std::vector> Global::donor_zones; + +InterfaceTopo Global::interfaceTopo; + +void PrintPidHeader() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; +} + +void Scheme::read( const json & j ) +{ + this->set_inviscid_scheme( j[ "inviscid" ] ); + this->set_reconstruction_scheme( j[ "reconstruction" ] ); + this->set_viscous_scheme( j[ "viscous" ] ); + this->set_time_scheme( j[ "time" ] ); +} + +void Scheme::set_inviscid_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "ftcs" ) + { + this->inviscid = to_int( BasicScheme::CENTER ); + } + else if ( name == "hllc" ) + { + this->inviscid = to_int( BasicScheme::HLLC ); + } + else if ( name == "lax" ) + { + this->inviscid = to_int( BasicScheme::LAX ); + } + else if ( name == "roe" ) + { + this->inviscid = to_int( BasicScheme::Roe ); + } + else if ( name == "rusanov" ) + { + this->inviscid = to_int( BasicScheme::Rusanov ); + } + else if ( name == "upwind1" ) + { + this->inviscid = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->inviscid = to_int( BasicScheme::UpWind2 ); + } + else if ( name == "weno5" ) + { + this->inviscid = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->inviscid = to_int( BasicScheme::CRWENO ); + } + else + { + this->inviscid = to_int( BasicScheme::WENO ); + } +} + +void Scheme::set_reconstruction_scheme( const std::string & name ) +{ + if ( name == "weno5" ) + { + this->reconstruction = to_int( BasicScheme::WENO ); + } + else if ( name == "crweno5" ) + { + this->reconstruction = to_int( BasicScheme::CRWENO ); + } + else if ( name == "upwind1" ) + { + this->reconstruction = to_int( BasicScheme::UpWind1 ); + } + else if ( name == "upwind2" ) + { + this->reconstruction = to_int( BasicScheme::UpWind2 ); + } +} + +void Scheme::set_viscous_scheme( const std::string & name ) +{ + if ( name == "center" ) + { + this->viscous = to_int( BasicScheme::CENTER ); + } + else + { + this->viscous = to_int( BasicScheme::CENTER ); + } +} + +void Scheme::set_time_scheme( const std::string & name ) +{ + if ( name == "cn" ) + { + this->time_scheme = to_int( BasicScheme::CN ); + } + else if ( name == "icp" ) + { + this->time_scheme = to_int( BasicScheme::ICP ); + } + else if ( name == "rk1" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else if ( name == "rk2" ) + { + this->time_scheme = to_int( BasicScheme::RK2 ); + } + else if ( name == "rk3" ) + { + this->time_scheme = to_int( BasicScheme::RK3 ); + } + else if ( name == "ftcs" ) + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } + else + { + this->time_scheme = to_int( BasicScheme::RK1 ); + } +} + + +bool Face::operator < ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return this->zone < rhs.zone; + } + + if ( this->i != rhs.i ) + { + return this->i < rhs.i; + } + + if ( this->j != rhs.j ) + { + return this->j < rhs.j; + } + + return this->k < rhs.k; +} + +bool Face::operator == ( const Face & rhs ) const +{ + if ( this->zone != rhs.zone ) + { + return false; + } + + if ( this->i != rhs.i ) + { + return false; + } + + if ( this->j != rhs.j ) + { + return false; + } + + return this->k == rhs.k; +} + +void Face::Print() +{ + std::cout << "(" << this->zone << "," << this->i << ")"; +} + +void FacePair::AddPair( const Face & face1, const Face & face2 ) +{ + if ( face1 < face2 ) + { + this->left = face1; + this->right = face2; + } + else + { + this->left = face2; + this->right = face1; + } +} + +bool FacePair::operator < ( const FacePair & rhs ) const +{ + if ( this->left == rhs.left || this->left == rhs.right ) + { + return false; + } + + return this->left < rhs.left; +} + +void FacePair::Print() +{ + this->left.Print(); + std::cout << " "; + this->right.Print(); + std::cout << "\n"; +} + +void InterfaceTopo::InitNeighborInfo() +{ + this->linkmap.resize( ZoneState::nZones ); + + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + if ( ! ZoneState::IsValid( iZone ) ) continue; + + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector & t = this->linkmap[ iZone ]; + t = interface->neighbor_donor_zones; + } +} + +void InterfaceTopo::SwapNeighborInfo() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int nNeighbor = donor_zones.size(); + + HXBcastData( &nNeighbor, 1, pid ); + + donor_zones.resize( nNeighbor ); + + HXBcastData( donor_zones.data(), donor_zones.size(), pid ); + } + + this->SwapNeighborDonorfaces(); +} + +void InterfaceTopo::SwapNeighborDonorfaces() +{ + int gl = 0; + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + + std::vector & donor_zones = this->linkmap[ iZone ]; + int ndonor_zones = donor_zones.size(); + + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = donor_zones[ iNei ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nInterFaces = 0; + std::vector donorfaces; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Interface * interface = Global::interfaces[ local_zoneid ]; + + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + + std::vector & neighbor_donorface = neighbor_donorfaces[ iNei ]; + + nInterFaces = neighbor_donorface.size(); + + donorfaces = neighbor_donorface; + } + + HXSendRecvData( &nInterFaces, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid && send_pid != recv_pid ) + { + donorfaces.resize( nInterFaces ); + } + + HXSendRecvData( donorfaces.data(), donorfaces.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * interface_recv = Global::interfaces[ local_donor_zoneid ]; + interface_recv->SendGeom( iZone, donorfaces ); + } + } + } +} + + +void Interface::CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ) +{ + int ist = start[ 0 ]; + int ied = end[ 0 ]; + int dim = start.size(); + std::vector index1( dim ); + std::vector index2( dim ); + + int icount = this->zoneList.size(); + for ( int i = ist; i <= ied; ++ i ) + { + int faceid = icount; + this->zoneList.push_back( donor_zoneid ); + this->local_faceids.push_back( faceid ); + index1[ 0 ] = i; + transform->MapIndex( index1, index2 ); + Face face; + face.zone = zoneid; + face.i = i; + + int i_donor = index2[ 0 ]; + + Face face_donor; + face_donor.zone = donor_zoneid; + face_donor.i = i_donor; + + FacePair facePair; + facePair.AddPair( face, face_donor ); + + Global::facePairList.push_back( facePair ); + int nSize = Global::facePairList.size(); + this->proc_global_faceids.push_back( nSize - 1 ); + + if ( i == 1 ) + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic - ig ); + ijk_donors.push_back( ic + iig ); + } + } + else + { + //ig = 0: interface value + //ig=1,2,... ghost cell value + int ic = i - Global::ifinite_volume; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + ijk_ghosts.push_back( ic + ig ); + ijk_donors.push_back( ic - iig ); + } + } + + icount ++; + } +} + +void Interface::SendGeom( int zone, std::vector & donorfaces ) +{ + Interface * interface = this; + + std::vector & send_to_zones = interface->send_to_zones; + + send_to_zones.push_back( zone ); + interface->donorfaces_for_send.push_back( donorfaces ); + + int nface = donorfaces.size(); + std::vector sub_donorijk; + int index_dim = 1; + int ngsize = ( Global::nghost + 1 - Global::ifinite_volume ); + for ( int i = 0; i < nface; ++ i ) + { + int global_faceid = donorfaces[ i ]; + int local_faceid = interface->global_local_face_map[ global_faceid ]; + int ijkpos = index_dim * local_faceid * ngsize; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int i_donor_cell = interface->ijk_donors[ ijkpos + iig ]; + sub_donorijk.push_back( i_donor_cell ); + } + int kkk = 1; + } + + interface->donorijk_for_send.push_back( sub_donorijk ); + + int ndata = sub_donorijk.size() * Global::nequ; + + std::vector sub_donordata( ndata ); + interface->donordata_for_send.push_back( sub_donordata ); +} + +void Global::InsertFaceMap( const Face & face ) +{ + std::map::iterator iter; + iter = Global::faceMap.find( face ); + if ( iter == Global::faceMap.end() ) + { + int faceid = Global::faceMap.size(); + Global::faceMap.insert( std::make_pair( face, faceid ) ); + } +} + +int Global::InsertFacePairMap( const FacePair & facePair ) +{ + std::map::iterator iter; + iter = Global::facePairMap.find( facePair ); + if ( iter == Global::facePairMap.end() ) + { + int facePairId = Global::facePairMap.size(); + Global::facePairMap.insert( std::make_pair( facePair, facePairId ) ); + return facePairId; + } + return iter->second; +} + +void Global::AddFacePairList( std::vector & a, std::vector & b ) +{ + for ( int i = 0; i < b.size(); ++ i ) + { + a.push_back( b[ i ] ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Global.h b/example/1d-linear-convection/weno3/cpp/01/Global.h new file mode 100644 index 00000000..f89bc3c0 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Global.h @@ -0,0 +1,179 @@ +#pragma once +#include "Vec1d.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +class Face +{ +public: + int zone = 0; + int i = 0; + int j = 1; + int k = 1; +public: + bool operator < ( const Face & rhs ) const; + bool operator == ( const Face & rhs ) const; +public: + void Print(); +}; + +class FacePair +{ +public: + Face left; + Face right; +public: + bool operator < ( const FacePair & rhs ) const; + void AddPair( const Face &face1, const Face &face2); +public: + void Print(); +}; + +class Transform; + +class InterfaceTopo +{ +public: + std::vector> linkmap; +public: + void InitNeighborInfo(); + void SwapNeighborInfo(); + void SwapNeighborDonorfaces(); +}; + + +class Interface +{ +public: + int zoneid; + std::vector zoneList; + std::vector global_faceids; + std::vector mpi_global_faceids; + std::vector proc_global_faceids; + std::vector local_faceids; + std::vector ijk_ghosts; + std::vector ijk_donors; + std::vector data_recv; + std::vector data_send; + std::unordered_map global_local_face_map; +public: + std::vector neighbor_donor_zones; + std::vector> neighbor_donorfaces; + std::vector> sub_local_faceids; + std::vector send_to_zones; + std::vector> donorfaces_for_send; + std::vector> donorijk_for_send; + std::vector> donordata_for_send; +public: + void CalcInterface( Transform * transform, std::vector & start, std::vector & end, int donor_zoneid ); + void SendGeom( int zone, std::vector & donorfaces ); +}; + +class Field; +class InterFaceZone; +class Zone; +class Grid; + +enum class BasicScheme +{ + FTCS = 0, + CENTER, //Central Space + CN, //CrankCNicolson + ICP, //Implicit Compact Pade (ICP) Scheme + WENO, //Weighted Essentially Non-oscillatory + CRWENO, //Compact Reconstruction WENO-5 Scheme + HLLC,//HLLC scheme + LAX, //Lax-Friedrichs flux splitting + Roe, // + Rusanov, // + UpWind1, + UpWind2, + RungeKutta, + RK1, + RK2, + RK3 +}; + +enum class GoverningEquation +{ + Heat = 0, + LinearConvection, + Burgers, + Euler +}; + +template +int to_int( const T & t ) +{ + return static_cast( t ); +} + +template +BasicScheme to_BasicScheme( const T & t ) +{ + return static_cast( t ); +} + +class Scheme +{ +public: + int inviscid; + int viscous; + int time_scheme; + int reconstruction; +public: + void read( const json & j ); + void set_inviscid_scheme( const std::string & name ); + void set_reconstruction_scheme( const std::string & name ); + void set_viscous_scheme( const std::string & name ); + void set_time_scheme( const std::string & name ); +}; + +class Global +{ +public: + static std::vector grids; + static std::vector fields; +public: + static std::vector zones; + static std::vector interfaces; +public: + static std::map faceMap; + static std::map facePairMap; + static std::vector facePairList; + static std::vector mpi_facePairList; + static std::vector> donor_zone_sets; + static std::vector> donor_zones; + static InterfaceTopo interfaceTopo; +public: + static Scheme scheme; + static GoverningEquation governing_equation; + static double total_time; + static double dt; + static int istart; + static int iconservation; + static int iviscous; + static int nsave; + static int idump_initial_field; + static int ifinite_volume; + static int nt; + static int iter_start; + static int iter; + static int cell_dim; + static int phys_dim; + static int nghost; + static int nequ; + static std::string file_string; +public: + static void InsertFaceMap( const Face & face ); + static int InsertFacePairMap( const FacePair & facePair ); + static void AddFacePairList( std::vector & a, std::vector & b ); +}; + +void PrintPidHeader(); diff --git a/example/1d-linear-convection/weno3/cpp/01/Grid.cpp b/example/1d-linear-convection/weno3/cpp/01/Grid.cpp new file mode 100644 index 00000000..e4f62efb --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Grid.cpp @@ -0,0 +1,290 @@ +#include "Grid.h" +#include "Vec1d.h" +#include +#include + +void Grid::Allocate( int nNodes ) +{ + this->ni = nNodes; + this->nic = nNodes - 1; //ncells + this->x.Allocate( 0, nNodes - 1 ); + this->xcc.Allocate( 0, this->nic - 1 ); //cell center; +} + +void Grid::CalcMetrics() +{ + for ( int i = 0; i < nic; ++ i ) + { + xcc[ i ] = 0.5 * ( x[ i ] + x[ i + 1 ] ); + } +} + +Region::Region() +{ +} + +Region::~Region() +{ +} + +Region & Region::operator = ( const Region & rhs ) +{ + if ( this == & rhs ) return * this; + + this->start = rhs.start; + this->end = rhs.end; + + return * this; +} + +void Region::SetRegion( std::vector & pnts ) +{ + int index_dim = pnts.size() / 2; + this->start.resize( index_dim ); + this->end.resize( index_dim ); + for ( int m = 0; m < index_dim; ++ m ) + { + this->start[ m ] = pnts[ m ]; + this->end[ m ] = pnts[ index_dim + m ]; + } +} + +void Region::Print() +{ + int nSize = this->start.size(); + std::cout << "start:("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->start[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; + std::cout << "end :("; + for ( int m = 0; m < nSize; ++ m ) + { + std::cout << this->end[ m ]; + if ( m != nSize - 1 ) + { + std::cout << ","; + } + } + std::cout << ")\n"; +} + +Coor::Coor() +{ + ; +} + +Coor::~Coor() +{ +} + +void Coor::DumpCoor() +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + //std::cout << coord[i] << " "; + std::cout << xd[ i ] << " "; + if ( ( i + 1 ) % 5 == 0 ) std::cout << "\n"; + } + std::cout << "\n"; +} + +void Coor::DumpCoorX( Vec1d &x ) +{ + double * xd = reinterpret_cast( const_cast( coord.data() ) ); + for ( int i = 0; i < this->nNodes; ++ i ) + { + x[ i ] = xd[ i ]; + } +} + +ZoneBc::ZoneBc() +{ + ; +} + +ZoneBc::~ZoneBc() +{ +} + +ZoneBc1To1::ZoneBc1To1() +{ + ; +} + +ZoneBc1To1::~ZoneBc1To1() +{ +} + +Zone::Zone() +{ + ; +} + +Zone::~Zone() +{ + for ( int i = 0; i < bccos.size(); ++ i ) + { + delete bccos[ i ]; + } + + for ( int i = 0; i < coors.size(); ++ i ) + { + delete coors[ i ]; + } +} + +int Trans::M[ 3 ][ 3 ]; +std::vector Trans::transform; + +int Trans::sgn( int x ) +{ + if ( x >= 0 ) + { + return 1; + } + else + { + return -1; + } +} + +int Trans::del( int x, int y ) +{ + if ( std::abs( x ) == std::abs( y ) ) + { + return 1; + } + return 0; +} + +void Trans::ZeroMatrix() +{ + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + Trans::M[ i ][ j ] = 0; + } + } +} + +void Trans::CalcTransformMatrix() +{ + int dim = Trans::transform.size(); + if ( dim == 1 ) + { + int a = Trans::transform[ 0 ]; + int sgna = Trans::sgn( a ); + int a1 = Trans::del( a, 1 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + } + else if ( dim == 2 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + } + else if ( dim == 3 ) + { + int a = Trans::transform[ 0 ]; + int b = Trans::transform[ 1 ]; + int c = Trans::transform[ 2 ]; + int sgna = Trans::sgn( a ); + int sgnb = Trans::sgn( b ); + int sgnc = Trans::sgn( c ); + int a1 = Trans::del( a, 1 ); + int a2 = Trans::del( a, 2 ); + int a3 = Trans::del( a, 3 ); + int b1 = Trans::del( b, 1 ); + int b2 = Trans::del( b, 2 ); + int b3 = Trans::del( b, 3 ); + int c1 = Trans::del( c, 1 ); + int c2 = Trans::del( c, 2 ); + int c3 = Trans::del( c, 3 ); + Trans::M[ 0 ][ 0 ] = sgna * a1; + Trans::M[ 1 ][ 0 ] = sgna * a2; + Trans::M[ 2 ][ 0 ] = sgna * a3; + Trans::M[ 0 ][ 1 ] = sgnb * b1; + Trans::M[ 1 ][ 1 ] = sgnb * b2; + Trans::M[ 2 ][ 1 ] = sgnb * b3; + Trans::M[ 0 ][ 2 ] = sgnc * c1; + Trans::M[ 1 ][ 2 ] = sgnc * c2; + Trans::M[ 2 ][ 2 ] = sgnc * c3; + } +} + +Transform::Transform() +{ + //int dim = Dim::dim; + int dim = 1; + this->diff.resize( dim ); + this->mul.resize( dim ); +} + +Transform::~Transform() +{ + ; +} + +void Transform::Init() +{ + Trans::ZeroMatrix(); + Trans::transform = this->transform; + Trans::CalcTransformMatrix(); + + int dim = 3; + for ( int j = 0; j < dim; ++ j ) + { + for ( int i = 0; i < dim; ++ i ) + { + this->Mt[ i ][ j ] = Trans::M[ i ][ j ]; + } + } +} + +void Transform::MapIndex( std::vector & index1, std::vector & index2 ) +{ + int dim = index1.size(); + for ( int m = 0; m < dim; ++ m ) + { + this->diff[ m ] = index1[ m ] - this->begin1[ m ]; + } + + this->Multiply( diff, this->mul ); + + for ( int m = 0; m < dim; ++ m ) + { + index2[ m ] = this->mul[ m ] + this->begin2[ m ]; + } + +} + +void Transform::Multiply( std::vector & a, std::vector & b ) +{ + int dim = a.size(); + for ( int i = 0; i < dim; ++ i ) + { + b[ i ] = 0; + for ( int j = 0; j < dim; ++ j ) + { + b[ i ] += this->Mt[ i ][ j ] * a[ j ]; + } + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Grid.h b/example/1d-linear-convection/weno3/cpp/01/Grid.h new file mode 100644 index 00000000..b7f81e8d --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Grid.h @@ -0,0 +1,115 @@ +#pragma once +#include "Vec1d.h" +#include +#include + +class Vec1d; + +class Grid +{ +public: + int zoneIndex; + int ni, nic; //nnode, ncell; + Vec1d x; + Vec1d xcc; +public: + void Allocate( int nNodes ); + void CalcMetrics(); +}; + +class Region +{ +public: + Region(); + ~Region(); +public: + std::vector start; + std::vector end; +public: + Region & operator = ( const Region & rhs ); + void SetRegion( std::vector & pnts ); + void Print(); +}; + +class Coor +{ +public: + Coor(); + ~Coor(); +public: + std::string coorname; + int nNodes; + std::vector nijk; + std::vector coord; +public: + void DumpCoor(); + void DumpCoorX( Vec1d & x ); +}; + +class ZoneBc +{ +public: + ZoneBc(); + ~ZoneBc(); +public: + int bcType; + int zoneid; + std::vector pnts; +}; + +class ZoneBc1To1 +{ +public: + ZoneBc1To1(); + ~ZoneBc1To1(); +public: + int zoneid; + int donor_zoneid; + std::vector pnts; + std::vector donor_pnts; + std::vector transform; +}; + + +class Zone +{ +public: + Zone(); + ~Zone(); +public: + int zoneIndex; + std::vector nijk; + std::vector bccos; + std::vector bc1to1s; + std::vector coors; +}; + +class Trans +{ +public: + static int M[ 3 ][ 3 ]; + static std::vector transform; + static int sgn( int x ); + static int del( int x, int y ); + static void ZeroMatrix(); + static void CalcTransformMatrix(); +}; + +class Transform +{ +public: + Transform(); + ~Transform(); +private: + std::vector diff; + std::vector mul; +public: + int Mt[ 3 ][ 3 ]; + std::vector begin1; + std::vector begin2; + std::vector transform; +public: + void Init(); + void MapIndex( std::vector & index1, std::vector & index2 ); + void Multiply( std::vector & a, std::vector & b ); +}; diff --git a/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp b/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp new file mode 100644 index 00000000..a160d532 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/HeatField.cpp @@ -0,0 +1,228 @@ +#include "HeatField.h" +#include "hxmath.h" +#include "Grid.h" +#include "Global.h" +#include "cgnslib.h" +#include +#include + +void HeatField::Init( std::fstream & file, Grid * grid ) +{ + this->ni = grid->ni; + this->nic = grid->nic; + grid->CalcMetrics(); + if ( Global::ifinite_volume == 1 ) + { + this->nx = this->nic; + } + else + { + // finite difference + this->nx = this->ni; + } + std::cout << "ni = " << ni << "\n"; + + Vec1d & x = grid->x; + this->dx = std::abs( x[ 1 ] - x[ 0 ] ); + this->dt = dx / 10.0; + this->nt = std::round( Global::total_time / dt ); + + std::cout << "this->dt = " << this->dt << "\n"; + std::cout << "this->nt = " << this->nt << "\n"; + std::cout << "this->ni = " << this->ni << "\n"; + std::cout << "nt * dt = " << nt * dt << "\n"; + + Global::nt = nt; + + this->alpha = 1 / ( std::numbers::pi * std::numbers::pi ); + this->beta = this->alpha * dt / ( dx * dx ); + + int ist = 0 - Global::nghost; + int ied = this->ni - 1 + Global::nghost; + + this->u.Allocate( this->nequ, ist, ied ); + this->un.Allocate( this->nequ, ist, ied ); + this->res.Allocate( this->nequ, 0, this->nx ); //N+1 + + Vec1d &u = this->u.vec(); + + if ( Global::ifinite_volume == 0 ) + { + //node + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = - std::sin( std::numbers::pi * x[ i ] ); //initial condition @ t=0 + } + } + else + { + //cell center + Vec1d & xcc = grid->xcc; + for ( int i = 0; i < nic; ++ i ) + { + u[ i ] = - std::sin( 2.0 * std::numbers::pi * xcc[ i ] ); //initial condition @ t=0 + } + + } + int kkk = 1; +} + +void HeatField::FTCS( Zone * zone ) +{ + this->Rhs( this->u, this->res ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = u[ i ] + dt * res[ i ]; + } + } +} + +void HeatField::CN( Zone * zone ) +{ + double rr = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + + std::vector a( ni ); + std::vector b( ni ); + std::vector c( ni ); + std::vector d( ni ); + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = - rr; + b[ i ] = 1.0 + 2.0 * rr; + c[ i ] = - rr; + } + + for ( int i = 0; i < ni; ++ i ) + { + d[ i ] = rr * u[ i - 1 ] + ( 1.0 - 2.0 * rr ) * u[ i ] + rr * u[ i + 1 ]; + } + + double uleft = u[ -1 ] + 2 * rr * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + 2 * rr * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::ICP( Zone * zone ) +{ + double beta = 0.5 * this->alpha * dt / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + std::vector a( ni );//0:ni-1 + std::vector b( ni );//0:ni-1 + std::vector c( ni );//0:ni-1 + std::vector d( ni );//0:ni-1 + + for ( int i = 0; i < ni; ++ i ) + { + a[ i ] = 1.0 / 12.0 - beta; + b[ i ] = 10.0 / 12.0 + 2.0 * beta; + c[ i ] = 1.0 / 12.0 - beta; + + double aa = 1.0 / 12.0 + beta; + double bb = 10.0 / 12.0 - 2.0 * beta; + double cc = 1.0 / 12.0 + beta; + d[ i ] = aa * u[ i - 1 ] + bb * u[ i ] + cc * u[ i + 1 ]; + } + + + //double uleft = u[ -1 ] + 2 * beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + //double uright = u[ ni ] + 2 * beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + //double uleft = u[ -1 ]; + //double uright = u[ ni ]; + + double uleft = u[ -1 ] + beta * ( u[ - 1 ] - 2 * u[ 0 ] + u[ 1 ] ); + double uright = u[ ni ] + beta * ( u[ ni - 2 ] - 2 * u[ ni - 1 ] + u[ ni ] ); + + d[ 0 ] -= a[ 0 ] * uleft; + d[ ni - 1 ] -= c[ ni - 1 ] * uright; + + //d[ 0 ] -= a[ 0 ] * u[ -1 ]; + //d[ ni - 1 ] -= c[ ni - 1 ] * u[ ni ]; + + + std::vector values( d.size() ); + + thomas_algorithm( a, b, c, d, values ); + + for ( int i = 0; i < ni; ++ i ) + { + u[ i ] = values[ i ]; + } + } +} + +void HeatField::UpdateOldField() +{ + this->un = this->u; +} + +void HeatField::InviscidResidual( VecWrap & u, VecWrap & res ) +{ + ; +} + +void HeatField::ViscousResidual( VecWrap & u, VecWrap & res ) +{ + double coef = this->alpha / ( dx * dx ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Vec1d & res = this->res.vec( m ); + for ( int i = 0; i < ni; ++ i ) + { + res[ i ] += coef * ( u[ i + 1 ] - 2.0 * u[ i ] + u[ i - 1 ] ); + } + } +} +void HeatField::Rhs( VecWrap & u, VecWrap & res ) +{ + res = 0; + InviscidResidual( u, res ); + ViscousResidual( u, res ); +} + +void HeatField::DumpField( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::PostProcess( Grid * grid ) +{ + this->DumpField( grid->x, u ); +} + +void HeatField::DumpField( Vec1d & x, VecWrap & u ) +{ + for ( int i = 0; i < x.size(); ++ i ) + { + Global::file_string += std::format( "{:.16f}", x[ i ] ); + for ( int m = 0; m < nequ; ++ m ) + { + Vec1d & u = this->u.vec( m ); + Global::file_string += std::format( " {:.16f}", u[ i ] ); + } + Global::file_string += std::format( "\n" ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/HeatField.h b/example/1d-linear-convection/weno3/cpp/01/HeatField.h new file mode 100644 index 00000000..4fcb3e37 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/HeatField.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "Vec1d.h" +#include "Field.h" + +class HeatField : public Field +{ +public: + int nt; + double dx; + double alpha, beta; +public: + void Init( std::fstream & file, Grid * grid ); +public: + void FTCS( Zone * zone ); + void CN( Zone * zone ); + void ICP( Zone * zone ); +public: + void Rhs( VecWrap & u, VecWrap & res ); + void InviscidResidual( VecWrap & u, VecWrap & res ); + void ViscousResidual( VecWrap & u, VecWrap & res ); + void UpdateOldField(); +public: + void DumpField( Grid * grid ); + void PostProcess( Grid * grid ); + void DumpField( Vec1d & x, VecWrap & u ); +}; + diff --git a/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py b/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py new file mode 100644 index 00000000..55f0fe08 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Linear Convection_plot.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +def set_fuction(nx, u, x, ct) : + for i in range(nx): + xm = x[i] + if 0.5 <= xm - ct <= 1: + u[i] = 2 + else: + u[i] = 1 + +filename = 'field_final.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTBS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +utheory= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +c = 1 +total_t = 0.625 +# theory solution +set_fuction(ni, utheory, x, c * total_t ) + +plt.figure("OneFLOW-CFD Solver") +plt.plot(x, utheory, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() +plt.show(); + diff --git a/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp b/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp new file mode 100644 index 00000000..08ccd453 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/LogFile.cpp @@ -0,0 +1,138 @@ +#include "LogFile.h" +#include "Parallel.h" +#include +#include + +#ifdef _WINDOWS +#include +#include +#include +#else +#include +#include +#endif + +LogFile logFile; + +class OStream : public std::ostringstream +{ +public: + OStream() {} + ~OStream() {} +public: + void ClearAll() + { + this->clear(); + this->str(""); + } +}; + +OStream StrIO; +std::string GetPrjDirName( const std::string & fileName ); +bool DirExist( const std::string & dirName ); +void MakeDir( const std::string & dirName ); + +std::string GetPrjDirName( const std::string & fileName ) +{ + size_t pos = fileName.find_last_of("\\/"); + if ( std::string::npos == pos ) + { + return ""; + } + else + { + return fileName.substr( 0, pos ); + } +} + +bool DirExist( const std::string & dirName ) +{ +#ifdef _WINDOWS + bool flag = ( _access( dirName.c_str(), 0 ) == 0 ); + return flag; +#else + bool flag = ( access( dirName.c_str(), 0 ) == 0 ); + return flag; +#endif +} + +void MakeDir( const std::string & dirName ) +{ + int flag; +#ifdef _WINDOWS + flag = _mkdir( dirName.c_str() ); +#else + flag = mkdir( dirName.c_str(), S_IRWXU ); +#endif + if ( flag == 0 ) + { + std::cout << dirName << " directory has been created successfully !\n"; + } +} + +void CreateDirIfNeeded( std::string & prjFileName ) +{ + std::string prj_dir = GetPrjDirName( prjFileName ); + + if ( ! DirExist( prj_dir ) ) + { + MakeDir( prj_dir ); + } +} + + +void OpenLogFile( int logFileIndex, std::fstream & file ) +{ + static int ifReWrite = 0; + + StrIO.ClearAll(); + StrIO << "log/log" << logFileIndex << ".log"; + std::string fileName = StrIO.str(); + + std::ios_base::openmode openMode; + + if ( ifReWrite == 0 ) + { + CreateDirIfNeeded( fileName ); + + openMode = std::ios_base::out | std::ios_base::trunc; + + ifReWrite = 1; + } + else + { + openMode = std::ios_base::out | std::ios_base::app; + } + + file.open( fileName.c_str(), openMode ); + if ( ! file ) + { + std::cout << "could not open " << fileName << std::endl; + exit( 0 ); + } +} + +void CloseLogFile( std::fstream & file ) +{ + file.close(); + file.clear(); +} + +LogFile::LogFile() +{ +} + +LogFile::~LogFile() +{ +} + +void LogFile::Open() +{ + int pid = Parallel::pid; + OpenLogFile( pid, this->my_fstream ); +} + +void LogFile::Close() +{ + CloseLogFile( this->my_fstream ); +} diff --git a/example/1d-linear-convection/weno3/cpp/01/LogFile.h b/example/1d-linear-convection/weno3/cpp/01/LogFile.h new file mode 100644 index 00000000..00e775ab --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/LogFile.h @@ -0,0 +1,27 @@ +#pragma once +#include + +void OpenLogFile( int logFileIndex, std::fstream & file ); +void CloseLogFile( std::fstream & file ); +class LogFile; +extern LogFile logFile; + +class LogFile +{ +public: + LogFile(); + ~LogFile(); + std::fstream my_fstream; +public: + void Open(); + void Close(); +}; + +template< typename T > +LogFile & operator << ( LogFile & f, const T & value ) +{ + f.Open(); + f.my_fstream << value; + f.Close(); + return f; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py b/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py new file mode 100644 index 00000000..752ec7f3 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/MyCRWenoPlot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +ns = 10 +if nvar >= 2: + ms = sys.argv[1] + print('ms=',ms) + ns = int(ms) + +print('ns=',ns) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: CRWENO-5 Scheme+Dirichlet BC") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py b/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py new file mode 100644 index 00000000..b44106d1 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/MyWenoPlot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Inviscid Burgers Equation: Non-Conservative Form-WENO-5 Scheme") +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp b/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp new file mode 100644 index 00000000..c0199572 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Parallel.cpp @@ -0,0 +1,100 @@ +#include "Parallel.h" +#include + +int Parallel::pid = 0; +int Parallel::nProc = 1; +int Parallel::serverid = 0; +int Parallel::tag = 0; + +void Parallel::Init() +{ +#ifdef HX_PARALLEL + int argc = 0; + char ** argv = 0; + MPI_Init( &argc, &argv ); + MPI_Comm_rank( MPI_COMM_WORLD, &Parallel::pid ); + MPI_Comm_size( MPI_COMM_WORLD, &Parallel::nProc ); + int len = -1; + char version[ MPI_MAX_LIBRARY_VERSION_STRING ]; + MPI_Get_library_version( version, &len ); + std::cout << "Hello, world! I am " << Parallel::pid << " of " << Parallel::nProc + << "(" << version << ", " << len << ")" << std::endl; +#endif +} + +void Parallel::Finalize() +{ +#ifdef HX_PARALLEL + MPI_Finalize(); +#endif +} + +bool Parallel::IsServer() +{ + return Parallel::pid == Parallel::serverid; +} + +void HXSendChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + MPI_Send( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvChar( void * data, int size, int pid, int tag ) +{ +#ifdef HX_PARALLEL + if ( size <= 0 ) return; + + MPI_Status status; + MPI_Recv( data, size, MPI_CHAR, pid, tag, MPI_COMM_WORLD, & status ); +#endif +} + +void HXSendString( std::string const & str, int recv_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len = str.size(); + MPI_Send( &len, 1, MPI_UNSIGNED, recv_pid, tag, MPI_COMM_WORLD ); + if ( len == 0 ) return; + MPI_Send( str.data(), len, MPI_CHAR, recv_pid, tag, MPI_COMM_WORLD ); +#endif +} + +void HXRecvString( std::string & str, int send_pid, int tag ) +{ +#ifdef HX_PARALLEL + unsigned len; + MPI_Status status; + MPI_Recv( &len, 1, MPI_UNSIGNED, send_pid, tag, MPI_COMM_WORLD, &status ); + if ( len == 0 ) return; + str.resize( len ); + MPI_Recv( str.data(), len, MPI_CHAR, send_pid, tag, MPI_COMM_WORLD, &status ); +#endif +} + +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag ) +{ + if ( send_pid == recv_pid ) return; + if ( Parallel::pid == send_pid ) + { + HXSendString( str, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvString( str, send_pid, tag ); + } +} + +void HXBcastString( std::string & str, int send_pid ) +{ + int nlen = 0; + if ( Parallel::pid == send_pid ) + { + nlen = str.size(); + } + HXBcastData( &nlen, 1, send_pid ); + str.resize( nlen ); + HXBcastData( str.data(), str.size(), send_pid ); +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Parallel.h b/example/1d-linear-convection/weno3/cpp/01/Parallel.h new file mode 100644 index 00000000..41f46dad --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Parallel.h @@ -0,0 +1,85 @@ +#pragma once +#ifdef HX_PARALLEL +#include "mpi.h" +#endif +#include +#include "LogFile.h" + +class Parallel +{ +public: + static int pid; + static int nProc; + static int serverid; + static int tag; +public: + static void Init(); + static void Finalize(); +public: + static bool IsServer(); +}; + +void HXSendChar( void * data, int size, int pid, int tag = 0 ); +void HXRecvChar( void * data, int size, int pid, int tag = 0 ); +void HXSendRecvString( std::string & str, int send_pid, int recv_pid, int tag = 0 ); +void HXSendString( std::string const & str, int recv_pid, int tag = 0 ); +void HXRecvString( std::string & str, int send_pid, int tag = 0 ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag ); + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag ); + +template< typename T > +void HXSendData( T * field, int nElement, int recv_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXSendChar( field, buffer_size, recv_pid, tag ); +} + +template< typename T > +void HXRecvData( T * field, int nElement, int send_pid, int tag = 0 ) +{ + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + HXRecvChar( field, buffer_size, send_pid, tag ); +} + +template< typename T > +void HXSendRecvData( T * field, int nElement, int send_pid, int recv_pid, int tag = 0 ) +{ + if ( send_pid == recv_pid ) return; + + if ( nElement <= 0 ) return; + + int buffer_size = nElement * sizeof( T ); + + if ( Parallel::pid == send_pid ) + { + HXSendChar( field, buffer_size, recv_pid, tag ); + } + else if ( Parallel::pid == recv_pid ) + { + HXRecvChar( field, buffer_size, send_pid, tag ); + } +} + +template< typename T > +void HXBcastData( T * field, int nElement, int send_pid ) +{ + if ( nElement <= 0 ) return; + int buffer_size = nElement * sizeof( T ); +#ifdef HX_PARALLEL + MPI_Bcast( field, buffer_size, MPI_CHAR, send_pid, MPI_COMM_WORLD ); +#endif +} + +void HXBcastString( std::string & str, int send_pid ); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/Post.cpp b/example/1d-linear-convection/weno3/cpp/01/Post.cpp new file mode 100644 index 00000000..b1b1c3d3 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Post.cpp @@ -0,0 +1,38 @@ +#include "Post.h" +#include "Parallel.h" +#include "ZoneState.h" +#include "Global.h" +#include "Field.h" +#include "Grid.h" +#include +#include +#include +#include +#include + +double compute_l2norm( int ni, std::vector & r ) +{ + double rms = 0.0; + for ( int i = 1; i < ni - 1; ++ i ) + { + rms += r[ i ] * r[ i ]; + } + rms = std::sqrt( rms / ( ni - 2 ) ); + return rms; +} + +double compute_max_error( int ni, std::vector & u_error ) +{ + double val_max = -1; + int ipos = -1; + for ( int i = 1; i < ni - 1; ++ i ) + { + if ( val_max < std::abs( u_error[ i ] ) ) + { + ipos = i; + val_max = std::abs( u_error[ i ] ); + } + } + std::cout << " ipos = " << ipos << "\n"; + return val_max; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Post.h b/example/1d-linear-convection/weno3/cpp/01/Post.h new file mode 100644 index 00000000..1ab1fb51 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Post.h @@ -0,0 +1,6 @@ +#pragma once +#include +#include + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); diff --git a/example/1d-linear-convection/weno3/cpp/01/README.txt b/example/1d-linear-convection/weno3/cpp/01/README.txt new file mode 100644 index 00000000..5a4410fb --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/README.txt @@ -0,0 +1,3 @@ +cmake -DCMAKE_TOOLCHAIN_FILE="c:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake" .. + +PS D:\github\OneFLOW\example\1d-heat-equation\ftcs\cpp\multiblock\parallel\8blocks\01\build> mpiexec -n 8 .\Debug\testprj.exe diff --git a/example/1d-linear-convection/weno3/cpp/01/Solver.cpp b/example/1d-linear-convection/weno3/cpp/01/Solver.cpp new file mode 100644 index 00000000..45259b3c --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Solver.cpp @@ -0,0 +1,793 @@ +#include "Solver.h" +#include "Field.h" +#include "HeatField.h" +#include "ConvectionField.h" +#include "BurgersField.h" +#include "EulerField.h" +#include "CgnsUtil.h" +#include "Parallel.h" +#include "Post.h" +#include "Weno.h" +#include "ZoneState.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +using json = nlohmann::json; + +Solver::Solver() +{ +} + +Solver::~Solver() +{ + Parallel::Finalize(); +} + +void Solver::Init() +{ + Parallel::Init(); + + if ( Parallel::IsServer() ) + { + std::ifstream f( "../linearconvection.json" ); + json data = json::parse( f ); + std::cout << "data=" << data.dump( 4 ) << std::endl; + Global::istart = data[ "istart" ]; + if ( Global::istart == 1 ) + { + Read_iter(); + } + + std::string equation = data[ "equation" ]; + if ( equation == "heat" ) + { + Global::governing_equation = GoverningEquation::Heat; + Global::nequ = 1; + } + else if ( equation == "linearconvection" ) + { + Global::governing_equation = GoverningEquation::LinearConvection; + Global::nequ = 1; + } + else if ( equation == "burgers" ) + { + Global::governing_equation = GoverningEquation::Burgers; + Global::nequ = 1; + } + else + { + Global::governing_equation = GoverningEquation::Euler; + Global::nequ = 3; + } + Global::iconservation = data[ "iconservation" ]; + Global::iviscous = data[ "iviscous" ]; + Global::nsave = data[ "nsave" ]; + Global::idump_initial_field = data[ "idump_initial_field" ]; + Global::ifinite_volume = data[ "ifinite_volume" ]; + Global::total_time = data[ "total_time" ]; + Global::dt = data[ "dt" ]; + std::cout << "Global::total_time = " << Global::total_time << "\n"; + std::cout << "Global::dt = " << Global::dt << "\n"; + + json &s = data[ "scheme" ]; + + std::cout << "s=" << s.dump( 4 ) << std::endl; + Global::scheme.read( s ); + + if ( Global::scheme.reconstruction == to_int( BasicScheme::WENO ) || + Global::scheme.reconstruction == to_int( BasicScheme::CRWENO )) + { + Global::nghost = 3; + } + else + { + Global::nghost = 1; + } + + this->gridfile = data[ "grid" ]; + } + HXBcastData( &Global::istart, 1, Parallel::serverid ); + HXBcastData( &Global::governing_equation, 1, Parallel::serverid ); + HXBcastData( &Global::iconservation, 1, Parallel::serverid ); + HXBcastData( &Global::iviscous, 1, Parallel::serverid ); + HXBcastData( &Global::nsave, 1, Parallel::serverid ); + HXBcastData( &Global::idump_initial_field, 1, Parallel::serverid ); + HXBcastData( &Global::ifinite_volume, 1, Parallel::serverid ); + HXBcastData( &Global::total_time, 1, Parallel::serverid ); + HXBcastData( &Global::dt, 1, Parallel::serverid ); + HXBcastData( &Global::scheme, 1, Parallel::serverid ); + HXBcastData( &Global::nghost, 1, Parallel::serverid ); + HXBcastData( &Global::nequ, 1, Parallel::serverid ); + HXBcastString( this->gridfile, Parallel::serverid ); + + PrintPidHeader(); + std::cout << "Global::istart = " << static_cast( Global::istart ) << "\n"; + PrintPidHeader(); + std::cout << "Global::governing_equation = " << static_cast( Global::governing_equation ) << "\n"; + PrintPidHeader(); + std::cout << "Global::iconservation = " << Global::iconservation << "\n"; + PrintPidHeader(); + std::cout << "Global::iviscous = " << Global::iviscous << "\n"; + PrintPidHeader(); + std::cout << "Global::nsave = " << Global::nsave << "\n"; + PrintPidHeader(); + std::cout << "Global::idump_initial_field = " << Global::idump_initial_field << "\n"; + PrintPidHeader(); + std::cout << "Global::ifinite_volume = " << Global::ifinite_volume << "\n"; + PrintPidHeader(); + std::cout << "Global::total_time = " << Global::total_time << "\n"; + PrintPidHeader(); + std::cout << "Global::dt = " << Global::dt << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.inviscid = " << Global::scheme.inviscid << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.viscous = " << Global::scheme.viscous << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.time_scheme = " << Global::scheme.time_scheme << "\n"; + PrintPidHeader(); + std::cout << "Global::scheme.reconstruction = " << Global::scheme.reconstruction << "\n"; + PrintPidHeader(); + std::cout << "Global::nghost = " << Global::nghost << "\n"; + PrintPidHeader(); + std::cout << "this->gridfile = " << this->gridfile << "\n"; + } + +void Solver::Read_iter() +{ + std::ifstream f( "iter.json" ); + json data = json::parse( f ); + + Global::iter_start = data[ "iter" ]; +} + +void Solver::Dump_iter() +{ + //std::print( "Global::iter={}", Global::iter + 1 ); + json j; + // add a number that is stored as double (note the implicit conversion of j to an object) + j["iter"] = Global::iter + 1; + + // JSONдļ + std::ofstream file("iter.json"); + if (file.is_open()) { + file << j.dump( 4 ); // 4ʾʽ + file.close(); + std::cout << "JSONдiter.jsonļ" << std::endl; + } else { + std::cerr << "޷ļ" << std::endl; + } +} + +void Solver::Run() +{ + this->Init(); + this->ReadGrid(); + this->InitTopo(); + this->InitFields(); + this->SolveFields(); + this->PostProcess(); +} + +void Solver::ReadGrid() +{ + ReadCgnsGridBaseZone( this->gridfile ); + ReadCgnsGrid( this->gridfile ); +} + +void Solver::CreateField() +{ + Field * field = nullptr; + if ( Global::governing_equation == GoverningEquation::Heat ) + { + field = new HeatField(); + } + else if ( Global::governing_equation == GoverningEquation::LinearConvection ) + { + field = new ConvectionField(); + } + else if ( Global::governing_equation == GoverningEquation::Burgers ) + { + field = new BurgersField(); + } + else + { + field = new EulerField(); + } + Global::fields.push_back( field ); +} + +void Solver::InitFields() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitFields() ZoneState::nZones = " << ZoneState::nZones << "\n"; + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + CreateField(); + } + + InitFieldCommon(); + + if ( Global::istart == 0 ) + { + InitFieldAsRestart(); + } + else + { + ReadFlowField(); + } + + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::InitFieldAsRestart() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + Field * field = Global::fields[ iZone ]; + field->InitFieldAsRestart( grid ); + } +} + +void Solver::ReadFlowField() +{ + std::string filename = "field_final.csv"; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::in ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->ReadFlowField( file, grid ); + } + + //HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + //if ( Parallel::pid == Parallel::serverid ) + //{ + // total_string += Global::file_string; + //} + } + if ( Parallel::pid == Parallel::serverid ) + { + file.close(); + } +} + +void Solver::InitFieldCommon() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Grid * grid = Global::grids[ iZone ]; + grid->zoneIndex = iZone; + Field * field = Global::fields[ iZone ]; + field->InitFieldCommon( grid ); + } +} + +void Solver::DumpInitialFields() +{ + this->DumpField(); +} + +void Solver::TimeIntegral() +{ + BasicScheme time_scheme = to_BasicScheme( Global::scheme.time_scheme ); + switch ( time_scheme ) { + case BasicScheme::RK1: + this->RungeKutta( 1 ); + break; + case BasicScheme::RK2: + this->RungeKutta( 2 ); + break; + case BasicScheme::RK3: + this->RungeKutta( 3 ); + break; + default: + this->CrankNicolsonSeries(); + } +} + +void Solver::SolveFields() +{ + if ( Global::idump_initial_field == 1 ) + { + this->DumpInitialFields(); + } + + for ( int it = Global::iter_start; it < Global::nt; ++ it ) + { + Global::iter = it; + this->TimeIntegral(); + + if ( ( Global::iter + 1 ) % Global::nsave == 0 ) + { + std::print( "it = {} nt = {}\n", Global::iter + 1, Global::nt ); + this->DumpField(); + } + } +} + +void Solver::FTCS() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->FTCS( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::CrankNicolsonSeries() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->CrankNicolsonSeries( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::ICP() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->ICP( zone ); + } + this->Boundary(); + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage ) +{ + for ( int istage = 0; istage < nStage; ++ istage ) + { + this->RungeKutta( nStage, istage ); + } + this->UpdateOldField(); +} + +void Solver::RungeKutta( int nStage, int istage ) +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + zone->zoneIndex = iZone; + field->RungeKutta( zone, nStage, istage ); + } + this->Boundary(); +} + +void Solver::Boundary() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->PhysicalBoundary( zone ); + } + ExchangeInterfaceField(); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->InterfaceBoundary( zone ); + } +} + +void Solver::UpdateOldField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Field * field = Global::fields[ iZone ]; + Zone * zone = Global::zones[ iZone ]; + field->UpdateOldField(); + } +} + +void Solver::UploadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + + Field * field = Global::fields[ iZone ]; + + int nsend_zones = interface->send_to_zones.size(); + for ( int iSend = 0; iSend < nsend_zones; ++ iSend ) + { + int zone_to_send = interface->send_to_zones[ iSend ]; + std::vector & donorfaces_for_send = interface->donorfaces_for_send[ iSend ]; + std::vector & donorijk_for_send = interface->donorijk_for_send[ iSend ]; + std::vector & donordata_for_send = interface->donordata_for_send[ iSend ]; + + int nInterFaces = donorfaces_for_send.size(); + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int iig = ig - Global::ifinite_volume; + int id_cell = donorijk_for_send[ ijkpos + iig ] - 1; + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + donordata_for_send[ data_pos ++ ] = u[ id_cell ]; + } + } + } + } + } +} + +void Solver::UpdateInterfaceField() +{ + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int ndonor_zones = Global::interfaceTopo.linkmap[ iZone ].size(); + for ( int iNei = 0; iNei < ndonor_zones; ++ iNei ) + { + int donor_zone = Global::interfaceTopo.linkmap[ iZone ][ iNei ]; + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = ZoneState::pids[ donor_zone ]; + int nsend = -1; + std::vector donordata; + if ( Parallel::pid != send_pid && Parallel::pid != recv_pid ) continue; + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + Interface * interface = Global::interfaces[ local_zoneid ]; + donordata = interface->donordata_for_send[ iNei ]; + nsend = donordata.size(); + } + HXSendRecvData( &nsend, 1, send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + donordata.resize( nsend ); + } + HXSendRecvData( donordata.data(), donordata.size(), send_pid, recv_pid ); + + if ( Parallel::pid == recv_pid ) + { + int local_donor_zoneid = ZoneState::g2lzoneids[ donor_zone ]; + Interface * donor_interface = Global::interfaces[ local_donor_zoneid ]; + int nSize = donor_interface->neighbor_donor_zones.size(); + int ipos = -1; + for ( int i = 0; i < nSize; ++ i ) + { + int nei_zone = donor_interface->neighbor_donor_zones[ i ]; + if ( nei_zone == iZone ) + { + ipos = i; + break; + } + } + + std::vector & neighbor_donorfaces = donor_interface->neighbor_donorfaces[ ipos ]; + std::vector & sub_local_faceids = donor_interface->sub_local_faceids[ ipos ]; + for ( int i = 0; i < neighbor_donorfaces.size(); ++ i ) + { + int local_faceid = sub_local_faceids[ i ]; + + int index_dim = 1; + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * local_faceid * ngsize; + int data_pos = local_faceid * ngsize * Global::nequ; + int donor_data_pos = i * ngsize * Global::nequ; + + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + double donor_value = donordata[ donor_data_pos ++ ]; + donor_interface->data_recv[ data_pos ++ ] = donor_value; + } + } + } + } + } + } +} + +void Solver::DownloadInterfaceField() +{ + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + Field * field = Global::fields[ iZone ]; + + int nInterFaces = interface->zoneList.size(); + + int index_dim = 1; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int ijkpos = index_dim * iFace * ngsize; + int data_pos = iFace * ngsize * Global::nequ; + for ( int ig = Global::ifinite_volume; ig <= Global::nghost; ++ ig ) + { + int ig_cell = interface->ijk_ghosts[ ijkpos ++ ] - 1; + if ( ig == 0 ) + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + double valueb = 0.5 * ( u[ ig_cell ] + donor_value ); + u[ ig_cell ] = valueb; + } + } + else + { + for ( int iequ = 0; iequ < Global::nequ; ++ iequ ) + { + Vec1d & u = field->u.vec( iequ ); + double donor_value = interface->data_recv[ data_pos ++ ]; + u[ ig_cell ] = donor_value; + } + } + } + } + } +} + +void Solver::ExchangeInterfaceField() +{ + this->UploadInterfaceField(); + this->UpdateInterfaceField(); + this->DownloadInterfaceField(); +} + +void Solver::DumpField() +{ + std::string filename = std::format( "field_final{}.csv", Global::iter+1 ); + this->DumpField( filename ); +} + +void Solver::DumpField( const std::string & filename ) +{ + std::string total_string = {}; + std::fstream file; + if ( Parallel::pid == Parallel::serverid ) + { + file.open( filename.c_str(), std::fstream::out ); + } + for ( int iZone = 0; iZone < ZoneState::nZones; ++ iZone ) + { + int send_pid = ZoneState::pids[ iZone ]; + int recv_pid = Parallel::serverid; + + Global::file_string = {}; + + if ( Parallel::pid == send_pid ) + { + int local_zoneid = ZoneState::g2lzoneids[ iZone ]; + + Grid * grid = Global::grids[ local_zoneid ]; + Field * field = Global::fields[ local_zoneid ]; + field->DumpField( grid ); + } + + HXSendRecvString( Global::file_string, send_pid, Parallel::serverid ); + + if ( Parallel::pid == Parallel::serverid ) + { + total_string += Global::file_string; + } + } + if ( Parallel::pid == Parallel::serverid ) + { + std::format_to( std::ostream_iterator( file ), "{}", total_string ); + file.close(); + } +} + +void Solver::PostProcess() +{ + std::string filename = "field_final.csv"; + this->DumpField( filename ); + this->Dump_iter(); +} + +void Solver::PrintField( std::vector &f ) +{ + int icount = 0; + for ( int i = 0; i < f.size(); ++ i ) + { + std::cout << std::setprecision(15) << f[ i ] << " "; + icount ++; + if ( icount % 5 == 0 ) + { + std::cout << "\n"; + } + } + std::cout << "\n"; + std::cout << "\n"; +} + +void Solver::InitTopo() +{ + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "Solver::InitTopo() " << "\n"; + + Global::donor_zone_sets.resize( LocalZone::nZones ); + Global::donor_zones.resize( LocalZone::nZones ); + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + int global_zoneid = LocalZone::global_zoneids[ iZone ]; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "iZone = " << iZone << " global_zoneid = " << global_zoneid << "\n"; + + Interface * interface = new Interface(); + interface->zoneid = global_zoneid; + Global::interfaces.push_back( interface ); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + Interface * interface = Global::interfaces[ iZone ]; + + int nbc1to1s = zone->bc1to1s.size(); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nbc1to1s = " << nbc1to1s << "\n"; + + for ( int ibc1to1 = 0; ibc1to1 < nbc1to1s; ++ ibc1to1 ) + { + ZoneBc1To1 * bc1to1 = zone->bc1to1s[ ibc1to1 ]; + int zoneid = bc1to1->zoneid; + int donor_zoneid = bc1to1->donor_zoneid; + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "zoneid = " << zoneid << " donor_zoneid = " << donor_zoneid << "\n"; + + Region region; + region.SetRegion( bc1to1->pnts ); + + Region donor_region; + donor_region.SetRegion( bc1to1->donor_pnts ); + + Transform transform; + transform.begin1 = region.start; + transform.begin2 = donor_region.start; + transform.transform = bc1to1->transform; + transform.Init(); + + interface->CalcInterface( &transform, region.start, region.end, donor_zoneid ); + } + int nInterfaces = interface->zoneList.size(); + int ngsize = Global::nghost + 1 - Global::ifinite_volume; + int nData = nInterfaces * ngsize * Global::nequ; + interface->data_recv.resize( nData ); + interface->data_send.resize( nData ); + } + + for ( int iProc = 0; iProc < Parallel::nProc; ++ iProc ) + { + int nSize = -1; + if ( iProc == Parallel::pid ) + { + nSize = Global::facePairList.size(); + } + HXBcastData( &nSize, 1, iProc ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + std::cout << "nSize = " << nSize << "\n"; + std::vector tmp; + if ( iProc == Parallel::pid ) + { + tmp = Global::facePairList; + } + else + { + tmp.resize( nSize ); + } + + HXBcastData( tmp.data(), tmp.size(), iProc ); + Global::AddFacePairList( Global::mpi_facePairList, tmp ); + } + + for ( int i = 0; i < Global::mpi_facePairList.size(); ++ i ) + { + FacePair &facePair = Global::mpi_facePairList[ i ]; + Global::InsertFacePairMap( facePair ); + std::cout << "Parallel::pid = " << Parallel::pid << " "; + facePair.Print(); + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Zone * zone = Global::zones[ iZone ]; + + Interface * interface = Global::interfaces[ iZone ]; + int nInterfaces = interface->local_faceids.size(); + for ( int iInterface = 0; iInterface < nInterfaces; ++ iInterface ) + { + int local_faceid = interface->local_faceids[ iInterface ]; + int proc_global_faceid = interface->proc_global_faceids[ iInterface ]; + FacePair & facePair = Global::facePairList[ proc_global_faceid ]; + int global_faceid = Global::InsertFacePairMap( facePair ); + interface->global_faceids.push_back( global_faceid ); + interface->global_local_face_map.insert( std::make_pair( global_faceid, local_faceid ) ); + } + } + + for ( int iZone = 0; iZone < LocalZone::nZones; ++ iZone ) + { + Interface * interface = Global::interfaces[ iZone ]; + int nInterFaces = interface->zoneList.size(); + std::set &donor_zoneSet = Global::donor_zone_sets[ iZone ]; + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + donor_zoneSet.insert( donor_zoneid ); + } + + std::vector &donor_zones = Global::donor_zones[ iZone ]; + for ( std::set::iterator iter = donor_zoneSet.begin(); iter != donor_zoneSet.end(); ++ iter ) + { + donor_zones.push_back( *iter ); + } + + interface->neighbor_donor_zones = donor_zones; + + std::unordered_map donor_zonelocal; + + for ( int idonor = 0; idonor < donor_zones.size(); ++ idonor ) + { + int donor_zone = donor_zones[ idonor ]; + donor_zonelocal.insert( std::make_pair( donor_zone, idonor ) ); + } + int ndonors = donor_zones.size(); + std::vector> & neighbor_donorfaces = interface->neighbor_donorfaces; + neighbor_donorfaces.resize( ndonors ); + + std::vector> & sub_local_faceids = interface->sub_local_faceids; + sub_local_faceids.resize( ndonors ); + + for ( int iFace = 0; iFace < nInterFaces; ++ iFace ) + { + int donor_zoneid = interface->zoneList[ iFace ]; + int ineighbor = donor_zonelocal[ donor_zoneid ]; + std::vector &donorfaces = neighbor_donorfaces[ ineighbor ]; + int global_faceid = interface->global_faceids[ iFace ]; + donorfaces.push_back( global_faceid ); + int local_faceid = interface->local_faceids[ iFace ]; + + std::vector & sub_local_faces = sub_local_faceids[ ineighbor ]; + sub_local_faces.push_back( local_faceid ); + } + } + + Global::interfaceTopo.InitNeighborInfo(); + Global::interfaceTopo.SwapNeighborInfo(); +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Solver.h b/example/1d-linear-convection/weno3/cpp/01/Solver.h new file mode 100644 index 00000000..ce995f68 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Solver.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include "Global.h" +#include "Grid.h" + +double compute_l2norm( int ni, std::vector & r ); +double compute_max_error( int ni, std::vector & u_error ); + +class Solver +{ +public: + Solver(); + ~Solver(); +public: + std::string gridfile; +public: + void Init(); + void Run(); + void ReadGrid(); + void InitFields(); + void InitFieldCommon(); + void InitFieldAsRestart(); + void ReadFlowField(); + void CreateField(); + void InitTopo(); + void SolveFields(); + void TimeIntegral(); + void DumpInitialFields(); + void Read_iter(); + void Dump_iter(); +public: + void Boundary(); + void UpdateOldField(); + void UploadInterfaceField(); + void UpdateInterfaceField(); + void DownloadInterfaceField(); + void ExchangeInterfaceField(); + void PrintField( std::vector & f ); +public: + void PostProcess(); + void DumpField(); + void DumpField( const std::string & filename ); +public: + void FTCS(); + void CrankNicolsonSeries(); + void ICP(); +public: + void RungeKutta( int nStage ); + void RungeKutta( int nStage, int istage ); +}; diff --git a/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp b/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp new file mode 100644 index 00000000..6f2fefb5 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Vec1d.cpp @@ -0,0 +1,10 @@ +#include "Vec1d.h" + +void VecWrap::Allocate( int nEqu, int ist, int ied, double value ) +{ + this->data.resize( nEqu ); + for ( int m = 0; m < nEqu; ++ m ) + { + this->data[ m ].Allocate( ist, ied, value ); + } +} diff --git a/example/1d-linear-convection/weno3/cpp/01/Vec1d.h b/example/1d-linear-convection/weno3/cpp/01/Vec1d.h new file mode 100644 index 00000000..82f65d17 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Vec1d.h @@ -0,0 +1,72 @@ +#pragma once +#include + +class Vec1d +{ +public: + std::vector data; + int ist = 0; + int ied; +public: + void Allocate( int ist, int ied, double value = 0 ) + { + int nelement = ied - ist + 1; + this->data.resize( nelement, value ); + this->ist = ist; + this->ied = ied; + } + std::size_t size() + { + return this->data.size(); + } + + double operator [] ( int i ) const + { + return data[ i - ist ]; + } + + double & operator [] ( int i ) + { + return data[ i - ist ]; + } + + Vec1d & operator = ( const Vec1d & rhs ) + { + if ( this == & rhs ) return * this; + this->data = rhs.data; + this->ist = rhs.ist; + this->ied = rhs.ied; + return * this; + } + + Vec1d & operator = ( const double value ) + { + for ( int i = 0; i < data.size(); ++ i ) + { + data[ i ] = value; + } + return * this; + } +}; + +class VecWrap +{ +public: + std::vector data; + void Allocate( int nEqu, int ist, int ied, double value = 0 ); + Vec1d & vec( int m = 0 ) { return data[ m ]; }; + VecWrap & operator = ( const double value ) + { + for ( int m = 0; m < data.size(); ++ m ) + { + data[ m ] = value; + } + return * this; + } + int get_nequ() const { return data.size(); } + + Vec1d & operator [] ( int m ) + { + return data[ m ]; + } +}; \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Weno.cpp b/example/1d-linear-convection/weno3/cpp/01/Weno.cpp new file mode 100644 index 00000000..211463db --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Weno.cpp @@ -0,0 +1,420 @@ +#include "Weno.h" +#include "hxmath.h" +#include +#include +#include +#include +#include + +double wcL3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double beta1 = SQR( v2 - v1 ); + double beta2 = SQR( v3 - v2 ); + + double d1 = 2.0 / 3.0; + double d2 = 1.0 / 3.0; + + // computing nonlinear weights w1, w2, w3 + double c1 = d1 / ( SQR( beta1 + eps ) ); + double c2 = d2 / ( SQR( beta2 + eps ) ); + + double w1 = c1 / ( c1 + c2 ); + double w2 = c2 / ( c1 + c2 ); + + // candiate stencils + double q1 = - v1 / 2.0 + 3.0 / 2.0 * v2; + double q2 = v2 / 2.0 + v3 / 2.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 ); + + return f; +} + +double wcR3( double v1, double v2, double v3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcL( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 1.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 6.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils + double q1 = v1 / 3.0 - 7.0 / 6.0 * v2 + 11.0 / 6.0 * v3; + double q2 = -v2 / 6.0 + 5.0 / 6.0 * v3 + v4 / 3.0; + double q3 = v3 / 3.0 + 5.0 / 6.0 * v4 - v5 / 6.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +double wcR( double v1, double v2, double v3, double v4, double v5 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 6.0e-1 / SQR( eps + s2 ); + double c3 = 1.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + // candiate stencils; + double q1 = -v1 / 6.0 + 5.0 / 6.0 * v2 + v3 / 3.0; + double q2 = v2 / 3.0 + 5.0 / 6.0 * v3 - v4 / 6.0; + double q3 = 11.0 / 6.0 * v3 - 7.0 / 6.0 * v4 + v5 / 3.0; + + // reconstructed value at interface + double f = ( w1 * q1 + w2 * q2 + w3 * q3 ); + + return f; +} + +//----------------------------------------------------------------------------- +// WENO reconstruction for upwind direction (positive; left to right) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i+1/2; j = 1,...,N +//----------------------------------------------------------------------------- +void wenoL( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 2 ]; + double v2 = u[ ii - 1 ]; + double v3 = u[ ii ]; + double v4 = u[ ii + 1 ]; + double v5 = u[ ii + 2 ]; + f[ i ] = wcL( v1, v2, v3, v4, v5 ); + if ( std::isnan( f[ i ] ) ) + { + int kkk = 1; + } + } +} + +//----------------------------------------------------------------------------- +// CRWENO reconstruction for downwind direction (negative; right to left) +// u(i): solution values at finite difference grid nodes i = 1,...,N+1 +// f(j): reconstructed values at nodes j = i-1/2; j = 2,...,N+1 +//----------------------------------------------------------------------------- +void wenoR( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v1 = u[ ii - 1 ]; + double v2 = u[ ii ]; + double v3 = u[ ii + 1 ]; + double v4 = u[ ii + 2 ]; + double v5 = u[ ii + 3 ]; + f[ i ] = wcR( v1, v2, v3, v4, v5 ); + } +} + +void Upwind1L( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii ]; + f[ i ] = v3; + } +} + +void Upwind1R( int N, Vec1d & u, Vec1d & f ) +{ + for ( int i = 0; i <= N; ++ i ) + { + int ii = i - 1; + double v3 = u[ ii + 1 ]; + f[ i ] = v3; + } +} + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = ( 2.0 * w1 + w2 ) / 3.0; + a2 = ( w1 + 2.0 * w2 + 2.0 * w3 ) / 3.0; + a3 = w3 / 3.0; + + b1 = w1 / 6.0; + b2 = ( 5.0 * w1 + 5.0 * w2 + w3 ) / 6.0; + b3 = ( w2 + 5.0 * w3 ) / 6.0; +} + +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + a1 = w1 / 3.0; + a2 = ( w3 + 2.0 * w2 + 2.0 * w1 ) / 3.0; + a3 = ( 2.0 * w3 + w2 ) / 3.0; + + b1 = ( w2 + 5.0 * w1 ) / 6.0; + b2 = ( 5.0 * w3 + 5.0 * w2 + w1 ) / 6.0; + b3 = w3 / 6.0; +} + +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 2.0e-1 / ( SQR( eps + s1 ) ); + double c2 = 5.0e-1 / ( SQR( eps + s2 ) ); + double c3 = 3.0e-1 / ( SQR( eps + s3 ) ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabL( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ) +{ + double eps = 1.0e-6; + + // smoothness indicators + double s1 = ( 13.0 / 12.0 ) * SQR( v1 - 2.0 * v2 + v3 ) + 0.25 * SQR( v1 - 4.0 * v2 + 3.0 * v3 ); + double s2 = ( 13.0 / 12.0 ) * SQR( v2 - 2.0 * v3 + v4 ) + 0.25 * SQR( v2 - v4 ); + double s3 = ( 13.0 / 12.0 ) * SQR( v3 - 2.0 * v4 + v5 ) + 0.25 * SQR( 3.0 * v3 - 4.0 * v4 + v5 ); + + // computing nonlinear weights w1, w2, w3 + double c1 = 3.0e-1 / SQR( eps + s1 ); + double c2 = 5.0e-1 / SQR( eps + s2 ); + double c3 = 2.0e-1 / SQR( eps + s3 ); + + double w1 = c1 / ( c1 + c2 + c3 ); + double w2 = c2 / ( c1 + c2 + c3 ); + double w3 = c3 / ( c1 + c2 + c3 ); + + crabR( w1, w2, w3, a1, a2, a3, b1, b2, b3 ); +} + +void crwenoL( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabL( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 2 ]; + v2 = u[ i - 1 ]; + v3 = u[ i ]; + v4 = u[ i + 1 ]; + v5 = u[ i + 2 ]; + crwcL( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + } + + i = ni - 1; + ii = i - ist; + crabL( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i - 1 ] + b2 * u[ i ] + b3 * u[ i + 1 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } + +} + +void crwenoR( int ni, Vec1d & u, Vec1d & f ) +{ + std::vector a( ni + 1 ); + std::vector b( ni + 1 ); + std::vector c( ni + 1 ); + std::vector r( ni + 1 ); + std::vector y( ni + 1 ); + + int i, ii; + double v1, v2, v3, v4, v5; + double a1, a2, a3, b1, b2, b3; + + int ist = -1; + + i = -1; + ii = i - ist; + crabR( 0, 0, 1, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + for ( int i = 0; i < ni - 1; ++ i ) + { + ii = i - ist; + v1 = u[ i - 1 ]; + v2 = u[ i ]; + v3 = u[ i + 1 ]; + v4 = u[ i + 2 ]; + v5 = u[ i + 3 ]; + + crwcR( v1, v2, v3, v4, v5, a1, a2, a3, b1, b2, b3 ); + + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + } + + i = ni - 1; + ii = i - ist; + crabR( 1, 0, 0, a1, a2, a3, b1, b2, b3 ); + a[ ii ] = a1; + b[ ii ] = a2; + c[ ii ] = a3; + r[ ii ] = b1 * u[ i ] + b2 * u[ i + 1 ] + b3 * u[ i + 2 ]; + + thomas_algorithm( a, b, c, r, y ); + + for ( int i = 0; i < ni + 1; ++ i ) + { + f[ i ] = y[ i ]; + } +} + + +void crwenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void crwenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + crwenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoL( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoL( ni, u.vec( m ), f.vec( m ) ); + } +} + +void wenoR( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + wenoR( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1L( ni, u.vec( m ), f.vec( m ) ); + } +} + +void Upwind1R( int ni, VecWrap & u, VecWrap & f ) +{ + int nequ = u.get_nequ(); + for ( int m = 0; m < nequ; ++ m ) + { + Upwind1R( ni, u.vec( m ), f.vec( m ) ); + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/Weno.h b/example/1d-linear-convection/weno3/cpp/01/Weno.h new file mode 100644 index 00000000..6f376907 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/Weno.h @@ -0,0 +1,36 @@ +#pragma once +#include "Vec1d.h" + +double wcL( double v1, double v2, double v3, double v4, double v5 ); +double wcR( double v1, double v2, double v3, double v4, double v5 ); +void wenoL( int N, Vec1d & u, Vec1d & f ); +void wenoR( int N, Vec1d & u, Vec1d & f ); + +void Upwind1L( int N, Vec1d & u, Vec1d & f ); +void Upwind1R( int N, Vec1d & u, Vec1d & f ); + +void crabL( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crabR( double w1, double w2, double w3, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcL( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); +void crwcR( double v1, double v2, double v3, double v4, double v5, + double & a1, double & a2, double & a3, + double & b1, double & b2, double & b3 ); + +void crwenoL( int ni, Vec1d & u, Vec1d & f ); +void crwenoR( int ni, Vec1d & u, Vec1d & f ); + +void crwenoL( int ni, VecWrap & u, VecWrap & f ); +void crwenoR( int ni, VecWrap & u, VecWrap & f ); + +void wenoL( int ni, VecWrap & u, VecWrap & f ); +void wenoR( int ni, VecWrap & u, VecWrap & f ); + +void Upwind1L( int ni, VecWrap & u, VecWrap & f ); +void Upwind1R( int ni, VecWrap & u, VecWrap & f ); + diff --git a/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp b/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp new file mode 100644 index 00000000..ff810849 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ZoneState.cpp @@ -0,0 +1,20 @@ +#include "ZoneState.h" +#include "Parallel.h" + +int ZoneState::nZones = 0; +std::vector ZoneState::pids; +std::vector ZoneState::g2lzoneids; + +bool ZoneState::IsValid( int zoneid ) +{ + return ZoneState::pids[ zoneid ] == Parallel::pid; +} + +int ZoneState::GetProcID( int zoneid ) +{ + return ZoneState::pids[ zoneid ]; +} + +int LocalZone::nZones = 0; +std::vector LocalZone::global_zoneids; + diff --git a/example/1d-linear-convection/weno3/cpp/01/ZoneState.h b/example/1d-linear-convection/weno3/cpp/01/ZoneState.h new file mode 100644 index 00000000..1096d632 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/ZoneState.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class ZoneState +{ +public: + static int nZones; + static int zone_id; + static std::vector pids; + static std::vector g2lzoneids; //global zone id to local zone id +public: + static bool IsValid( int zoneid ); + static int GetProcID( int zoneid ); +}; + +class LocalZone +{ +public: + static int nZones; + static std::vector global_zoneids; +}; \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers.json b/example/1d-linear-convection/weno3/cpp/01/burgers.json new file mode 100644 index 00000000..1034215d --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers.json @@ -0,0 +1,17 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json b/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json new file mode 100644 index 00000000..9619dfe6 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers_ftcs.json @@ -0,0 +1,15 @@ +{ + "total_time" : 0.25, + "equation" : "burgers", + "iconservation" : 0, + "iviscous" : 0, + "nsave" : 250, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "ftcs", + "viscous" : "ftcs", + "time" : "ftcs" + }, + "grid" : "../burgers1d1blocksv1.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py b/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py new file mode 100644 index 00000000..0882aff1 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/burgers_plot.py @@ -0,0 +1,64 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'LaxFriedrichs' +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +ns = 10 + +u = np.zeros( (ni, ns + 1 ) ) +x = np.zeros( (ni) ) + +for j in range(ns+1): + filename = 'field_final'+str((j)*250)+'.csv' + print('filename=',filename) + with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i][j] = float(row[1]) + i += 1 + +print("u.shape=",u.shape) +n1 = u.shape[0] +n2 = u.shape[1] +print(f"n1={n1},n2={n2}") +#exit() +#x = np.linspace(0,1, num=ni) + +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] + +for k in range(ns+1): + ut = u[sorted_indices,k] + u[:,k] = ut[:] +tm = 0.25 + +titlename = "Inviscid Burgers Equation: WENO5+ " + scheme + " Scheme" +plt.figure("OneFLOW-CFD Solver", figsize=(6, 4), dpi=100) +for k in range(0, ns+1): + plt.plot(xt, u[:,k], linewidth=1.0, label="t="+format(tm*k/ns, ".4f")) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title(titlename) +plt.legend(loc='upper right', fontsize='6') +plt.show() \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/cfd.json b/example/1d-linear-convection/weno3/cpp/01/cfd.json new file mode 100644 index 00000000..8007b6dd --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/cfd.json @@ -0,0 +1,12 @@ +{ + "total_time" : 1.0, + "equation" : "burgers", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/heat.json b/example/1d-linear-convection/weno3/cpp/01/heat.json new file mode 100644 index 00000000..0febea40 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heat.json @@ -0,0 +1,17 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 400, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../heat1d2blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/heat_plot.py b/example/1d-linear-convection/weno3/cpp/01/heat_plot.py new file mode 100644 index 00000000..2f62d1a2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heat_plot.py @@ -0,0 +1,116 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +#-----------------------------------------------------------------------------# +# Compute L-2 norm for a vector +#-----------------------------------------------------------------------------# +def compute_l2norm(nx,r): + rms = 0.0 + for i in range(1, nx): + rms += r[i] * r[i] + rms = np.sqrt( rms / ( ( nx - 1 ) ) ) + return rms + +def compute_max_error( nx, u_error ): + val_max = -1; + ipos = -1; + for i in range(1, nx): + if ( val_max < np.abs( u_error[ i ] ) ): + ipos = i; + val_max = np.abs( u_error[ i ] ) + print( "ipos = ", ipos ) + return val_max; + + +nt = 400 +t = 1.0 + +filename = 'field_final'+str(nt)+'.csv' + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +labelname = "FTCS solution" +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + labelname = scheme + ' solution' + +print("labelname=",labelname) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +x = np.zeros( (ni) ) +u = np.zeros( (ni) ) +ue= np.zeros( (ni) ) + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + u[i] = float(row[1]) + i += 1 +#sort +sorted_indices = np.argsort(x) +xt=x[sorted_indices] +ut=u[sorted_indices] +x=xt +u=ut + +for i in range(ni): + ue[i] = - np.exp(-t) * np.sin( np.pi * x[i] ) # theory solution + +uerror = u - ue + +nx = ni - 1 + +my_max_error = compute_max_error( nx, uerror ) + +rms_error = compute_l2norm(nx,uerror) +max_error = np.max( np.abs(uerror) ) + +#print("my_max_error = {0:.15f}".format(my_max_error)) +print("Error details: "); +print("L-2 Norm = {0}" .format(str(rms_error))); +print("Maximum Norm = {0}".format(str(max_error))); + +# create output file for L2-norm +output = open("output.txt", "w"); +output.write("Error details: \n"); +output.write("L-2 Norm = {0}\n" .format(str(rms_error))); +output.write("Maximum Norm = {0}\n".format(str(max_error))); +output.close() + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +#plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.scatter(x, u, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/heaticp.json b/example/1d-linear-convection/weno3/cpp/01/heaticp.json new file mode 100644 index 00000000..965d3f22 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/heaticp.json @@ -0,0 +1,13 @@ +{ + "total_time" : 1.0, + "equation" : "heat", + "iconservation" : "0", + "iviscous" : 0, + "scheme" : + { + "inviscid" : "weno5", + "viscous" : "center", + "time" : "icp" + }, + "grid" : "../heat1d1blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp b/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp new file mode 100644 index 00000000..c1b08977 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/hxmath.cpp @@ -0,0 +1,30 @@ +#include "hxmath.h" + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ) +{ + size_t N = d.size(); + + std::vector c_star( N, 0.0 ); + std::vector d_star( N, 0.0 ); + + c_star[ 0 ] = c[ 0 ] / b[ 0 ]; + d_star[ 0 ] = d[ 0 ] / b[ 0 ]; + + for ( int i = 1; i < N; ++ i ) + { + double coef = 1.0 / ( b[ i ] - a[ i ] * c_star[ i - 1 ] ); + c_star[ i ] = c[ i ] * coef; + d_star[ i ] = ( d[ i ] - a[ i ] * d_star[ i - 1 ] ) * coef; + } + + x[ N - 1 ] = d_star[ N - 1 ]; + + for ( int i = N - 2; i >= 0; -- i ) + { + x[ i ] = d_star[ i ] - c_star[ i ] * x[ i + 1 ]; + } +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/hxmath.h b/example/1d-linear-convection/weno3/cpp/01/hxmath.h new file mode 100644 index 00000000..2c942e2a --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/hxmath.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "vec1d.h" + +template +auto SQR(Args... args) { + return (... + (args * args)); +} + +void thomas_algorithm( const std::vector & a, + const std::vector & b, + const std::vector & c, + const std::vector & d, + std::vector & x ); + +using RhsPtr = void(*)(int, double, Vec1d &, Vec1d &); diff --git a/example/1d-linear-convection/weno3/cpp/01/linearconvection.json b/example/1d-linear-convection/weno3/cpp/01/linearconvection.json new file mode 100644 index 00000000..9491dce2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/linearconvection.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.625, + "dt" : 0.025, + "equation" : "linearconvection", + "iconservation" : 0, + "ifinite_volume" : 0, + "iviscous" : 0, + "nsave" : 100, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "upwind1", + "reconstruction" : "upwind1", + "viscous" : "center", + "time" : "rk1" + }, + "grid" : "../linearconvection1d.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns b/example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns new file mode 100644 index 00000000..9bd44946 Binary files /dev/null and b/example/1d-linear-convection/weno3/cpp/01/linearconvection1d.cgns differ diff --git a/example/1d-linear-convection/weno3/cpp/01/main.cpp b/example/1d-linear-convection/weno3/cpp/01/main.cpp new file mode 100644 index 00000000..fcce6376 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/main.cpp @@ -0,0 +1,8 @@ +#include "Solver.h" + +int main( int argc, char ** argv ) +{ + Solver solver; + solver.Run(); + return 0; +} diff --git a/example/1d-linear-convection/weno3/cpp/01/plot.py b/example/1d-linear-convection/weno3/cpp/01/plot.py new file mode 100644 index 00000000..41a173a6 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/plot.py @@ -0,0 +1,58 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +ue_list = [] +un_list = [] +uerror_list = [] + +with open('field_final.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + #print(row) + #print(row[0]) + #print(row[0], row[1], row[2], row[3]) + if ( icount != 0 ) : + x_list.append(row[0]) + ue_list.append(row[1]) + un_list.append(row[2]) + uerror_list.append(row[3]) + icount += 1 + +ni = icount - 1 +print("ni=",ni) + +x = np.zeros( ni ) +ue = np.zeros( ni ) +un = np.zeros( ni ) +uerror = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + ue[i] = float(ue_list[i]) + un[i] = float(un_list[i]) + uerror[i] = float(uerror_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(10, 4), dpi=100) +plt.subplot(1, 2, 1) +plt.plot(x, ue, "k-", linewidth=1.0, label="Exact solution") +plt.scatter(x, un, facecolor="none", edgecolor="blue", s=20, linewidths=0.5, label="ICP solution") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("Solution field") +plt.legend() +plt.tight_layout() + +plt.subplot(1, 2, 2) +plt.scatter(x, np.abs(uerror), facecolor="none", edgecolor="green", s=20, linewidths=0.5) +plt.ylabel(r"$\epsilon$") +plt.xlabel("$x$") +plt.title("Discretization error") +plt.tight_layout() +plt.ticklabel_format(axis='y', style='sci', scilimits=(-4,-4)) + +plt.show(); + + diff --git a/example/1d-linear-convection/weno3/cpp/01/plotting2.jl b/example/1d-linear-convection/weno3/cpp/01/plotting2.jl new file mode 100644 index 00000000..c74255b2 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/plotting2.jl @@ -0,0 +1,49 @@ +using CSV +using DataFrames +using PyPlot +rc("font", family="Arial", size=16.0) + + +final_field = CSV.read("field_final.csv", DataFrame)#, datarow = 2, type=Float64) + +x = convert(Array,final_field[:,1]) + +u_e = convert(Array,final_field[:,2]) +u_n = convert(Array,final_field[:,3]) +u_error = convert(Array,final_field[:,4]) + +u = Array{Float64}(undef, length(u_e), 2) +u[:,1] = u_e +u[:,2] = u_n + +for i = 1:Int64(length(u_error)) + u_error[i] = abs(u_error[i]) +end + +fig = figure("FTCS", figsize=(14,6)); +ax1 = fig[:add_subplot](1,2,1); +ax2 = fig[:add_subplot](1,2,2); + +ax1.plot(x, u_e, lw=4, ls = "-", color="b", label="Exact solution") +ax1.plot(x, u_n, lw=4, ls = "--", color="r", label="FTCS solution") +ax1.set_xlabel("\$x\$") +ax1.set_ylabel("\$u\$") +ax1.set_title("Solution field") +ax1.set_xlim(-1,1) +ax1.legend(fontsize=14, loc=0) + +ax2.plot(x, u_error, marker = "o", markeredgecolor="k", + markersize=8, color="g", lw=4) +ax2.set_xlabel("\$x\$") +ax2.set_ylabel("\$ϵ\$") +ax2.set_title("Discretization error") +ax2.set_xlim(-1,1) +#ax2.legend(fontsize=14, loc=0) + +#plt[:subplot](ax1); +#plt[:subplot](ax2); + +fig.tight_layout() +fig.savefig("ftcs.pdf") + +show() diff --git a/example/1d-linear-convection/weno3/cpp/01/sod.json b/example/1d-linear-convection/weno3/cpp/01/sod.json new file mode 100644 index 00000000..638176c8 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod.json @@ -0,0 +1,19 @@ +{ + "istart" : 0, + "total_time" : 0.20, + "dt" : 0.0001, + "equation" : "euler", + "iconservation" : 1, + "ifinite_volume" : 1, + "iviscous" : 0, + "nsave" : 200, + "idump_initial_field" : 1, + "scheme" : + { + "inviscid" : "lax", + "reconstruction" : "weno5", + "viscous" : "center", + "time" : "rk3" + }, + "grid" : "../sodshocktube1d4blocks.cgns" +} \ No newline at end of file diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_plot.py b/example/1d-linear-convection/weno3/cpp/01/sod_plot.py new file mode 100644 index 00000000..2fda5d73 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_plot.py @@ -0,0 +1,173 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +class MyPlot: + def __init__( self ): + self.x = [] + self.r = [] + self.u = [] + self.m = [] + self.p = [] + self.ReadData() + + def AddData( self, xm, rm, um, mm, pm ): + self.x.append( xm ) + self.r.append( rm ) + self.u.append( um ) + self.m.append( mm ) + self.p.append( pm ) + + def ReadData( self ): + with open('../sod_theory.plt', 'r') as f: + for index, line in enumerate(f): + words = line.strip().split() + self.x.append( float(words[0]) ) + self.r.append( float(words[1]) ) + self.u.append( float(words[2]) ) + self.m.append( float(words[3]) ) + self.p.append( float(words[4]) ) + self.ComputeEnergy() + + def ComputeEnergy( self ): + num = len(self.x) + self.e = np.zeros( num ) + print("self.e.len=", len(self.e)) + gama = 1.4 + for i in range(0, num ): + um = self.u[i] + rm = self.r[i] + pm = self.p[i] + self.e[i] = (1.0/(gama-1.0))* pm/rm + 0.5 * ( um * um ) + + def PlotTheory( self ): + plt.figure("Exact solution for the Sod's shock-tube problem", figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, linewidth=1.0, label="density") + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, linewidth=1.0, label="velocity") + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.m, linewidth=1.0, label="mach number") + plt.xlabel("$x$") + plt.ylabel(r"$m$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, linewidth=1.0, label="pressure") + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + + def PlotCompare( self, x, q, title ): + numPoints = len( q[:,0] ) + print("numPoints=",numPoints) + + rr = np.zeros( numPoints ) + uu = np.zeros( numPoints ) + pp = np.zeros( numPoints ) + ee = np.zeros( numPoints ) + + gama = 1.4 + for i in range( 0, numPoints ): + rho = q[ i, 0 ] + rhou = q[ i, 1 ] + rhoe = q[ i, 2 ] + rr[i] = rho + uu[i] = rhou / rho + ee[i] = rhoe / rho + pp[i] = ( gama - 1.0 ) * ( rhoe - 0.5 * rho * ( uu[i] * uu[i] ) ) + + sizes = 4 + #plt.figure("Sod's shock-tube problem+Rusanov Scheme+WENO-5 reconstruction", figsize=(10, 8), dpi=100) + plt.figure(title, figsize=(10, 8), dpi=100) + plt.subplot(2, 2, 1) + plt.plot(self.x, self.r, color='black', linewidth=1.0, label="theory") + plt.scatter(x, rr, marker= "o", s=sizes, facecolors='none', edgecolors='blue', label="OneFLOW-CFD" ) + + plt.xlabel("$x$") + plt.ylabel(r"$\rho$") + plt.legend() + + plt.subplot(2, 2, 2) + plt.plot(self.x, self.u, color='black', linewidth=1.0, label="theory") + plt.scatter(x, uu, marker= "o", s=sizes, facecolors='none', edgecolors='red', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$u$") + plt.legend() + + plt.subplot(2, 2, 3) + plt.plot(self.x, self.e, color='black', linewidth=1.0, label="theory") + plt.scatter(x, ee, marker= "o", s=sizes, facecolors='none', edgecolors='green', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$E$") + plt.legend() + + plt.subplot(2, 2, 4) + plt.plot(self.x, self.p, color='black', linewidth=1.0, label="theory") + plt.scatter(x, pp, marker= "o", s=sizes, facecolors='none', edgecolors='orange', label="OneFLOW-CFD" ) + plt.xlabel("$x$") + plt.ylabel(r"$p$") + plt.legend() + + plt.tight_layout() + + plt.show() + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +scheme = 'Rusanov' +nt = 2000 +if nvar >= 2: + scheme = sys.argv[1] + print('scheme=',scheme) + +if nvar >= 3: + mt = sys.argv[2] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 + +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) + + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +title = "Sod's shock-tube problem+ " + scheme + " Scheme+WENO-5 reconstruction" +mplot = MyPlot() +mplot.PlotCompare(x, q, title) diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_sort.py b/example/1d-linear-convection/weno3/cpp/01/sod_sort.py new file mode 100644 index 00000000..bc46ba61 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_sort.py @@ -0,0 +1,68 @@ +import numpy as np +import csv +import sys +import os + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +with open('field_final0.csv', newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm+1) ) +x = np.zeros( (ni) ) + +filename = 'field_final'+str(nt)+'.csv' + +with open(filename, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + q[i][3] = float(row[4]) + i += 1 + +#sort +sorted_indices = np.argsort(x) +xs=x[sorted_indices] +qs=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xs[i])) + ll.append("{:.25f}".format(qs[i,0])) + ll.append("{:.25f}".format(qs[i,1])) + ll.append("{:.25f}".format(qs[i,2])) + ll.append("{:.25f}".format(qs[i,3])) + data.append(ll) + +basename = os.path.basename(filename) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.bak' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py b/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py new file mode 100644 index 00000000..b56f80b5 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_sort_on_xcoor.py @@ -0,0 +1,85 @@ +import numpy as np +import csv +import sys +import os + +def get_sorted_indices(arr1, arr2): + # 创建一个字典来存储原始数组的索引 + index_dict = {value: index for index, value in enumerate(arr1)} + # 使用字典来构建 index_map + index_map = [index_dict[item] for item in arr2] + return index_map + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +nt = 2000 +if nvar >= 2: + mt = sys.argv[1] + nt = int(mt) + print('nt=',nt) + +filename_src = 'field_final'+str(nt)+'.csv' +filename_tgt = 'field_final_x_tgt.csv' +print("filename_src=",filename_src) +print("filename_tgt=",filename_tgt) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for row in readCSV: + icount += 1 + +ni = icount +print("ni=",ni) + +nm = 3 +q = np.zeros( (ni, nm ) ) +x = np.zeros( (ni) ) +xt = np.zeros( (ni) ) + +with open(filename_src, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + x[i] = float(row[0]) + q[i][0] = float(row[1]) + q[i][1] = float(row[2]) + q[i][2] = float(row[3]) + i += 1 + +with open(filename_tgt, newline='') as csvfile: + readCSV = csv.reader(csvfile, delimiter= ' ') + i = 0 + for row in readCSV: + xt[i] = float(row[0]) + i += 1 + +#exit() + +#sort +sorted_indices = get_sorted_indices(x, xt) +qt=q[sorted_indices,:] + +data = [] + +for i in range(ni): + ll = [] + ll.append("{:.25f}".format(xt[i])) + ll.append("{:.25f}".format(qt[i,0])) + ll.append("{:.25f}".format(qt[i,1])) + ll.append("{:.25f}".format(qt[i,2])) + data.append(ll) + +basename = os.path.basename(filename_src) +file_name, _ = os.path.splitext(basename) + +outfilename = file_name + '.tgt' + +print("outfilename=",outfilename) + +with open(outfilename, 'w', newline='', encoding='utf-8') as csvfile: + writer = csv.writer(csvfile, delimiter=' ') + writer.writerows(data) + diff --git a/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt b/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt new file mode 100644 index 00000000..017b2a23 --- /dev/null +++ b/example/1d-linear-convection/weno3/cpp/01/sod_theory.plt @@ -0,0 +1,29 @@ +0.0 1.0 0.0 0.0 1.0 +0.26335680867601535 1.0 0.0 0.0 1.0 +0.27347447203688646 0.9648750586208616 0.042156930670296286 0.035884818144028864 0.9511729968287278 +0.28359213539775757 0.9307441341034813 0.08431386134059257 0.07228844784905321 0.9044039093345754 +0.2937097987586287 0.8975859779771813 0.12647079201088884 0.1092222222653988 0.8596199444877537 +0.3038274621194998 0.8653796467623747 0.16862772268118514 0.1466978070530514 0.8167503838854002 +0.3139451254803709 0.8341044997658321 0.21078465335148144 0.1847272126663733 0.7757265390861141 +0.324062788841242 0.8037401968759483 0.2529415840217777 0.22332280718751102 0.7364817075902278 +0.3341804522021131 0.7742666963580094 0.295098514692074 0.2624973297373015 0.6989511294611133 +0.34429811556298423 0.7456642526494588 0.3372554453623703 0.30226390449422186 0.6630719445828217 +0.35441577892385534 0.717913414155165 0.37941237603266653 0.34263605535379293 0.628783150549354 +0.36453344228472645 0.6909950210426873 0.4215693067029629 0.3836277212628337 0.5960255611808599 +0.37465110564559756 0.6648902030375431 0.46372623737325913 0.4252532722650894 0.5647417656620655 +0.38476876900646867 0.6395803772184753 0.5058831680435554 0.46752752629703953 0.5348760882982245 +0.3948864323673398 0.6150472458127165 0.5480400987138516 0.5104657667751211 0.5063745488838924 +0.4050040957282109 0.5912727939912592 0.590197029384148 0.5540837610182198 0.47918482367982607 +0.415121759089082 0.5682392876641204 0.6323539600544442 0.5983977795520808 0.4532562069932973 +0.4252394224499531 0.5459292712756086 0.6745108907247406 0.6434246163452886 0.4285395733571278 +0.4353570858108242 0.5243255655995911 0.7166678213950368 0.6891816100296887 0.4049873403027381 +0.44547474917169533 0.50341126553476 0.7588247520653331 0.7356866661615835 0.38255343172251066 +0.45559241253256644 0.48316973789989986 0.8009816827356294 0.782958280583741 0.36119324181676515 +0.4657100758934376 0.4635846192291532 0.843138613405926 0.8310155639522582 0.3408635996206424 +0.47582773925430866 0.4446398135672895 0.885295544076222 0.879878267496601 0.321522734106199 +0.48594540261517977 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.4263194902649682 0.9274524747465183 0.9295668100857784 0.3031302398550031 +0.6854904949493037 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.2655737448562897 0.9274524747465183 0.7336781473651145 0.3031302398550031 +0.8504311802684247 0.125 0.0 0.0 0.1 +1.0 0.125 0.0 0.0 0.1 diff --git a/example/1d-linear-convection/weno3/python/01/weno3.py b/example/1d-linear-convection/weno3/python/01/weno3.py new file mode 100644 index 00000000..da81ef74 --- /dev/null +++ b/example/1d-linear-convection/weno3/python/01/weno3.py @@ -0,0 +1,68 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 定义求解区域的网格和时间步长 +nx = 100 # 网格数 +L = 1 # 区域长度 +dx = L / nx # 网格步长 +dt = 0.01 # 时间步长 +nt = 10 # 时间步数 +a = 1 # 对流速度 + +# 定义线性对流方程的初始条件和边界条件 +x = np.linspace(0, L, nx) +u0 = np.sin(2 * np.pi * x) # 初始条件 +u = u0.copy() +u_bc = np.concatenate((u[-3:], u, u[:3])) # 周期边界条件 + +# 定义WENO方法的参数 +epsilon = 1e-6 # 避免分母为0 +p = 2 # 权重参数 + +# 循环求解线性对流方程 +for n in range(nt): + # 计算每个子模板的光滑度指标 + beta_0 = (u_bc[2:nx+2] - u_bc[1:nx+1])**2 + beta_1 = (u_bc[3:nx+3] - u_bc[2:nx+2])**2 + beta_3 = (1/3) * ((u_bc[1:nx+1] - 2*u_bc[2:nx+2] + u_bc[3:nx+3]) / dx)**2 + \ + (1/4) * ((u_bc[3:nx+3] - u_bc[1:nx+1]) / dx)**2 + + # 计算权重 + d_0 = 1/3 + d_1 = 2/3 + d_3 = 1/3 + alpha_0 = d_0 / (beta_0 + epsilon)**p + alpha_1 = d_1 / (beta_1 + epsilon)**p + alpha_3 = d_3 / (beta_3 + epsilon)**p + w_0 = alpha_0 / (alpha_0 + alpha_1 + alpha_3) + w_1 = alpha_1 / (alpha_0 + alpha_1 + alpha_3) + w_3 = alpha_3 / (alpha_0 + alpha_1 + alpha_3) + + # 计算重构值 + f_0 = -0.5 * u_bc[1:nx+1] + 1.5 * u_bc[2:nx+2] + f_1 = 0.5 * u_bc[2:nx+2] + 0.5 * u_bc[3:nx+3] + f_3 = (-1/6) * u_bc[1:nx+1] + (5/6) * u_bc[2:nx+2] + (1/3) * u_bc[3:nx+3] + f_weno = w_0 * f_0 + w_1 * f_1 + w_3 * f_3 + + # 更新解 + u = u - dt / dx * (f_weno - np.roll(f_weno, 1)) + + # 更新边界条件 + u_bc = np.concatenate((u[-3:], u, u[:3])) + +# 计算理论解 +t = nt * dt +u_exact = np.sin(2 * np.pi * (x - a * t)) +print("at=",a * t) +print("u0=",u0) +print("u_exact=",u_exact) + +# 绘制结果 +#plt.plot(x, u, label='WENO Solution') +plt.plot(x, u_exact, label='Exact Solution', linestyle='--') +plt.plot(x, u0, label='init Solution', linestyle='--') +plt.legend() +plt.title('Comparison of WENO Solution and Exact Solution') +plt.xlabel('x') +plt.ylabel('u') +plt.show() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt new file mode 100644 index 00000000..3d9c1611 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno1.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3978472836E+00 + -0.1475000000E+01 0.4267107631E+00 + -0.1425000000E+01 0.4551038904E+00 + -0.1375000000E+01 0.4829359721E+00 + -0.1325000000E+01 0.5100994918E+00 + -0.1275000000E+01 0.5364642119E+00 + -0.1225000000E+01 0.5618685745E+00 + -0.1175000000E+01 0.5861066686E+00 + -0.1125000000E+01 0.6089075423E+00 + -0.1075000000E+01 0.6299004565E+00 + -0.1025000000E+01 0.6485521486E+00 + -0.9750000000E+00 0.6640421254E+00 + -0.9250000000E+00 0.6749787962E+00 + -0.8750000000E+00 0.6786049580E+00 + -0.8250000000E+00 0.6661069824E+00 + -0.7750000000E+00 0.5397624003E+00 + -0.7250000000E+00 -0.2020829473E-01 + -0.6750000000E+00 -0.2250720675E+00 + -0.6250000000E+00 -0.2166894789E+00 + -0.5750000000E+00 -0.2032813898E+00 + -0.5250000000E+00 -0.1863137042E+00 + -0.4750000000E+00 -0.1666851401E+00 + -0.4250000000E+00 -0.1449884793E+00 + -0.3750000000E+00 -0.1216322279E+00 + -0.3250000000E+00 -0.9689476951E-01 + -0.2750000000E+00 -0.7091556422E-01 + -0.2250000000E+00 -0.4347209157E-01 + -0.1750000000E+00 -0.1011179643E-01 + -0.1250000000E+00 0.3697148653E-01 + -0.7500000000E-01 0.6707060641E-01 + -0.2500000000E-01 0.9723084379E-01 + 0.2500000000E-01 0.1275040098E+00 + 0.7500000000E-01 0.1578541658E+00 + 0.1250000000E+00 0.1882367792E+00 + 0.1750000000E+00 0.2186062738E+00 + 0.2250000000E+00 0.2489166057E+00 + 0.2750000000E+00 0.2791207239E+00 + 0.3250000000E+00 0.3091697383E+00 + 0.3750000000E+00 0.3390119185E+00 + 0.4250000000E+00 0.3685915076E+00 + 0.4750000000E+00 0.3978472836E+00 + 0.5250000000E+00 0.4267107631E+00 + 0.5750000000E+00 0.4551038904E+00 + 0.6250000000E+00 0.4829359721E+00 + 0.6750000000E+00 0.5100994918E+00 + 0.7250000000E+00 0.5364642119E+00 + 0.7750000000E+00 0.5618685745E+00 + 0.8250000000E+00 0.5861066686E+00 + 0.8750000000E+00 0.6089075423E+00 + 0.9250000000E+00 0.6299004565E+00 + 0.9750000000E+00 0.6485521486E+00 + 0.1025000000E+01 0.6640421254E+00 + 0.1075000000E+01 0.6749787962E+00 + 0.1125000000E+01 0.6786049580E+00 + 0.1175000000E+01 0.6661069824E+00 + 0.1225000000E+01 0.5397624003E+00 + 0.1275000000E+01 -0.2020829473E-01 + 0.1325000000E+01 -0.2250720675E+00 + 0.1375000000E+01 -0.2166894789E+00 + 0.1425000000E+01 -0.2032813898E+00 + 0.1475000000E+01 -0.1863137042E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt new file mode 100644 index 00000000..abb3d18c --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno2.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3869953761E+00 + -0.1475000000E+01 0.4169194255E+00 + -0.1425000000E+01 0.4469413982E+00 + -0.1375000000E+01 0.4770459572E+00 + -0.1325000000E+01 0.5062530397E+00 + -0.1275000000E+01 0.5341942582E+00 + -0.1225000000E+01 0.5612180194E+00 + -0.1175000000E+01 0.5878990245E+00 + -0.1125000000E+01 0.6146216447E+00 + -0.1075000000E+01 0.6417418513E+00 + -0.1025000000E+01 0.6701424162E+00 + -0.9750000000E+00 0.6966269005E+00 + -0.9250000000E+00 0.7154578360E+00 + -0.8750000000E+00 0.7229834685E+00 + -0.8250000000E+00 0.7226468112E+00 + -0.7750000000E+00 0.6177183553E+00 + -0.7250000000E+00 -0.1196667134E+00 + -0.6750000000E+00 -0.2371902797E+00 + -0.6250000000E+00 -0.2300309096E+00 + -0.5750000000E+00 -0.2109122282E+00 + -0.5250000000E+00 -0.1872517428E+00 + -0.4750000000E+00 -0.1640755253E+00 + -0.4250000000E+00 -0.1409622978E+00 + -0.3750000000E+00 -0.1156962459E+00 + -0.3250000000E+00 -0.8862474712E-01 + -0.2750000000E+00 -0.6163968850E-01 + -0.2250000000E+00 -0.3357086015E-01 + -0.1750000000E+00 -0.4875134725E-02 + -0.1250000000E+00 0.2427735989E-01 + -0.7500000000E-01 0.5369647834E-01 + -0.2500000000E-01 0.8336991079E-01 + 0.2500000000E-01 0.1132766827E+00 + 0.7500000000E-01 0.1433855550E+00 + 0.1250000000E+00 0.1736613168E+00 + 0.1750000000E+00 0.2040776671E+00 + 0.2250000000E+00 0.2346009631E+00 + 0.2750000000E+00 0.2651897403E+00 + 0.3250000000E+00 0.2958737330E+00 + 0.3750000000E+00 0.3266782024E+00 + 0.4250000000E+00 0.3570149022E+00 + 0.4750000000E+00 0.3869953761E+00 + 0.5250000000E+00 0.4169194255E+00 + 0.5750000000E+00 0.4469413982E+00 + 0.6250000000E+00 0.4770459572E+00 + 0.6750000000E+00 0.5062530397E+00 + 0.7250000000E+00 0.5341942582E+00 + 0.7750000000E+00 0.5612180194E+00 + 0.8250000000E+00 0.5878990245E+00 + 0.8750000000E+00 0.6146216447E+00 + 0.9250000000E+00 0.6417418513E+00 + 0.9750000000E+00 0.6701424162E+00 + 0.1025000000E+01 0.6966269005E+00 + 0.1075000000E+01 0.7154578360E+00 + 0.1125000000E+01 0.7229834685E+00 + 0.1175000000E+01 0.7226468112E+00 + 0.1225000000E+01 0.6177183553E+00 + 0.1275000000E+01 -0.1196667134E+00 + 0.1325000000E+01 -0.2371902797E+00 + 0.1375000000E+01 -0.2300309096E+00 + 0.1425000000E+01 -0.2109122282E+00 + 0.1475000000E+01 -0.1872517428E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt new file mode 100644 index 00000000..990cecd5 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno3.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868642875E+00 + -0.1475000000E+01 0.4168486845E+00 + -0.1425000000E+01 0.4465638041E+00 + -0.1375000000E+01 0.4759475543E+00 + -0.1325000000E+01 0.5049291462E+00 + -0.1275000000E+01 0.5334296252E+00 + -0.1225000000E+01 0.5613544319E+00 + -0.1175000000E+01 0.5885832770E+00 + -0.1125000000E+01 0.6149692665E+00 + -0.1075000000E+01 0.6403339550E+00 + -0.1025000000E+01 0.6644774657E+00 + -0.9750000000E+00 0.6872033878E+00 + -0.9250000000E+00 0.7081750801E+00 + -0.8750000000E+00 0.7274800566E+00 + -0.8250000000E+00 0.7397132124E+00 + -0.7750000000E+00 0.6519815577E+00 + -0.7250000000E+00 -0.1542327846E+00 + -0.6750000000E+00 -0.2403632288E+00 + -0.6250000000E+00 -0.2258780818E+00 + -0.5750000000E+00 -0.2076583578E+00 + -0.5250000000E+00 -0.1870168045E+00 + -0.4750000000E+00 -0.1644425502E+00 + -0.4250000000E+00 -0.1403060419E+00 + -0.3750000000E+00 -0.1149259803E+00 + -0.3250000000E+00 -0.8853938919E-01 + -0.2750000000E+00 -0.6131743746E-01 + -0.2250000000E+00 -0.3339869832E-01 + -0.1750000000E+00 -0.4893686380E-02 + -0.1250000000E+00 0.2410314538E-01 + -0.7500000000E-01 0.5348803369E-01 + -0.2500000000E-01 0.8320007249E-01 + 0.2500000000E-01 0.1131807815E+00 + 0.7500000000E-01 0.1433750622E+00 + 0.1250000000E+00 0.1737314324E+00 + 0.1750000000E+00 0.2042014559E+00 + 0.2250000000E+00 0.2347389162E+00 + 0.2750000000E+00 0.2652989314E+00 + 0.3250000000E+00 0.2958370215E+00 + 0.3750000000E+00 0.3263083800E+00 + 0.4250000000E+00 0.3566669371E+00 + 0.4750000000E+00 0.3868642875E+00 + 0.5250000000E+00 0.4168486845E+00 + 0.5750000000E+00 0.4465638041E+00 + 0.6250000000E+00 0.4759475543E+00 + 0.6750000000E+00 0.5049291462E+00 + 0.7250000000E+00 0.5334296252E+00 + 0.7750000000E+00 0.5613544319E+00 + 0.8250000000E+00 0.5885832770E+00 + 0.8750000000E+00 0.6149692665E+00 + 0.9250000000E+00 0.6403339550E+00 + 0.9750000000E+00 0.6644774657E+00 + 0.1025000000E+01 0.6872033878E+00 + 0.1075000000E+01 0.7081750801E+00 + 0.1125000000E+01 0.7274800566E+00 + 0.1175000000E+01 0.7397132124E+00 + 0.1225000000E+01 0.6519815577E+00 + 0.1275000000E+01 -0.1542327846E+00 + 0.1325000000E+01 -0.2403632288E+00 + 0.1375000000E+01 -0.2258780818E+00 + 0.1425000000E+01 -0.2076583578E+00 + 0.1475000000E+01 -0.1870168045E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt new file mode 100644 index 00000000..a1c7a982 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno4.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868411771E+00 + -0.1475000000E+01 0.4168236420E+00 + -0.1425000000E+01 0.4465364676E+00 + -0.1375000000E+01 0.4759171894E+00 + -0.1325000000E+01 0.5048952040E+00 + -0.1275000000E+01 0.5333892034E+00 + -0.1225000000E+01 0.5613037091E+00 + -0.1175000000E+01 0.5885242249E+00 + -0.1125000000E+01 0.6149104174E+00 + -0.1075000000E+01 0.6402843654E+00 + -0.1025000000E+01 0.6644151712E+00 + -0.9750000000E+00 0.6870334937E+00 + -0.9250000000E+00 0.7075915274E+00 + -0.8750000000E+00 0.7260416325E+00 + -0.8250000000E+00 0.7403336059E+00 + -0.7750000000E+00 0.6654229727E+00 + -0.7250000000E+00 -0.1662713613E+00 + -0.6750000000E+00 -0.2401134717E+00 + -0.6250000000E+00 -0.2255829480E+00 + -0.5750000000E+00 -0.2075787414E+00 + -0.5250000000E+00 -0.1869765428E+00 + -0.4750000000E+00 -0.1643954233E+00 + -0.4250000000E+00 -0.1402652374E+00 + -0.3750000000E+00 -0.1148942559E+00 + -0.3250000000E+00 -0.8851131858E-01 + -0.2750000000E+00 -0.6129329546E-01 + -0.2250000000E+00 -0.3338063416E-01 + -0.1750000000E+00 -0.4887861141E-02 + -0.1250000000E+00 0.2408928579E-01 + -0.7500000000E-01 0.5346853666E-01 + -0.2500000000E-01 0.8318001505E-01 + 0.2500000000E-01 0.1131613770E+00 + 0.7500000000E-01 0.1433561374E+00 + 0.1250000000E+00 0.1737124894E+00 + 0.1750000000E+00 0.2041821994E+00 + 0.2250000000E+00 0.2347193748E+00 + 0.2750000000E+00 0.2652792397E+00 + 0.3250000000E+00 0.2958171038E+00 + 0.3750000000E+00 0.3262878842E+00 + 0.4250000000E+00 0.3566453650E+00 + 0.4750000000E+00 0.3868411771E+00 + 0.5250000000E+00 0.4168236420E+00 + 0.5750000000E+00 0.4465364676E+00 + 0.6250000000E+00 0.4759171894E+00 + 0.6750000000E+00 0.5048952040E+00 + 0.7250000000E+00 0.5333892034E+00 + 0.7750000000E+00 0.5613037091E+00 + 0.8250000000E+00 0.5885242249E+00 + 0.8750000000E+00 0.6149104174E+00 + 0.9250000000E+00 0.6402843654E+00 + 0.9750000000E+00 0.6644151712E+00 + 0.1025000000E+01 0.6870334937E+00 + 0.1075000000E+01 0.7075915274E+00 + 0.1125000000E+01 0.7260416325E+00 + 0.1175000000E+01 0.7403336059E+00 + 0.1225000000E+01 0.6654229727E+00 + 0.1275000000E+01 -0.1662713613E+00 + 0.1325000000E+01 -0.2401134717E+00 + 0.1375000000E+01 -0.2255829480E+00 + 0.1425000000E+01 -0.2075787414E+00 + 0.1475000000E+01 -0.1869765428E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt new file mode 100644 index 00000000..39b7457b --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno5.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868395234E+00 + -0.1475000000E+01 0.4168214927E+00 + -0.1425000000E+01 0.4465338877E+00 + -0.1375000000E+01 0.4759141663E+00 + -0.1325000000E+01 0.5048916070E+00 + -0.1275000000E+01 0.5333847709E+00 + -0.1225000000E+01 0.5612980406E+00 + -0.1175000000E+01 0.5885167892E+00 + -0.1125000000E+01 0.6149004218E+00 + -0.1075000000E+01 0.6402720415E+00 + -0.1025000000E+01 0.6644016921E+00 + -0.9750000000E+00 0.6869917808E+00 + -0.9250000000E+00 0.7075737293E+00 + -0.8750000000E+00 0.7256981164E+00 + -0.8250000000E+00 0.7401377007E+00 + -0.7750000000E+00 0.6729567942E+00 + -0.7250000000E+00 -0.1730889524E+00 + -0.6750000000E+00 -0.2402469630E+00 + -0.6250000000E+00 -0.2255384038E+00 + -0.5750000000E+00 -0.2075674444E+00 + -0.5250000000E+00 -0.1869675885E+00 + -0.4750000000E+00 -0.1643888705E+00 + -0.4250000000E+00 -0.1402608200E+00 + -0.3750000000E+00 -0.1148911193E+00 + -0.3250000000E+00 -0.8850907058E-01 + -0.2750000000E+00 -0.6129169639E-01 + -0.2250000000E+00 -0.3337964815E-01 + -0.1750000000E+00 -0.4887557395E-02 + -0.1250000000E+00 0.2408892100E-01 + -0.7500000000E-01 0.5346824771E-01 + -0.2500000000E-01 0.8317964560E-01 + 0.2500000000E-01 0.1131613563E+00 + 0.7500000000E-01 0.1433564991E+00 + 0.1250000000E+00 0.1737128807E+00 + 0.1750000000E+00 0.2041824417E+00 + 0.2250000000E+00 0.2347195521E+00 + 0.2750000000E+00 0.2652793505E+00 + 0.3250000000E+00 0.2958169883E+00 + 0.3750000000E+00 0.3262873440E+00 + 0.4250000000E+00 0.3566442736E+00 + 0.4750000000E+00 0.3868395234E+00 + 0.5250000000E+00 0.4168214927E+00 + 0.5750000000E+00 0.4465338877E+00 + 0.6250000000E+00 0.4759141663E+00 + 0.6750000000E+00 0.5048916070E+00 + 0.7250000000E+00 0.5333847709E+00 + 0.7750000000E+00 0.5612980406E+00 + 0.8250000000E+00 0.5885167892E+00 + 0.8750000000E+00 0.6149004218E+00 + 0.9250000000E+00 0.6402720415E+00 + 0.9750000000E+00 0.6644016921E+00 + 0.1025000000E+01 0.6869917808E+00 + 0.1075000000E+01 0.7075737293E+00 + 0.1125000000E+01 0.7256981164E+00 + 0.1175000000E+01 0.7401377007E+00 + 0.1225000000E+01 0.6729567942E+00 + 0.1275000000E+01 -0.1730889524E+00 + 0.1325000000E+01 -0.2402469630E+00 + 0.1375000000E+01 -0.2255384038E+00 + 0.1425000000E+01 -0.2075674444E+00 + 0.1475000000E+01 -0.1869675885E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt new file mode 100644 index 00000000..889c1555 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno6.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868392085E+00 + -0.1475000000E+01 0.4168213307E+00 + -0.1425000000E+01 0.4465337167E+00 + -0.1375000000E+01 0.4759138544E+00 + -0.1325000000E+01 0.5048910997E+00 + -0.1275000000E+01 0.5333840599E+00 + -0.1225000000E+01 0.5612971006E+00 + -0.1175000000E+01 0.5885155255E+00 + -0.1125000000E+01 0.6148986459E+00 + -0.1075000000E+01 0.6402694620E+00 + -0.1025000000E+01 0.6643984579E+00 + -0.9750000000E+00 0.6869810297E+00 + -0.9250000000E+00 0.7075737507E+00 + -0.8750000000E+00 0.7256087468E+00 + -0.8250000000E+00 0.7400298908E+00 + -0.7750000000E+00 0.6774720179E+00 + -0.7250000000E+00 -0.1775213300E+00 + -0.6750000000E+00 -0.2401222009E+00 + -0.6250000000E+00 -0.2255340650E+00 + -0.5750000000E+00 -0.2075635018E+00 + -0.5250000000E+00 -0.1869654336E+00 + -0.4750000000E+00 -0.1643875389E+00 + -0.4250000000E+00 -0.1402599982E+00 + -0.3750000000E+00 -0.1148905767E+00 + -0.3250000000E+00 -0.8850868906E-01 + -0.2750000000E+00 -0.6129141337E-01 + -0.2250000000E+00 -0.3337945810E-01 + -0.1750000000E+00 -0.4887493661E-02 + -0.1250000000E+00 0.2408884668E-01 + -0.7500000000E-01 0.5346812259E-01 + -0.2500000000E-01 0.8317978735E-01 + 0.2500000000E-01 0.1131612490E+00 + 0.7500000000E-01 0.1433561731E+00 + 0.1250000000E+00 0.1737128044E+00 + 0.1750000000E+00 0.2041828013E+00 + 0.2250000000E+00 0.2347198794E+00 + 0.2750000000E+00 0.2652792412E+00 + 0.3250000000E+00 0.2958164417E+00 + 0.3750000000E+00 0.3262866535E+00 + 0.4250000000E+00 0.3566437225E+00 + 0.4750000000E+00 0.3868392085E+00 + 0.5250000000E+00 0.4168213307E+00 + 0.5750000000E+00 0.4465337167E+00 + 0.6250000000E+00 0.4759138544E+00 + 0.6750000000E+00 0.5048910997E+00 + 0.7250000000E+00 0.5333840599E+00 + 0.7750000000E+00 0.5612971006E+00 + 0.8250000000E+00 0.5885155255E+00 + 0.8750000000E+00 0.6148986459E+00 + 0.9250000000E+00 0.6402694620E+00 + 0.9750000000E+00 0.6643984579E+00 + 0.1025000000E+01 0.6869810297E+00 + 0.1075000000E+01 0.7075737507E+00 + 0.1125000000E+01 0.7256087468E+00 + 0.1175000000E+01 0.7400298908E+00 + 0.1225000000E+01 0.6774720179E+00 + 0.1275000000E+01 -0.1775213300E+00 + 0.1325000000E+01 -0.2401222009E+00 + 0.1375000000E+01 -0.2255340650E+00 + 0.1425000000E+01 -0.2075635018E+00 + 0.1475000000E+01 -0.1869654336E+00 diff --git a/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt b/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt new file mode 100644 index 00000000..24393a34 --- /dev/null +++ b/example/burgers/inviscid-1d/data_compare/solution_total_eno7.plt @@ -0,0 +1,61 @@ + -0.1525000000E+01 0.3868392635E+00 + -0.1475000000E+01 0.4168213348E+00 + -0.1425000000E+01 0.4465336993E+00 + -0.1375000000E+01 0.4759138410E+00 + -0.1325000000E+01 0.5048910758E+00 + -0.1275000000E+01 0.5333839905E+00 + -0.1225000000E+01 0.5612969697E+00 + -0.1175000000E+01 0.5885153145E+00 + -0.1125000000E+01 0.6148982967E+00 + -0.1075000000E+01 0.6402688560E+00 + -0.1025000000E+01 0.6643975691E+00 + -0.9750000000E+00 0.6869777983E+00 + -0.9250000000E+00 0.7075740090E+00 + -0.8750000000E+00 0.7255780485E+00 + -0.8250000000E+00 0.7399754487E+00 + -0.7750000000E+00 0.6810919060E+00 + -0.7250000000E+00 -0.1811233524E+00 + -0.6750000000E+00 -0.2400531259E+00 + -0.6250000000E+00 -0.2255337663E+00 + -0.5750000000E+00 -0.2075620178E+00 + -0.5250000000E+00 -0.1869648182E+00 + -0.4750000000E+00 -0.1643872091E+00 + -0.4250000000E+00 -0.1402598192E+00 + -0.3750000000E+00 -0.1148904706E+00 + -0.3250000000E+00 -0.8850862004E-01 + -0.2750000000E+00 -0.6129137302E-01 + -0.2250000000E+00 -0.3337943999E-01 + -0.1750000000E+00 -0.4887482940E-02 + -0.1250000000E+00 0.2408884789E-01 + -0.7500000000E-01 0.5346811667E-01 + -0.2500000000E-01 0.8317978567E-01 + 0.2500000000E-01 0.1131612536E+00 + 0.7500000000E-01 0.1433561665E+00 + 0.1250000000E+00 0.1737128227E+00 + 0.1750000000E+00 0.2041827929E+00 + 0.2250000000E+00 0.2347198883E+00 + 0.2750000000E+00 0.2652792582E+00 + 0.3250000000E+00 0.2958164964E+00 + 0.3750000000E+00 0.3262867483E+00 + 0.4250000000E+00 0.3566438179E+00 + 0.4750000000E+00 0.3868392635E+00 + 0.5250000000E+00 0.4168213348E+00 + 0.5750000000E+00 0.4465336993E+00 + 0.6250000000E+00 0.4759138410E+00 + 0.6750000000E+00 0.5048910758E+00 + 0.7250000000E+00 0.5333839905E+00 + 0.7750000000E+00 0.5612969697E+00 + 0.8250000000E+00 0.5885153145E+00 + 0.8750000000E+00 0.6148982967E+00 + 0.9250000000E+00 0.6402688560E+00 + 0.9750000000E+00 0.6643975691E+00 + 0.1025000000E+01 0.6869777983E+00 + 0.1075000000E+01 0.7075740090E+00 + 0.1125000000E+01 0.7255780485E+00 + 0.1175000000E+01 0.7399754487E+00 + 0.1225000000E+01 0.6810919060E+00 + 0.1275000000E+01 -0.1811233524E+00 + 0.1325000000E+01 -0.2400531259E+00 + 0.1375000000E+01 -0.2255337663E+00 + 0.1425000000E+01 -0.2075620178E+00 + 0.1475000000E+01 -0.1869648182E+00 diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/README.txt b/example/burgers/inviscid-1d/eno1/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..b02416dc --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/enoburgers.f90 @@ -0,0 +1,284 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 1 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.0d0, 1.0d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/fortran/01/plot.py b/example/burgers/inviscid-1d/eno1/fortran/01/plot.py new file mode 100644 index 00000000..19756784 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/fortran/01/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno1") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno1/julia/01/eno.jl b/example/burgers/inviscid-1d/eno1/julia/01/eno.jl new file mode 100644 index 00000000..ff4ffc1a --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/julia/01/eno.jl @@ -0,0 +1,206 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 1 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing where needed +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) # Adjusted to 0-based +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) # Corrected to 0-based +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Corrected to match Python’s 0-based dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 # Adjusted from 2:iorder since m starts at 1 in Python + for j in 1:ntcell-1 # Adjusted from 2:ntcell-1 to match Python’s 1:ntcell + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 # Adjusted from 2:iorder + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 1.0 ] + coef[1, :] = [ 1.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/julia/01/plot.py b/example/burgers/inviscid-1d/eno1/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01/eno.py b/example/burgers/inviscid-1d/eno1/python/01/eno.py new file mode 100644 index 00000000..978fe40d --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01/eno.py @@ -0,0 +1,169 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 1 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01/plot.py b/example/burgers/inviscid-1d/eno1/python/01/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01a/eno.py b/example/burgers/inviscid-1d/eno1/python/01a/eno.py new file mode 100644 index 00000000..c1571b74 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01a/eno.py @@ -0,0 +1,169 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01a/plot.py b/example/burgers/inviscid-1d/eno1/python/01a/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01a/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01b/eno.py b/example/burgers/inviscid-1d/eno1/python/01b/eno.py new file mode 100644 index 00000000..93b35c05 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01b/eno.py @@ -0,0 +1,166 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01b/plot.py b/example/burgers/inviscid-1d/eno1/python/01b/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01b/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01c/eno.py b/example/burgers/inviscid-1d/eno1/python/01c/eno.py new file mode 100644 index 00000000..751fe6ab --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01c/eno.py @@ -0,0 +1,198 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + #dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + #ighost = 2 + #ishift = ighost + 1=3 + #i=0,1,...,nx + #i+ishift=3,4,...,nx+3 + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + #i=0,1,...,nx + #i+ishift=3,4,...,nx+3 + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + #print(f'l1={l1},l2={l2},k1={k1},k2={k2},i={i}') + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost=2,-ighost=-2 + #ishift = ighost + 1=3 + #ist = 1 + ishift + #ied = nx + ishift + #i=-2,-1,0 + #ishift+i=3-2,3-1,3+0=1,2,3 + #ied + i=ied-2,ied-1,ied+0 + #ist=ishift + #ied=nx-1+ishift + #ist-1=2 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #i=1,2 + #ied+i=ied+1,ied+2 + #ist-1=2 + #ist-1+i=3,4 + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +#ighost = iorder +ighost = 2 +ishift = ighost + 1 +#ist = 1 + ishift +#ied = nx + ishift +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +#dd = np.zeros((ighost, ntcell + 1)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01c/plot.py b/example/burgers/inviscid-1d/eno1/python/01c/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01c/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01d/eno.py b/example/burgers/inviscid-1d/eno1/python/01d/eno.py new file mode 100644 index 00000000..d3ea1be8 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01d/eno.py @@ -0,0 +1,185 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost=2,-ighost=-2 + #ishift = ighost + 1=3 + #ist = 1 + ishift + #ied = nx + ishift + #i=-2,-1,0 + #ishift+i=3-2,3-1,3+0=1,2,3 + #ied + i=ied-2,ied-1,ied+0 + #ist=ishift + #ied=nx-1+ishift + #ist-1=2 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #i=1,2 + #ied+i=ied+1,ied+2 + #ist-1=2 + #ist-1+i=3,4 + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/01d/plot.py b/example/burgers/inviscid-1d/eno1/python/01d/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/01d/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/02/eno.py b/example/burgers/inviscid-1d/eno1/python/02/eno.py new file mode 100644 index 00000000..71b6fef1 --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/02/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + #for j in range(1, ntcell): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + #ighost = 2 + #i=-2,-1,0 + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + #ighost = 2 + #i=1,2,3 + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [1.0] + coef[1] = [1.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 1 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno1/python/02/plot.py b/example/burgers/inviscid-1d/eno1/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno1/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..471acb82 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 new file mode 100644 index 00000000..4fc96f70 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: pu(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, pu, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), pu(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = pu( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + call update_oldfield(un, pu, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(pu) + do i = 1, nx + pu(i) = pu(i) + dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call residual(pu) + + do i = 1, nx + pu(i) = 0.75 * un(i) + 0.25 * pu(i) + 0.25 * dt * res(i) + enddo + + call boundary( pu, nx, ighost ) + + call residual(pu) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + pu(i) = c1 * un(i) + c2 * pu(i) + c3 * dt * res(i) + enddo + call boundary( pu, nx, ighost ) + + call update_oldfield(un, pu, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),pu(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01a/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 new file mode 100644 index 00000000..e3a08d37 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/enoburgers.f90 @@ -0,0 +1,265 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer il(0:nx),ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: nx, ighost + implicit none + real(8) :: x(-ighost:nx+ighost) +endmodule mesh_module + +module field_module + use global, only: nx, ighost + implicit none + real(8) :: u(-ighost:nx+ighost), un(-ighost:nx+ighost) +endmodule field_module + +subroutine residual(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer i + + call reconstruction(u) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(u) + use global + implicit none + real(8) :: u(-ighost:nx+ighost) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = -ighost, nx + ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +subroutine update_oldfield(un, u, nx, ighost) + implicit none + integer :: nx, ighost + real(8) :: un(-ighost:nx+ighost), u(-ighost:nx+ighost) + integer :: i + + do i = -ighost, nx + ighost + un( i ) = u( i ) + enddo +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + + do i = -ighost, nx + ighost + x(i) = ( i - 1 ) * dx + dx/2 - 1.0 + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = 1, nx + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u, nx, ighost ) + call update_oldfield(un, u, nx, ighost) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + u(i) = u(i) + dt * res(i) + enddo + call boundary( u, nx, ighost ) + + call residual(u) + + do i = 1, nx + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u, nx, ighost ) + + call residual(u) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u, nx, ighost ) + + call update_oldfield(un, u, nx, ighost) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = -ighost, nx + ighost + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = 1, nx + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01b/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 new file mode 100644 index 00000000..ad471194 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/enoburgers.f90 @@ -0,0 +1,272 @@ +module global + implicit none + !integer, parameter :: nx = 40 + integer, parameter :: nx = 10 + !integer, parameter :: ighost = 10 + integer, parameter :: ighost = 2 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + real(8) :: res(ist:ied) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux,nx) + do i = ist, ied + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux,nx) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i, nx + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + implicit none + real(8),dimension(:) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + u(i) = u(i) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01c/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 new file mode 100644 index 00000000..e82b32bb --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/enoburgers.f90 @@ -0,0 +1,271 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + real(8) :: res(ist:ied) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + u(i) = u(i) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01d/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 new file mode 100644 index 00000000..faa4d065 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + !real(8) :: res(ist:ied) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(ist-1:ied) + integer :: i + + do i = ist-1, ied + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01e/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 new file mode 100644 index 00000000..d4f2b30e --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(ii) - flux(ii-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+q(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(ist-1:ied), up1_2p(ist-1:ied), flux(0:nx) + integer :: i, ii + + do i = ist-1, ied + ii = i - ist + 1 + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(ii) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(ii) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(ii) = 0 + else + flux(ii) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01f/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 new file mode 100644 index 00000000..d9e8ebe9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/enoburgers.f90 @@ -0,0 +1,278 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = ist, ied + ii = i - ist + 1 + res(ii) = - ( flux(ii) - flux(ii-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i, ii + + do i = ist-1, ied + ii = i - ist + 1 + if ( up1_2m(ii) >= 0 ) then + if ( up1_2p(ii) >= 0 ) then + flux(ii) = 0.5 * up1_2m(ii) * up1_2m(ii) + else + flux(ii) = 0.5 * ( up1_2m(ii) * up1_2m(ii) + up1_2p(ii) * up1_2p(ii) ) + endif + else + if ( up1_2p(ii) >= 0 ) then + flux(ii) = 0 + else + flux(ii) = 0.5 * up1_2p(ii) * up1_2p(ii) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01g/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 new file mode 100644 index 00000000..7837f05f --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, ii + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii + real(8) :: c1, c2, c3 + + call residual(u) + do i = ist, ied + ii = i - ist + 1 + u(i) = u(i) + dt * res(ii) + enddo + call boundary( u ) + + call residual(u) + + do i = ist, ied + ii = i - ist + 1 + u(i) = 0.75 * un(i) + 0.25 * u(i) + 0.25 * dt * res(ii) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = ist, ied + ii = i - ist + 1 + u(i) = c1 * un(i) + c2 * u(i) + c3 * dt * res(ii) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01h/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 new file mode 100644 index 00000000..3019cd63 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/enoburgers.f90 @@ -0,0 +1,279 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(ist-1:ied),ir(ist-1:ied) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj + + !chose the stencil by ENO method + do j=1,ntcell + dd(0,j) = q(j) + enddo + do i=1,iorder-1 + do j=1,ntcell-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j = ist-1, ied + il(j) = j + ir(j) = j + 1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=ist-1, ied + k1=il(j) + k2=ir(j) + l1=j-k1+1 + l2=j-k2+1 + jj = j - ( ist - 1 ) + up1_2m(jj)=0 + up1_2p(jj)=0 + do m=0,iorder-1 + up1_2m(jj)=up1_2m(jj)+q(k1+m)*coef(l1,m) + up1_2p(jj)=up1_2p(jj)+q(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01i/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 new file mode 100644 index 00000000..a0bdcc18 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/enoburgers.f90 @@ -0,0 +1,279 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + integer :: jj, kk, k + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do k = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(k,j) = dd(k-1,j+1)-dd(k-1,j) + enddo + enddo + + do i = 0, nx + j = i + ist - 1 + il(i) = j + ir(i) = j + 1 + do k=1,iorder-1 + if ( abs(dd(k,il(i)-1)) <= abs(dd(k,il(i))) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(k,ir(i)-1)) <= abs(dd(k,ir(i))) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + j = i + ist - 1 + k1 = il(i) + k2 = ir(i) + l1 = j - k1 + 1 + l2 = j - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + x(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, ii, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = ist + i - 1 + ii = i - ist + 1 + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = ist + i - 1 + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = ist + i - 1 + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) x(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) x(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01j/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 new file mode 100644 index 00000000..c80fdaa5 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/enoburgers.f90 @@ -0,0 +1,276 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx, dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: x(1:ntcell) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ist - 1 + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ist - 1 + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i, ii + + do i = -ighost, nx + ighost + ii = i + ighost + 1 + xcc(ii) = ( i - 1 ) * dx + dx/2 - 1.0 + !write(*,*)'i=',i,'ii=',ii + enddo + + i = 0 + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 1, nx + j = i + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 1, nx + j = i + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 1, nx + j = i + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + dx = 2.0 / nx + dt = dx * 0.5 + write(*,*) 'Input T:' + read(*,*) simu_time + + call init_coef() + call init_mesh() + call init_field() + + t = 0 + do while( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01k/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt b/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 new file mode 100644 index 00000000..a667919a --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/enoburgers.f90 @@ -0,0 +1,284 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py b/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/01l/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt b/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/README.txt b/example/burgers/inviscid-1d/eno2/fortran/02/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 b/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 new file mode 100644 index 00000000..723e75eb --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/enoburgers.f90 @@ -0,0 +1,286 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [ 1.5d0, -0.5d0, & + 0.5d0, 0.5d0, & + -0.5d0, 1.5d0 ] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/fortran/02/plot.py b/example/burgers/inviscid-1d/eno2/fortran/02/plot.py new file mode 100644 index 00000000..a21732cd --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/fortran/02/plot.py @@ -0,0 +1,42 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno2") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() + + +plt.show(); + + diff --git a/example/burgers/inviscid-1d/eno2/julia/01/eno.jl b/example/burgers/inviscid-1d/eno2/julia/01/eno.jl new file mode 100644 index 00000000..448367b9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/julia/01/eno.jl @@ -0,0 +1,207 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 2 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 3.0/2.0, -1.0/2.0 ] + coef[1, :] = [ 3.0/2.0, -1.0/2.0 ] + coef[2, :] = [ -1.0/2.0, 3.0/2.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/julia/01/plot.py b/example/burgers/inviscid-1d/eno2/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/01/eno.py b/example/burgers/inviscid-1d/eno2/python/01/eno.py new file mode 100644 index 00000000..23773a74 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/01/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 2 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/01/plot.py b/example/burgers/inviscid-1d/eno2/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/02/eno.py b/example/burgers/inviscid-1d/eno2/python/02/eno.py new file mode 100644 index 00000000..dba66619 --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/02/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 2 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/02/plot.py b/example/burgers/inviscid-1d/eno2/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/03/eno.py b/example/burgers/inviscid-1d/eno2/python/03/eno.py new file mode 100644 index 00000000..a00eee5e --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/03/eno.py @@ -0,0 +1,171 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [3.0/2.0, -1.0/2.0] + coef[1] = [1.0/2.0, 1.0/2.0] + coef[2] = [-1.0/2.0, 3.0/2.0] +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 2 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno2/python/03/plot.py b/example/burgers/inviscid-1d/eno2/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno2/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/README.txt b/example/burgers/inviscid-1d/eno3/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..5ceb9b39 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/enoburgers.f90 @@ -0,0 +1,287 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 3 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + real(8) :: values(isize) = [ 1.8333333333333333d0, -1.1666666666666667d0, 0.3333333333333333d0, & + 0.3333333333333333d0, 0.8333333333333333d0, -0.1666666666666667d0, & + -0.1666666666666667d0, 0.8333333333333333d0, 0.3333333333333333d0, & + 0.3333333333333333d0, -1.1666666666666667d0, 1.8333333333333333d0 ] + integer :: i, j, icount + + icount = 1 + do i = 0, iorder + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/fortran/01/plot.py b/example/burgers/inviscid-1d/eno3/fortran/01/plot.py new file mode 100644 index 00000000..6bf2c013 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno3") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/julia/01/eno.jl b/example/burgers/inviscid-1d/eno3/julia/01/eno.jl new file mode 100644 index 00000000..76f0287e --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/julia/01/eno.jl @@ -0,0 +1,208 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 3 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1, :] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2, :] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3, :] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/julia/01/plot.py b/example/burgers/inviscid-1d/eno3/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/01/eno.py b/example/burgers/inviscid-1d/eno3/python/01/eno.py new file mode 100644 index 00000000..2e40a3e2 --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/01/eno.py @@ -0,0 +1,172 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 3 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/01/plot.py b/example/burgers/inviscid-1d/eno3/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/02/eno.py b/example/burgers/inviscid-1d/eno3/python/02/eno.py new file mode 100644 index 00000000..a52aadec --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/02/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 3 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/02/plot.py b/example/burgers/inviscid-1d/eno3/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/03/eno.py b/example/burgers/inviscid-1d/eno3/python/03/eno.py new file mode 100644 index 00000000..429bb23c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/03/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 11.0/6.0, -7.0/6.0, 1.0/3.0 ] + coef[1] = [ 1.0/3.0, 5.0/6.0, -1.0/6.0 ] + coef[2] = [ -1.0/6.0, 5.0/6.0, 1.0/3.0 ] + coef[3] = [ 1.0/3.0, -7.0/6.0, 11.0/6.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 3 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno3/python/03/plot.py b/example/burgers/inviscid-1d/eno3/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno3/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/README.txt b/example/burgers/inviscid-1d/eno4/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..d535b2e4 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/enoburgers.f90 @@ -0,0 +1,299 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 4 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 25.0/12.0 + coef(0, 1) = -23.0/12.0 + coef(0, 2) = 13.0/12.0 + coef(0, 3) = -1.0/4.0 + + coef(1, 0) = 1.0/4.0 + coef(1, 1) = 13.0/12.0 + coef(1, 2) = -5.0/12.0 + coef(1, 3) = 1.0/12.0 + + coef(2, 0) = -1.0/12.0 + coef(2, 1) = 7.0/12.0 + coef(2, 2) = 7.0/12.0 + coef(2, 3) = -1.0/12.0 + + coef(3, 0) = 1.0/12.0 + coef(3, 1) = -5.0/12.0 + coef(3, 2) = 13.0/12.0 + coef(3, 3) = 1.0/4.0 + + coef(4, 0) = -1.0/4.0 + coef(4, 1) = 13.0/12.0 + coef(4, 2) = -23.0/12.0 + coef(4, 3) = 25.0/12.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/fortran/01/plot.py b/example/burgers/inviscid-1d/eno4/fortran/01/plot.py new file mode 100644 index 00000000..775b3197 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno4") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/julia/01/eno.jl b/example/burgers/inviscid-1d/eno4/julia/01/eno.jl new file mode 100644 index 00000000..732efdbb --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/julia/01/eno.jl @@ -0,0 +1,209 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 4 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1, :] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2, :] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3, :] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4, :] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/julia/01/plot.py b/example/burgers/inviscid-1d/eno4/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/01/eno.py b/example/burgers/inviscid-1d/eno4/python/01/eno.py new file mode 100644 index 00000000..55ed295a --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/01/eno.py @@ -0,0 +1,173 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 4 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/01/plot.py b/example/burgers/inviscid-1d/eno4/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/02/eno.py b/example/burgers/inviscid-1d/eno4/python/02/eno.py new file mode 100644 index 00000000..05d93bac --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/02/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 4 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/02/plot.py b/example/burgers/inviscid-1d/eno4/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/03/eno.py b/example/burgers/inviscid-1d/eno4/python/03/eno.py new file mode 100644 index 00000000..9b7565c7 --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/03/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 25.0/12.0, -23.0/12.0, 13.0/12.0, -1.0/4.0 ] + coef[1] = [ 1.0/4.0, 13.0/12.0, -5.0/12.0, 1.0/12.0 ] + coef[2] = [ -1.0/12.0, 7.0/12.0, 7.0/12.0, -1.0/12.0 ] + coef[3] = [ 1.0/12.0, -5.0/12.0, 13.0/12.0, 1.0/4.0 ] + coef[4] = [ -1.0/4.0, 13.0/12.0, -23.0/12.0, 25.0/12.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 4 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno4/python/03/plot.py b/example/burgers/inviscid-1d/eno4/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno4/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/README.txt b/example/burgers/inviscid-1d/eno5/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..54c0a730 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/enoburgers.f90 @@ -0,0 +1,310 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 5 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 137.0/60.0 + coef(0, 1) = -163.0/60.0 + coef(0, 2) = 137.0/60.0 + coef(0, 3) = -21.0/20.0 + coef(0, 4) = 1.0/5.0 + + coef(1, 0) = 1.0/5.0 + coef(1, 1) = 77.0/60.0 + coef(1, 2) = -43.0/60.0 + coef(1, 3) = 17.0/60.0 + coef(1, 4) = -1.0/20.0 + + coef(2, 0) = -1.0/20.0 + coef(2, 1) = 9.0/20.0 + coef(2, 2) = 47.0/60.0 + coef(2, 3) = -13.0/60.0 + coef(2, 4) = 1.0/30.0 + + coef(3, 0) = 1.0/30.0 + coef(3, 1) = -13.0/60.0 + coef(3, 2) = 47.0/60.0 + coef(3, 3) = 9.0/20.0 + coef(3, 4) = -1.0/20.0 + + coef(4, 0) = -1.0/20.0 + coef(4, 1) = 17.0/60.0 + coef(4, 2) = -43.0/60.0 + coef(4, 3) = 77.0/60.0 + coef(4, 4) = 1.0/5.0 + + coef(5, 0) = 1.0/5.0 + coef(5, 1) = -21.0/20.0 + coef(5, 2) = 137.0/60.0 + coef(5, 3) = -163.0/60.0 + coef(5, 4) = 137.0/60.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/fortran/01/plot.py b/example/burgers/inviscid-1d/eno5/fortran/01/plot.py new file mode 100644 index 00000000..87eef54f --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno5") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/julia/01/eno.jl b/example/burgers/inviscid-1d/eno5/julia/01/eno.jl new file mode 100644 index 00000000..74516595 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/julia/01/eno.jl @@ -0,0 +1,210 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 5 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1, :] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2, :] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3, :] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4, :] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5, :] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/julia/01/plot.py b/example/burgers/inviscid-1d/eno5/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/01/eno.py b/example/burgers/inviscid-1d/eno5/python/01/eno.py new file mode 100644 index 00000000..863aaea0 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/01/eno.py @@ -0,0 +1,174 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 5 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/01/plot.py b/example/burgers/inviscid-1d/eno5/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/02/eno.py b/example/burgers/inviscid-1d/eno5/python/02/eno.py new file mode 100644 index 00000000..badae66e --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/02/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 5 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/02/plot.py b/example/burgers/inviscid-1d/eno5/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/03/eno.py b/example/burgers/inviscid-1d/eno5/python/03/eno.py new file mode 100644 index 00000000..ee7fc9f1 --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/03/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 137.0/60.0, -163.0/60.0, 137.0/60.0, -21.0/20.0, 1.0/5.0 ] + coef[1] = [ 1.0/5.0, 77.0/60.0, -43.0/60.0, 17.0/60.0, -1.0/20.0 ] + coef[2] = [ -1.0/20.0, 9.0/20.0, 47.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[3] = [ 1.0/30.0, -13.0/60.0, 47.0/60.0, 9.0/20.0, -1.0/20.0 ] + coef[4] = [ -1.0/20.0, 17.0/60.0, -43.0/60.0, 77.0/60.0, 1.0/5.0 ] + coef[5] = [ 1.0/5.0, -21.0/20.0, 137.0/60.0, -163.0/60.0, 137.0/60.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 5 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno5/python/03/plot.py b/example/burgers/inviscid-1d/eno5/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno5/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/README.txt b/example/burgers/inviscid-1d/eno6/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..d262981b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/enoburgers.f90 @@ -0,0 +1,323 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 6 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 49.0/20.0 + coef(0, 1) = -71.0/20.0 + coef(0, 2) = 79.0/20.0 + coef(0, 3) = -163.0/60.0 + coef(0, 4) = 31.0/30.0 + coef(0, 5) = -1.0/6.0 + + coef(1, 0) = 1.0/6.0 + coef(1, 1) = 29.0/20.0 + coef(1, 2) = -21.0/20.0 + coef(1, 3) = 37.0/60.0 + coef(1, 4) = -13.0/60.0 + coef(1, 5) = 1.0/30.0 + + coef(2, 0) = -1.0/30.0 + coef(2, 1) = 11.0/30.0 + coef(2, 2) = 19.0/20.0 + coef(2, 3) = -23.0/60.0 + coef(2, 4) = 7.0/60.0 + coef(2, 5) = -1.0/60.0 + + coef(3, 0) = 1.0/60.0 + coef(3, 1) = -2.0/15.0 + coef(3, 2) = 37.0/60.0 + coef(3, 3) = 37.0/60.0 + coef(3, 4) = -2.0/15.0 + coef(3, 5) = 1.0/60.0 + + coef(4, 0) = -1.0/60.0 + coef(4, 1) = 7.0/60.0 + coef(4, 2) = -23.0/60.0 + coef(4, 3) = 19.0/20.0 + coef(4, 4) = 11.0/30.0 + coef(4, 5) = -1.0/30.0 + + coef(5, 0) = 1.0/30.0 + coef(5, 1) = -13.0/60.0 + coef(5, 2) = 37.0/60.0 + coef(5, 3) = -21.0/20.0 + coef(5, 4) = 29.0/20.0 + coef(5, 5) = 1.0/6.0 + + coef(6, 0) = -1.0/6.0 + coef(6, 1) = 31.0/30.0 + coef(6, 2) = -163.0/60.0 + coef(6, 3) = 79.0/20.0 + coef(6, 4) = -71.0/20.0 + coef(6, 5) = 49.0/20.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/fortran/01/plot.py b/example/burgers/inviscid-1d/eno6/fortran/01/plot.py new file mode 100644 index 00000000..ca0edf79 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno6") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/julia/01/eno.jl b/example/burgers/inviscid-1d/eno6/julia/01/eno.jl new file mode 100644 index 00000000..922a07d8 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/julia/01/eno.jl @@ -0,0 +1,211 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 6 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1, :] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2, :] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3, :] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4, :] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5, :] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6, :] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/julia/01/plot.py b/example/burgers/inviscid-1d/eno6/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/01/eno.py b/example/burgers/inviscid-1d/eno6/python/01/eno.py new file mode 100644 index 00000000..19e34aeb --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/01/eno.py @@ -0,0 +1,175 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 6 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/01/plot.py b/example/burgers/inviscid-1d/eno6/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/02/eno.py b/example/burgers/inviscid-1d/eno6/python/02/eno.py new file mode 100644 index 00000000..f9908e96 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/02/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 6 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/02/plot.py b/example/burgers/inviscid-1d/eno6/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/03/eno.py b/example/burgers/inviscid-1d/eno6/python/03/eno.py new file mode 100644 index 00000000..0a3b3446 --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/03/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 49.0/20.0, -71.0/20.0, 79.0/20.0, -163.0/60.0, 31.0/30.0, -1.0/6.0 ] + coef[1] = [ 1.0/6.0, 29.0/20.0, -21.0/20.0, 37.0/60.0, -13.0/60.0, 1.0/30.0 ] + coef[2] = [ -1.0/30.0, 11.0/30.0, 19.0/20.0, -23.0/60.0, 7.0/60.0, -1.0/60.0 ] + coef[3] = [ 1.0/60.0, -2.0/15.0, 37.0/60.0, 37.0/60.0, -2.0/15.0, 1.0/60.0 ] + coef[4] = [ -1.0/60.0, 7.0/60.0, -23.0/60.0, 19.0/20.0, 11.0/30.0, -1.0/30.0 ] + coef[5] = [ 1.0/30.0, -13.0/60.0, 37.0/60.0, -21.0/20.0, 29.0/20.0, 1.0/6.0 ] + coef[6] = [ -1.0/6.0, 31.0/30.0, -163.0/60.0, 79.0/20.0, -71.0/20.0, 49.0/20.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 6 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno6/python/03/plot.py b/example/burgers/inviscid-1d/eno6/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno6/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt b/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/README.txt b/example/burgers/inviscid-1d/eno7/fortran/01/README.txt new file mode 100644 index 00000000..9d453dd9 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/README.txt @@ -0,0 +1 @@ +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 b/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..5dab972d --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/enoburgers.f90 @@ -0,0 +1,338 @@ +module global + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 7 + integer, parameter :: ishift = ighost + 1 + integer, parameter :: ist = 1 + ishift + integer, parameter :: ied = nx + ishift + integer, parameter :: ntcell = nx + ishift + ighost + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + integer :: il(0:nx), ir(0:nx) + real(8) :: coef(0:iorder,0:iorder-1) + real(8) :: dd(0:ighost-1, 1:ntcell) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(0:nx-1) + real(8) :: dt +end module global + +module mesh_module + use global, only: ntcell + implicit none + real(8) :: xstart, xend, dx + real(8) :: x(1:ntcell+1) + real(8) :: xcc(1:ntcell) +endmodule mesh_module + +module field_module + use global, only: ntcell + implicit none + real(8) :: u(1:ntcell), un(1:ntcell) +endmodule field_module + +subroutine residual(q) + use global + use mesh_module, only : dx + implicit none + real(8) :: q(1:ntcell) + integer :: i + + call reconstruction(q) + call engquist_osher_flux(up1_2m,up1_2p,flux) + do i = 0, nx-1 + res(i) = - ( flux(i+1) - flux(i) ) / dx + enddo + +end subroutine residual + +subroutine reconstruction(q) + use global + implicit none + real(8) :: q(1:ntcell) + integer :: i, j, m, k1, k2, l1, l2 + + !chose the stencil by ENO method + do j = 1, ntcell + dd(0,j) = q(j) + enddo + + do m = 1, iorder - 1 + do j = 1, ntcell - 1 + dd(m,j) = dd(m-1,j+1)-dd(m-1,j) + enddo + enddo + + do i = 0, nx + il(i) = i + ir(i) = i + 1 + do m=1,iorder-1 + if ( abs(dd(m,il(i)-1+ishift)) <= abs(dd(m,il(i)+ishift)) ) then + il(i) = il(i) - 1 + endif + if ( abs(dd(m,ir(i)-1+ishift)) <= abs(dd(m,ir(i)+ishift)) ) then + ir(i) = ir(i) - 1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do i = 0, nx + k1 = il(i) + k2 = ir(i) + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m(i) = 0 + up1_2p(i) = 0 + do m=0,iorder-1 + up1_2m(i) = up1_2m(i) + q(k1+ishift+m) * coef(l1,m) + up1_2p(i) = up1_2p(i) + q(k2+ishift+m) * coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine engquist_osher_flux(up1_2m,up1_2p,flux) + use global, only: ist, ied, nx + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + integer :: i + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine engquist_osher_flux + +subroutine boundary( u ) + use global + implicit none + real(8) :: u(1:ntcell) + integer :: i + + do i = - ighost, 0 + u( ishift + i ) = u( ied + i ) + enddo + + do i = 1, ighost + u( ied + i ) = u( ishift + i ) + enddo + +end subroutine boundary + +subroutine update_oldfield(qn, q) + use global, only: ntcell + implicit none + real(8),dimension(1:ntcell) :: qn, q + qn = q +end subroutine update_oldfield + +subroutine init_coef + use global + implicit none + + coef(0, 0) = 363.0/140.0 + coef(0, 1) = -617.0/140.0 + coef(0, 2) = 853.0/140.0 + coef(0, 3) = -2341.0/420.0 + coef(0, 4) = 667.0/210.0 + coef(0, 5) = -43.0/42.0 + coef(0, 6) = 1.0/7.0 + + coef(1, 0) = 1.0/7.0 + coef(1, 1) = 223.0/140.0 + coef(1, 2) = -197.0/140.0 + coef(1, 3) = 153.0/140.0 + coef(1, 4) = -241.0/420.0 + coef(1, 5) = 37.0/210.0 + coef(1, 6) = -1.0/42.0 + + coef(2, 0) = -1.0/42.0 + coef(2, 1) = 13.0/42.0 + coef(2, 2) = 153.0/140.0 + coef(2, 3) = -241.0/420.0 + coef(2, 4) = 109.0/420.0 + coef(2, 5) = -31.0/420.0 + coef(2, 6) = 1.0/105.0 + + coef(3, 0) = 1.0/105.0 + coef(3, 1) = -19.0/210.0 + coef(3, 2) = 107.0/210.0 + coef(3, 3) = 319.0/420.0 + coef(3, 4) = -101.0/420.0 + coef(3, 5) = 5.0/84.0 + coef(3, 6) = -1.0/140.0 + + coef(4, 0) = -1.0/140.0 + coef(4, 1) = 5.0/84.0 + coef(4, 2) = -101.0/420.0 + coef(4, 3) = 319.0/420.0 + coef(4, 4) = 107.0/210.0 + coef(4, 5) = -19.0/210.0 + coef(4, 6) = 1.0/105.0 + + coef(5, 0) = 1.0/105.0 + coef(5, 1) = -31.0/420.0 + coef(5, 2) = 109.0/420.0 + coef(5, 3) = -241.0/420.0 + coef(5, 4) = 153.0/140.0 + coef(5, 5) = 13.0/42.0 + coef(5, 6) = -1.0/42.0 + + coef(6, 0) = -1.0/42.0 + coef(6, 1) = 37.0/210.0 + coef(6, 2) = -241.0/420.0 + coef(6, 3) = 153.0/140.0 + coef(6, 4) = -197.0/140.0 + coef(6, 5) = 223.0/140.0 + coef(6, 6) = 1.0/7.0 + + coef(7, 0) = 1.0/7.0 + coef(7, 1) = -43.0/42.0 + coef(7, 2) = 667.0/210.0 + coef(7, 3) = -2341.0/420.0 + coef(7, 4) = 853.0/140.0 + coef(7, 5) = -617.0/140.0 + coef(7, 6) = 363.0/140.0 + +end subroutine init_coef + +subroutine init_mesh + use global + use mesh_module + implicit none + integer :: i + real(8) :: xstart0 + + xstart = -1.0 + xend = 1.0 + + dx = ( xend - xstart ) / nx + xstart0 = xstart - ishift * dx + + do i = 1, ntcell + 1 + x(i) = xstart0 + ( i - 1 ) * dx + enddo + + do i = 1, ntcell + xcc(i) = 0.5 * ( x(i) + x(i+1) ) + enddo + +end subroutine init_mesh + +subroutine init_field() + use global + use mesh_module + use field_module + implicit none + integer :: i + + do i = ist, ied + u(i) = 0.25 + 0.5 * sin( pi * xcc(i) ) + enddo + + call boundary( u ) + call update_oldfield(un, u) + +end subroutine init_field + +subroutine runge_kutta_3() + use global + use field_module + implicit none + integer :: i, j + real(8) :: c1, c2, c3 + + call residual(u) + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = u(j) + dt * res(i) + enddo + call boundary( u ) + + call residual(u) + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = 0.75 * un(j) + 0.25 * u(j) + 0.25 * dt * res(i) + enddo + + call boundary( u ) + + call residual( u ) + + c1 = 1.0 / 3.0 + c2 = 2.0 / 3.0 + c3 = 2.0 / 3.0 + + do i = 0, nx-1 + j = i + 1 + ishift + u(j) = c1 * un(j) + c2 * u(j) + c3 * dt * res(i) + enddo + call boundary( u ) + + call update_oldfield(un, u) + +end subroutine runge_kutta_3 + +subroutine visualize + use global + use mesh_module + use field_module + implicit none + integer :: i + open(1,file='solution_total.plt',status='unknown') + do i = 1, ntcell + write(1,101) xcc(i),u(i) + enddo + close(1) + + open(2,file='solution.plt',status='unknown') + do i = ist, ied + write(2,101) xcc(i),u(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end subroutine visualize + +program main + use global + use mesh_module + use field_module + implicit none + integer :: i + real(8) :: t, simu_time + + call init_coef() + call init_mesh() + call init_field() + + write(*,*) 'Input T:' + read(*,*) simu_time + + dt = dx * 0.5 + t = 0 + do while ( t < simu_time ) + call runge_kutta_3() + + t = t + dt + if ( t + dt > simu_time ) then + dt = simu_time - t + endif + enddo + + write(*,*) t + + call visualize() + +end program main \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/fortran/01/plot.py b/example/burgers/inviscid-1d/eno7/fortran/01/plot.py new file mode 100644 index 00000000..87c8ba86 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/fortran/01/plot.py @@ -0,0 +1,38 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label="Eno7") +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/julia/01/eno.jl b/example/burgers/inviscid-1d/eno7/julia/01/eno.jl new file mode 100644 index 00000000..c91d3fec --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/julia/01/eno.jl @@ -0,0 +1,212 @@ +using OffsetArrays + +# Global constants and variables +const nx = 40 +const ighost = 10 +const iorder = 7 +const ishift = ighost + 1 +const ist = 1 + ishift +const ied = nx + ishift +const ntcell = nx + ishift + ighost +const isize = iorder * (iorder + 1) +const pi = 3.14159265358979323846 + +# Global arrays with zero-based indexing +il = OffsetArray(zeros(Int, nx + 1), 0:nx) +ir = OffsetArray(zeros(Int, nx + 1), 0:nx) +coef = OffsetArray(zeros(iorder + 1, iorder), 0:iorder, 0:iorder-1) +dd = OffsetArray(zeros(ighost, ntcell + 1), 0:ighost-1, 0:ntcell) +up1_2m = OffsetArray(zeros(nx + 1), 0:nx) +up1_2p = OffsetArray(zeros(nx + 1), 0:nx) +flux = OffsetArray(zeros(nx + 1), 0:nx) +res = OffsetArray(zeros(nx), 0:nx-1) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = OffsetArray(zeros(ntcell + 2), 0:ntcell+1) +xcc = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +# Field module variables +u = OffsetArray(zeros(ntcell + 1), 0:ntcell) +un = OffsetArray(zeros(ntcell + 1), 0:ntcell) + +function residual(q) + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx-1 + res[i] = -(flux[i + 1] - flux[i]) / dx + end +end + +function reconstruction(q) + # Choose the stencil by ENO method + dd[0, 1:ntcell] .= q[1:ntcell] # Matches Python’s dd[0, 1:ntcell + 1] + + for m in 1:iorder-1 + for j in 1:ntcell-1 + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + end + end + + for i in 0:nx + il[i] = i + ir[i] = i + 1 + for m in 1:iorder-1 + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]) + il[i] -= 1 + end + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]) + ir[i] -= 1 + end + end + end + + # Reconstruction u(j+1/2) + for i in 0:nx + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0.0 + up1_2p[i] = 0.0 + for m in 0:iorder-1 + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + end + end +end + +function engquist_osher_flux(up1_2m, up1_2p, flux) + for i in 0:nx + if up1_2m[i] >= 0 + if up1_2p[i] >= 0 + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + end + else + if up1_2p[i] >= 0 + flux[i] = 0.0 + else + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + end + end + end +end + +function boundary(u) + for i in -ighost:0 + u[ishift + i] = u[ied + i] + end + for i in 1:ighost + u[ied + i] = u[ishift + i] + end +end + +function update_oldfield(qn, q) + qn .= q +end + +function init_coef() + coef[0, :] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1, :] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2, :] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3, :] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4, :] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5, :] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6, :] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7, :] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] +end + +function init_mesh() + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in 1:ntcell+1 + x[i] = xstart0 + (i - 1) * dx + end + + for i in 1:ntcell + xcc[i] = 0.5 * (x[i] + x[i + 1]) + end +end + +function init_field() + for i in ist:ied + u[i] = 0.25 + 0.5 * sin(pi * xcc[i]) + end + boundary(u) + update_oldfield(un, u) +end + +function runge_kutta_3() + global u, un, dt + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + end + boundary(u) + + residual(u) + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + end + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in 0:nx-1 + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + end + boundary(u) + update_oldfield(un, u) +end + +function visualize() + open("solution_total.plt", "w") do f1 + for i in 1:ntcell + println(f1, "$(xcc[i])\t$(u[i])") + end + end + + open("solution.plt", "w") do f2 + for i in ist:ied + println(f2, "$(xcc[i])\t$(u[i])") + end + end +end + +function main() + global dt + init_coef() + init_mesh() + init_field() + + println("Input T: ") + simu_time = parse(Float64, readline()) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time + runge_kutta_3() + t += dt + if t + dt > simu_time + dt = simu_time - t + end + end + + println(t) + visualize() +end + +# Run the main function +main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/julia/01/plot.py b/example/burgers/inviscid-1d/eno7/julia/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/julia/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/01/eno.py b/example/burgers/inviscid-1d/eno7/python/01/eno.py new file mode 100644 index 00000000..4ad651fc --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/01/eno.py @@ -0,0 +1,176 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 1:ntcell + 1] = q[1:ntcell + 1] + + for m in range(1, iorder): + for j in range(1, ntcell): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i + ir[i] = i + 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + 1 + l2 = i - k2 + 1 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ishift + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ishift + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + xstart0 = xstart - ishift * dx + + for i in range(1, ntcell + 2): + x[i] = xstart0 + (i - 1) * dx + + for i in range(1, ntcell + 1): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[i]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + 1 + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + 1 + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution_total.plt', 'w') as f1: + for i in range(1, ntcell + 1): + f1.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + + with open('solution.plt', 'w') as f2: + for i in range(ist, ied + 1): + f2.write(f"{xcc[i]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +ighost = 10 +iorder = 7 +ishift = ighost + 1 +ist = 1 + ishift +ied = nx + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell + 1)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(ntcell + 2) +xcc = np.zeros(ntcell + 1) + +# Field module variables +u = np.zeros(ntcell + 1) +un = np.zeros(ntcell + 1) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/01/plot.py b/example/burgers/inviscid-1d/eno7/python/01/plot.py new file mode 100644 index 00000000..ef63f50b --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/01/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution_total.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/02/eno.py b/example/burgers/inviscid-1d/eno7/python/02/eno.py new file mode 100644 index 00000000..054efb88 --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/02/eno.py @@ -0,0 +1,177 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 1): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 7 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + ishift + ighost +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((ighost, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/02/plot.py b/example/burgers/inviscid-1d/eno7/python/02/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/02/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/03/eno.py b/example/burgers/inviscid-1d/eno7/python/03/eno.py new file mode 100644 index 00000000..8eb0ef4e --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/03/eno.py @@ -0,0 +1,177 @@ +import numpy as np + +def residual(q): + reconstruction(q) + engquist_osher_flux(up1_2m, up1_2p, flux) + for i in range(nx): + res[i] = -(flux[i + 1] - flux[i]) / dx + +def reconstruction(q): + global il, ir, dd, up1_2m, up1_2p + + # Choose the stencil by ENO method + dd[0, 0:ntcell-1] = q[0:ntcell-1] + + for m in range(1, iorder): + for j in range(0, ntcell-1): + dd[m, j] = dd[m-1, j+1] - dd[m-1, j] + + for i in range(nx + 1): + il[i] = i - 1 + for m in range(1, iorder): + if abs(dd[m, il[i]-1+ishift]) <= abs(dd[m, il[i]+ishift]): + il[i] -= 1 + + for i in range(nx + 1): + ir[i] = i + for m in range(1, iorder): + if abs(dd[m, ir[i]-1+ishift]) <= abs(dd[m, ir[i]+ishift]): + ir[i] -= 1 + + # Reconstruction u(j+1/2) + for i in range(nx + 1): + k1 = il[i] + k2 = ir[i] + l1 = i - k1 + l2 = i - k2 + up1_2m[i] = 0 + up1_2p[i] = 0 + for m in range(iorder): + up1_2m[i] += q[k1 + ishift + m] * coef[l1, m] + up1_2p[i] += q[k2 + ishift + m] * coef[l2, m] + +def engquist_osher_flux(up1_2m, up1_2p, flux): + for i in range(nx + 1): + if up1_2m[i] >= 0: + if up1_2p[i] >= 0: + flux[i] = 0.5 * up1_2m[i] * up1_2m[i] + else: + flux[i] = 0.5 * (up1_2m[i] * up1_2m[i] + up1_2p[i] * up1_2p[i]) + else: + if up1_2p[i] >= 0: + flux[i] = 0 + else: + flux[i] = 0.5 * up1_2p[i] * up1_2p[i] + +def boundary(u): + for i in range(-ighost, 1): + u[ist - 1 + i] = u[ied + i] + for i in range(1, ighost + 2): + u[ied + i] = u[ist - 1 + i] + +def update_oldfield(qn, q): + qn[:] = q[:] + +def init_coef(): + global coef + coef[0] = [ 363.0/140.0, -617.0/140.0, 853.0/140.0, -2341.0/420.0, 667.0/210.0, -43.0/42.0, 1.0/7.0 ] + coef[1] = [ 1.0/7.0, 223.0/140.0, -197.0/140.0, 153.0/140.0, -241.0/420.0, 37.0/210.0, -1.0/42.0 ] + coef[2] = [ -1.0/42.0, 13.0/42.0, 153.0/140.0, -241.0/420.0, 109.0/420.0, -31.0/420.0, 1.0/105.0 ] + coef[3] = [ 1.0/105.0, -19.0/210.0, 107.0/210.0, 319.0/420.0, -101.0/420.0, 5.0/84.0, -1.0/140.0 ] + coef[4] = [ -1.0/140.0, 5.0/84.0, -101.0/420.0, 319.0/420.0, 107.0/210.0, -19.0/210.0, 1.0/105.0 ] + coef[5] = [ 1.0/105.0, -31.0/420.0, 109.0/420.0, -241.0/420.0, 153.0/140.0, 13.0/42.0, -1.0/42.0 ] + coef[6] = [ -1.0/42.0, 37.0/210.0, -241.0/420.0, 153.0/140.0, -197.0/140.0, 223.0/140.0, 1.0/7.0 ] + coef[7] = [ 1.0/7.0, -43.0/42.0, 667.0/210.0, -2341.0/420.0, 853.0/140.0, -617.0/140.0, 363.0/140.0 ] + +def init_mesh(): + global xstart, xend, dx, x, xcc + xstart = -1.0 + xend = 1.0 + dx = (xend - xstart) / nx + + for i in range(0, nx+1): + x[i] = xstart + i * dx + + for i in range(0, nx): + xcc[i] = 0.5 * (x[i] + x[i + 1]) + +def init_field(): + global u, un + for i in range(ist, ied + 1): + j = i - ist + u[i] = 0.25 + 0.5 * np.sin(pi * xcc[j]) + boundary(u) + update_oldfield(un, u) + +def runge_kutta_3(): + global u, un, dt + residual(u) + for i in range(nx): + j = i + ishift + u[j] = u[j] + dt * res[i] + boundary(u) + + residual(u) + for i in range(nx): + j = i + ishift + u[j] = 0.75 * un[j] + 0.25 * u[j] + 0.25 * dt * res[i] + boundary(u) + + residual(u) + c1, c2, c3 = 1.0/3.0, 2.0/3.0, 2.0/3.0 + for i in range(nx): + j = i + ishift + u[j] = c1 * un[j] + c2 * u[j] + c3 * dt * res[i] + boundary(u) + update_oldfield(un, u) + +def visualize(): + with open('solution.plt', 'w') as f: + for i in range(ist, ied + 1): + j = i - ist + f.write(f"{xcc[j]:20.10e}{u[i]:20.10e}\n") + +# Global constants and variables +nx = 40 +iorder = 7 +ighost = iorder +ishift = ighost + 1 +ist = 0 + ishift +ied = nx - 1 + ishift +ntcell = nx + 2 * ishift +isize = iorder * (iorder + 1) +pi = 3.14159265358979323846 + +il = np.zeros(nx + 1, dtype=int) +ir = np.zeros(nx + 1, dtype=int) +coef = np.zeros((iorder + 1, iorder)) +dd = np.zeros((iorder, ntcell)) +up1_2m = np.zeros(nx + 1) +up1_2p = np.zeros(nx + 1) +flux = np.zeros(nx + 1) +res = np.zeros(nx) +dt = 0.0 + +# Mesh module variables +xstart = 0.0 +xend = 0.0 +dx = 0.0 +x = np.zeros(nx + 1) +xcc = np.zeros(nx) + +# Field module variables +u = np.zeros(ntcell) +un = np.zeros(ntcell) + +def main(): + global dt + init_coef() + init_mesh() + init_field() + + simu_time = float(input("Input T: ")) + dt = dx * 0.5 + print(f'dt={dt}') + t = 0.0 + + while t < simu_time: + runge_kutta_3() + t += dt + if t + dt > simu_time: + dt = simu_time - t + + print(t) + visualize() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/example/burgers/inviscid-1d/eno7/python/03/plot.py b/example/burgers/inviscid-1d/eno7/python/03/plot.py new file mode 100644 index 00000000..e389044c --- /dev/null +++ b/example/burgers/inviscid-1d/eno7/python/03/plot.py @@ -0,0 +1,53 @@ +import numpy as np +import matplotlib.pyplot as plt +import csv +import sys + +nvar = len(sys.argv) +print('nvar=',nvar) +print('sys.argv=',sys.argv) + +order = 1 +if nvar >= 2: + var = sys.argv[1] + print('var=',var) + order = int(var) + +print('order=',order) + +x_list = [] +u_list = [] + +with open('solution.plt', newline='') as csvfile: + #readCSV = csv.reader(csvfile, delimiter= ' ') + icount = 0 + for line in csvfile: + # 去除首尾空格,按连续空格分割 + row = line.strip().split() + #print("row=",row) + x_list.append(row[0]) + u_list.append(row[1]) + icount += 1 + +ni = icount +print("ni=",ni) + +#print("x_list=",x_list) + +x = np.zeros( ni ) +u = np.zeros( ni ) + +for i in range(0, ni): + x[i] = float(x_list[i]) + u[i] = float(u_list[i]) + +labelname = 'Eno' + str(order) + +plt.figure("OneFLOW-CFD Solver", figsize=(8, 6), dpi=100) +plt.plot(x, u, "b-", linewidth=1.0, marker = 's', markerfacecolor='None', label=labelname) +plt.xlabel("$x$") +plt.ylabel("$u$") +plt.title("burgers T=1") +plt.legend() +plt.tight_layout() +plt.show(); \ No newline at end of file diff --git a/example/burgers/theory/python/01/testprj.py b/example/burgers/theory/python/01/testprj.py new file mode 100644 index 00000000..035a5d81 --- /dev/null +++ b/example/burgers/theory/python/01/testprj.py @@ -0,0 +1,20 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 参数设置 +nu = 0.1 # 粘性系数 +x = np.linspace(-1, 1, 400) # x 范围从 -1 到 1 +t = 0.1 # 时间 t + +# 计算解析解 +u = 2 * np.pi * nu * np.tan(np.pi * x) + +# 绘图 +plt.figure(figsize=(10, 6)) +plt.plot(x, u, label=f't = {t}', linewidth=2) +plt.title('解析解 u(x, t) = 2 * pi * nu * tan(pi * x)', fontsize=14) +plt.xlabel('x', fontsize=12) +plt.ylabel('u(x, t)', fontsize=12) +plt.legend(fontsize=12) +plt.grid(True) +plt.show() \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/CMakeLists.txt b/example/eno/enoburgers/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/README.txt b/example/eno/enoburgers/fortran/01/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01/enoburgers.f90 b/example/eno/enoburgers/fortran/01/enoburgers.f90 new file mode 100644 index 00000000..0cd18f3d --- /dev/null +++ b/example/eno/enoburgers/fortran/01/enoburgers.f90 @@ -0,0 +1,291 @@ +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(0:iorder-1,0:iorder-1) +! real(8) :: res(1:nx) +! real(8) :: dx +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, m +! integer :: k1, k2, l1, l2 +! integer :: nx, iorder, ighost +! +!! Choose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j) = u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j) = dd(i-1,j+1) - dd(i-1,j) +! enddo +! enddo +! +! do j = 0, nx +! il(j) = j +! do i = 1, iorder - 1 +! if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j) = il(j) - 1 +! endif +! enddo +! enddo +! +! do j = 0, nx +! ir(j) = j + 1 +! do i = 1, iorder - 1 +! if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j) = ir(j) - 1 +! endif +! enddo +! enddo +! +!! Reconstruction u(j+1/2) +! do j = 0, nx +! k1 = il(j) +! k2 = ir(j) +! l1 = j - k1 +! l2 = j - k2 +! up1_2m(j) = 0 +! up1_2p(j) = 0 +! do m = 0, iorder - 1 +! up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) +! up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) +! enddo +! enddo +! +! do i = 1, nx +! res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx +! enddo +! +! end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & + ,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + !real(8) :: coef(0:iorder-1, 0:iorder-1) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + !dx = 1.0 / nx + !dt = dx * 0.5 + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + !coef = reshape([1.5,-0.5,0.5,0.5,-0.5,1.5], [iorder+1, iorder], order = [1, 2]) + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt b/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/README.txt b/example/eno/enoburgers/fortran/01_debug/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 b/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 new file mode 100644 index 00000000..57c2b5f1 --- /dev/null +++ b/example/eno/enoburgers/fortran/01_debug/enoburgers.f90 @@ -0,0 +1,289 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + real(8) :: res(1:nx) + real(8) :: dx + integer :: il(0:nx), ir(0:nx) + integer :: i, j, m + integer :: k1, k2, l1, l2 + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + + do j = 0, nx + il(j) = j + do i = 1, iorder - 1 + if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j) = il(j) - 1 + endif + enddo + enddo + + do j = 0, nx + ir(j) = j + 1 + do i = 1, iorder - 1 + if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j) = ir(j) - 1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k1 = il(j) + k2 = ir(j) + l1 = j - k1 + l2 = j - k2 + up1_2m(j) = 0 + up1_2p(j) = 0 + do m = 0, iorder - 1 + up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) + up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) + enddo + enddo + + do i = 1, nx + res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx + enddo + + end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & +! ,iorder,ighost) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(-1:iorder-1,0:iorder-1) +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, k1, k2, l1, l2, m, nx +! integer :: iorder, ighost +! +! ! chose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j)=u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j)=dd(i-1,j+1)-dd(i-1,j) +! enddo +! enddo +! do j=0,nx +! il(j)=j +! ir(j)=j+1 +! do i=1,iorder-1 +! if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j)=il(j)-1 +! endif +! if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j)=ir(j)-1 +! endif +! enddo +! enddo +! ! reconstruction u(j+1_2) +! do j=0,nx +! k1=il(j) +! k2=ir(j) +! l1=j-k1 +! l2=j-k2 +! up1_2m(j)=0 +! up1_2p(j)=0 +! do m=0,iorder-1 +! up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) +! up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) +! enddo +! enddo +!end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + !dx = 1.0 / nx + !dt = dx * 0.5 + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/CMakeLists.txt b/example/eno/enoburgers/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/README.txt b/example/eno/enoburgers/fortran/01a/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01a/enoburgers.f90 b/example/eno/enoburgers/fortran/01a/enoburgers.f90 new file mode 100644 index 00000000..608f5c2b --- /dev/null +++ b/example/eno/enoburgers/fortran/01a/enoburgers.f90 @@ -0,0 +1,336 @@ +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(0:iorder-1,0:iorder-1) +! real(8) :: res(1:nx) +! real(8) :: dx +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, m +! integer :: k1, k2, l1, l2 +! integer :: nx, iorder, ighost +! +!! Choose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j) = u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j) = dd(i-1,j+1) - dd(i-1,j) +! enddo +! enddo +! +! do j = 0, nx +! il(j) = j +! do i = 1, iorder - 1 +! if ( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j) = il(j) - 1 +! endif +! enddo +! enddo +! +! do j = 0, nx +! ir(j) = j + 1 +! do i = 1, iorder - 1 +! if ( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j) = ir(j) - 1 +! endif +! enddo +! enddo +! +!! Reconstruction u(j+1/2) +! do j = 0, nx +! k1 = il(j) +! k2 = ir(j) +! l1 = j - k1 +! l2 = j - k2 +! up1_2m(j) = 0 +! up1_2p(j) = 0 +! do m = 0, iorder - 1 +! up1_2m(j) = up1_2m(j) + u(k1+m) * coef(l1,m) +! up1_2p(j) = up1_2p(j) + u(k2+m) * coef(l2,m) +! enddo +! enddo +! +! do i = 1, nx +! res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx +! enddo +! +! end subroutine + +!subroutine getflux(up1_2m,up1_2p,flux,nx) +! implicit none +! real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) +! integer :: i, nx +! +! do i = 0, nx +! if ( up1_2m(i) >= 0 ) then +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0.5 * up1_2m(i) * up1_2m(i) +! else +! flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) +! endif +! else +! if ( up1_2p(i) >= 0 ) then +! flux(i) = 0 +! else +! flux(i) = 0.5 * up1_2p(i) * up1_2p(i) +! endif +! endif +! enddo +!end subroutine + +!subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef & +! ,iorder,ighost) +! implicit none +! real(8) :: u(-ighost:nx+ighost) +! real(8) :: up1_2m(0:nx),up1_2p(0:nx) +! real(8) :: dd(0:ighost-1,-ighost:nx+ighost) +! real(8) :: coef(-1:iorder-1,0:iorder-1) +! integer :: il(0:nx), ir(0:nx) +! integer :: i, j, k1, k2, l1, l2, m, nx +! integer :: iorder, ighost +! +! ! chose the stencil by ENO method +! do j=-ighost,nx+ighost +! dd(0,j)=u(j) +! enddo +! do i=1,iorder-1 +! do j=-ighost,nx+ighost-1 +! dd(i,j)=dd(i-1,j+1)-dd(i-1,j) +! enddo +! enddo +! do j=0,nx +! il(j)=j +! ir(j)=j+1 +! do i=1,iorder-1 +! if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then +! il(j)=il(j)-1 +! endif +! if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then +! ir(j)=ir(j)-1 +! endif +! enddo +! enddo +! ! reconstruction u(j+1_2) +! do j=0,nx +! k1=il(j) +! k2=ir(j) +! l1=j-k1 +! l2=j-k2 +! up1_2m(j)=0 +! up1_2p(j)=0 +! do m=0,iorder-1 +! up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) +! up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) +! enddo +! enddo +!end subroutine reconstruction + + +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + real(8) :: res(1:nx) + real(8) :: dx + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + !pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + ! /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call getflux(up1_2m,up1_2p,flux,nx) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Initial"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), u0(i) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/CMakeLists.txt b/example/eno/enoburgers/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/README.txt b/example/eno/enoburgers/fortran/01b/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01b/enoburgers.f90 b/example/eno/enoburgers/fortran/01b/enoburgers.f90 new file mode 100644 index 00000000..bb727327 --- /dev/null +++ b/example/eno/enoburgers/fortran/01b/enoburgers.f90 @@ -0,0 +1,230 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + real(8) :: res(1:nx) + real(8) :: dx + + ! chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + ! reconstruction u(j+1_2) + do j=0,nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo + + + do i = 1, nx + res(i) = - ( up1_2m(i) - up1_2m(i-1) ) / dx + enddo +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i=0,nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine rhs(up1_2m,up1_2p,nx,dx,res) + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx + integer :: nx, i + + call getflux(up1_2m,up1_2p,flux,nx) + + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo +end subroutine rhs + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt, ress + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + !u1(i) = pu(i) + dt * ress + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + ress = - ( flux(i) - flux(i-1) ) / dx + !u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost,dx,res) + !call getflux(up1_2m,up1_2p,flux,nx) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( flux(i) - flux(i-1) ) / dx + !su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + open(1,file='temp21.plt',status='unknown') + do i=-ighost,nx+ighost + write(1,101) x(i),pu(i) + enddo + close(1) + open(2,file='solution.plt',status='unknown') + do i=1,nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end program main \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/CMakeLists.txt b/example/eno/enoburgers/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..bc555e2d --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enoburgers.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/README.txt b/example/eno/enoburgers/fortran/01c/README.txt new file mode 100644 index 00000000..0d354569 --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/README.txt @@ -0,0 +1,3 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear +cmake ../ -T fortran=ifx \ No newline at end of file diff --git a/example/eno/enoburgers/fortran/01c/enoburgers.f90 b/example/eno/enoburgers/fortran/01c/enoburgers.f90 new file mode 100644 index 00000000..4d842aa3 --- /dev/null +++ b/example/eno/enoburgers/fortran/01c/enoburgers.f90 @@ -0,0 +1,218 @@ +subroutine reconstruction(u,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx),up1_2p(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, k1, k2, l1, l2, m, nx + integer :: iorder, ighost + + !chose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + + do j=0,nx + il(j)=j + ir(j)=j+1 + do i=1,iorder-1 + if( abs(dd(i,il(j)-1)) <= abs(dd(i,il(j))) ) then + il(j)=il(j)-1 + endif + if( abs(dd(i,ir(j)-1)) <= abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + + !reconstruction u(j+1_2) + do j = 0, nx + k1=il(j) + k2=ir(j) + l1=j-k1 + l2=j-k2 + up1_2m(j)=0 + up1_2p(j)=0 + do m=0,iorder-1 + up1_2m(j)=up1_2m(j)+u(k1+m)*coef(l1,m) + up1_2p(j)=up1_2p(j)+u(k2+m)*coef(l2,m) + enddo + enddo + +end subroutine reconstruction + +!calculate numerical flux +subroutine getflux(up1_2m,up1_2p,flux,nx) + implicit none + real(8) :: up1_2m(0:nx),up1_2p(0:nx),flux(0:nx) + integer :: i, nx + + do i = 0, nx + if ( up1_2m(i) >= 0 ) then + if ( up1_2p(i) >= 0 ) then + flux(i) = 0.5 * up1_2m(i) * up1_2m(i) + else + flux(i) = 0.5 * ( up1_2m(i) * up1_2m(i) + up1_2p(i) * up1_2p(i) ) + endif + else + if ( up1_2p(i) >= 0 ) then + flux(i) = 0 + else + flux(i) = 0.5 * up1_2p(i) * up1_2p(i) + endif + endif + enddo +end subroutine getflux + +subroutine rhs(up1_2m,up1_2p,nx,dx,res) + implicit none + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dx + integer :: nx, i + + call getflux(up1_2m,up1_2p,flux,nx) + + do i = 1, nx + res(i) = - ( flux(i) - flux(i-1) ) / dx + enddo +end subroutine rhs + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + integer, parameter :: isize = iorder * ( iorder + 1 ) + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), x(-ighost:nx+ighost) + real(8) :: up1_2m(0:nx), up1_2p(0:nx), flux(0:nx) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(-1:iorder-1,0:iorder-1) + integer :: il(0:nx), ir(0:nx) + integer :: i, j, icount + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + real(8) :: values(isize) = [1.5d0, -0.5d0, 0.5d0, 0.5d0, -0.5d0, 1.5d0] + + dx = 2.0 / nx + dt = dx * 0.5 + + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + icount = 1 + do i = -1, iorder-1 + do j = 0, iorder-1 + coef(i, j) = values(icount) + icount = icount + 1 + end do + end do +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 - 1.0 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = 0.25 + 0.5 * sin( pi * x(i) ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + do i = 1, nx + !ress = - ( flux(i) - flux(i-1) ) / dx + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2m,up1_2p,dd,il,ir,coef,iorder,ighost) + call rhs(up1_2m,up1_2p,nx,dx,res) + + do i = 1, nx + t1 = 1.0/3 + t2 = 2.0/3 + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + open(1,file='temp.plt',status='unknown') + do i=-ighost,nx+ighost + write(1,101) x(i),pu(i) + enddo + close(1) + open(2,file='solution.plt',status='unknown') + do i=1,nx + write(2,101) x(i),pu(i) + enddo + close(2) + 101 format(1x,e20.10,e20.10) +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/CMakeLists.txt b/example/eno/enolinear/fortran/01/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/README.txt b/example/eno/enolinear/fortran/01/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01/enolinear.f90 b/example/eno/enolinear/fortran/01/enolinear.f90 new file mode 100644 index 00000000..9e81111e --- /dev/null +++ b/example/eno/enolinear/fortran/01/enolinear.f90 @@ -0,0 +1,184 @@ + subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit double precision (a-h,o-z) + double precision u(-ighost:nx+ighost),up1_2(0:nx) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j)=j + do i=1,iorder-1 + if(abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j)))) then + ir(j)=ir(j)-1 + endif + enddo + enddo +! Reconstruction u(j+1/2) + do j=0,nx + k=ir(j) + l=j-k + up1_2(j)=0 + do m=0,iorder-1 + up1_2(j)=up1_2(j)+u(k+m)*coef(l,m) + enddo + enddo + end + +! Main program + program main + implicit double precision (a-h,o-z) + parameter (nx=40,pi=3.14159265358979323846,ighost=10,iorder=2) + double precision pu(-ighost:nx+ighost),su(-ighost:nx+ighost) + double precision u1(-ighost:nx+ighost),u2(-ighost:nx+ighost) + double precision u0(1:nx),up1_2(0:nx),x(-ighost:nx+ighost) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + tt=5.0/3.0 + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! 3rd-order coefficients +! data ((coef(i,j),j=0,2),i=0,2) & +! & /0.3333333333333333D0, 0.8333333333333333D0, +! & -0.1666666666666667D0,-0.1666666666666667D0, +! & 0.8333333333333333D0, 0.3333333333333333D0, +! & 0.3333333333333333D0,-1.1666666666666667D0, +! & 1.8333333333333333D0/ +! 4th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /0.25, 1.083333,-0.416667, 0.083333, +! & -0.083333, 0.583333, 0.583333,-0.083333, +! & 0.083333,-0.416667, 1.083333, 0.25, +! & -0.25, 1.083333,-1.916667, 2.083333/ +! 5th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /2.0D-1, 1.283333333333333D0,-7.166666666666667D-1, +! & 2.833333333333333333D-1,-5.0D-2, +! & -5.0D-2, 4.5D-1, 7.8333333333333333D-1, +! & -2.166666666666667D-1, 3.3333333333333333D-2, +! & 3.333333333333333333D-2,-2.166666666666667D-1, +! & 7.83333333333333333D-1,0.45D0,-5.0D-2, +! & -5.0D-2, 2.8333333333333333D-1,-7.166666666666667D-1, +! & 1.283333333333333333D0, 2.0D-1, +! & 2.0D-1,-1.05D0,2.2833333333333333333D0, +! & -2.716666666666667D0, 2.283333333333333333D0/ +! 6th-order coefficients +! data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & +! & /0.166667, 1.45, -1.05, 0.616667,-0.216667, 0.033333, +! & -0.033333, 0.366667, 0.95, -0.383333, 0.116667,-0.016667, +! & 0.016667,-0.133333, 0.616667, 0.616667,-0.133333, 0.016667, +! & -0.016667, 0.116667,-0.383333, 0.95, 0.366667,-0.033333, +! & 0.033333,-0.216667, 0.616667,-1.05, 1.45, 0.166667, +! & -0.166667, 1.033333,-2.716667, 3.95, -3.55, 2.45 / +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo +! Initial mean value 1 +! Initial mean value 2 + do i=1,nx +! pu(i)=0.5*((x(i)+dx/2)*(x(i)+dx/2)-(x(i)-dx/2)*(x(i)-dx/2))/dx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + & /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + + end \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/CMakeLists.txt b/example/eno/enolinear/fortran/01a/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01a/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/README.txt b/example/eno/enolinear/fortran/01a/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01a/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01a/enolinear.f90 b/example/eno/enolinear/fortran/01a/enolinear.f90 new file mode 100644 index 00000000..55ea1b8e --- /dev/null +++ b/example/eno/enolinear/fortran/01a/enolinear.f90 @@ -0,0 +1,163 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit double precision (a-h,o-z) + double precision u(-ighost:nx+ighost),up1_2(0:nx) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j)=u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j)=dd(i-1,j+1)-dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j)=j + do i=1,iorder-1 + if(abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j)))) then + ir(j)=ir(j)-1 + endif + enddo + enddo +! Reconstruction u(j+1/2) + do j=0,nx + k=ir(j) + l=j-k + up1_2(j)=0 + do m=0,iorder-1 + up1_2(j)=up1_2(j)+u(k+m)*coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit double precision (a-h,o-z) + parameter (nx=40,pi=3.14159265358979323846,ighost=10,iorder=2) + double precision pu(-ighost:nx+ighost),su(-ighost:nx+ighost) + double precision u1(-ighost:nx+ighost),u2(-ighost:nx+ighost) + double precision u0(1:nx),up1_2(0:nx),x(-ighost:nx+ighost) + double precision dd(0:ighost-1,-ighost:nx+ighost) + double precision coef(0:iorder-1,0:iorder-1) + integer ir(0:nx) + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + tt=5.0/3.0 + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 +! Initial mean value 2 + do i=1,nx +! pu(i)=0.5*((x(i)+dx/2)*(x(i)+dx/2)-(x(i)-dx/2)*(x(i)-dx/2))/dx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + & /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/CMakeLists.txt b/example/eno/enolinear/fortran/01b/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/README.txt b/example/eno/enolinear/fortran/01b/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01b/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01b/enolinear.f90 b/example/eno/enolinear/fortran/01b/enolinear.f90 new file mode 100644 index 00000000..2e968f66 --- /dev/null +++ b/example/eno/enolinear/fortran/01b/enolinear.f90 @@ -0,0 +1,170 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(unit=1,file='\temp2.plt',status='unknown') + + dx=1.0/nx + dt=dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + & /0.5,0.5,-0.5,1.5/ +! Initialize grid and initial conditions + do i=-ighost,nx+ighost + x(i)=(i-1)*dx+dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i=1,nx + pu(i)=-(cos(2.0*pi*(x(i)+dx/2))-cos(2.0*pi*(x(i)-dx/2))) & + /(dx*2.0*pi) + enddo + do i=0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i=nx+1,nx+ighost + pu(i)=pu(i-nx) + enddo + + do i=0,nx + u0(i)=pu(i) + enddo + +! Time stepping + t=0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(unit=2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx +! if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error+abs(u0(i)-pu(i)) + it=it+1 +! endif + enddo + error=error/it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error + +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/CMakeLists.txt b/example/eno/enolinear/fortran/01c/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01c/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/README.txt b/example/eno/enolinear/fortran/01c/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01c/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01c/enolinear.f90 b/example/eno/enolinear/fortran/01c/enolinear.f90 new file mode 100644 index 00000000..ea5591e3 --- /dev/null +++ b/example/eno/enolinear/fortran/01c/enolinear.f90 @@ -0,0 +1,169 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo +end subroutine reconstruction + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(1,file='\temp2.plt',status='unknown') + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + + count = 0 ! ʼ + + do i=-ighost,nx+ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if (count == 5) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i=1,nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + do i = 0,-ighost,-1 + pu(i)=pu(i+nx) + enddo + do i= nx + 1, nx + ighost + pu(i)=pu(i-nx) + enddo + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while(t.lt.supt) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + do i=0,-ighost,-1 + u1(i)=u1(i+nx) + enddo + do i=nx+1,nx+ighost + u1(i)=u1(i-nx) + enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + u2(i)=u2(i+nx) + enddo + do i=nx+1,nx+ighost + u2(i)=u2(i-nx) + enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + do i=0,-ighost,-1 + su(i)=su(i+nx) + enddo + do i=nx+1,nx+ighost + su(i)=su(i-nx) + enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx + !if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error + abs( u0(i) - pu(i) ) + it=it+1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/CMakeLists.txt b/example/eno/enolinear/fortran/01d/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01d/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/README.txt b/example/eno/enolinear/fortran/01d/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01d/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01d/enolinear.f90 b/example/eno/enolinear/fortran/01d/enolinear.f90 new file mode 100644 index 00000000..d78adcf3 --- /dev/null +++ b/example/eno/enolinear/fortran/01d/enolinear.f90 @@ -0,0 +1,194 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + open(1,file='\temp2.plt',status='unknown') + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + + count = 0 ! ʼ + + do i = - ighost, nx + ighost + write(*,'(1x,f10.6)',advance='no') x(i) + count = count + 1 + if ( count == 5 ) then + write(*,*) ! + count = 0 ! ü + endif + enddo + + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + !do i = 0, - ighost, - 1 + ! pu(i)=pu(i+nx) + !enddo + ! + !do i= nx + 1, nx + ighost + ! pu(i)=pu(i-nx) + !enddo + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t .lt. supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u1(i)=pu(i)-dt*temp/dx + enddo + + call boundary( u1, nx, ighost ) + !do i=0,-ighost,-1 + ! u1(i)=u1(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! u1(i)=u1(i-nx) + !enddo + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + enddo + + call boundary( u2, nx, ighost ) + !do i=0,-ighost,-1 + ! u2(i)=u2(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! u2(i)=u2(i-nx) + !enddo + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + su(i)=t1*pu(i)+t2*(u2(i)-dt*temp/dx) + enddo + + call boundary( su, nx, ighost ) + !do i=0,-ighost,-1 + ! su(i)=su(i+nx) + !enddo + !do i=nx+1,nx+ighost + ! su(i)=su(i-nx) + !enddo + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + t=t+dt + if(t+dt.gt.supt) then + dt=supt-t + endif + enddo + +! Output results to Tecplot file + open(2, file='solution.plt', status='unknown') + write(2, *) 'TITLE = "Numerical and Exact Solutions"' + write(2, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(2, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(2, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(2) + + do i=1,nx + !if(x(i).gt.0.2.and.x(i).lt.0.8) then + error=error + abs( u0(i) - pu(i) ) + it=it+1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/CMakeLists.txt b/example/eno/enolinear/fortran/01e/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01e/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/README.txt b/example/eno/enolinear/fortran/01e/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01e/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01e/enolinear.f90 b/example/eno/enolinear/fortran/01e/enolinear.f90 new file mode 100644 index 00000000..b2e730f7 --- /dev/null +++ b/example/eno/enolinear/fortran/01e/enolinear.f90 @@ -0,0 +1,159 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j=0,nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m=0,iorder-1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + do i=1,nx + temp=up1_2(i)-up1_2(i-1) + !u1(i)=pu(i)-dt*temp/dx + u1(i) = pu(i) - dt * temp/dx + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + temp=up1_2(i)-up1_2(i-1) + !u2(i)=3.0/4.0*pu(i)+1.0/4.0*(u1(i)-dt*temp/dx) + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) - 1.0/4.0 * dt * temp/dx + + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + temp = up1_2(i)-up1_2(i-1) + t1=1.0/3 + t2=2.0/3 + !su(i) = t1 * pu(i) + t2 * ( u2(i) - dt * temp / dx ) + su(i) = t1 * pu(i) + t2 * u2(i) - t2 * dt * temp / dx + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/CMakeLists.txt b/example/eno/enolinear/fortran/01f/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01f/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/README.txt b/example/eno/enolinear/fortran/01f/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01f/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01f/enolinear.f90 b/example/eno/enolinear/fortran/01f/enolinear.f90 new file mode 100644 index 00000000..eb04a10a --- /dev/null +++ b/example/eno/enolinear/fortran/01f/enolinear.f90 @@ -0,0 +1,158 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m = 0, iorder - 1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + real(8) :: ress + + dx = 1.0/nx + dt = dx*0.5 + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost) + + do i = 1, nx + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + u1(i) = pu(i) + dt * ress + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * ress + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + ress = - ( up1_2(i) - up1_2(i-1) ) / dx + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * ress + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/CMakeLists.txt b/example/eno/enolinear/fortran/01g/CMakeLists.txt new file mode 100644 index 00000000..d95dbe1c --- /dev/null +++ b/example/eno/enolinear/fortran/01g/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.31) + +project ( testprj ) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) + +enable_language(Fortran) + +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_20 ) + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +add_executable( ${PROJECT_NAME} + enolinear.f90 +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/README.txt b/example/eno/enolinear/fortran/01g/README.txt new file mode 100644 index 00000000..d3db84e1 --- /dev/null +++ b/example/eno/enolinear/fortran/01g/README.txt @@ -0,0 +1,2 @@ +PS D:\github\OneFLOW\example\eno\enolinear\fortran\01\build> cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell' +ifort ../enolinear.for -o enolinear \ No newline at end of file diff --git a/example/eno/enolinear/fortran/01g/enolinear.f90 b/example/eno/enolinear/fortran/01g/enolinear.f90 new file mode 100644 index 00000000..92f790da --- /dev/null +++ b/example/eno/enolinear/fortran/01g/enolinear.f90 @@ -0,0 +1,161 @@ +subroutine reconstruction(u,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + implicit none + real(8) :: u(-ighost:nx+ighost) + real(8) :: up1_2(0:nx) + real(8) :: dd(0:ighost-1,-ighost:nx+ighost) + real(8) :: coef(0:iorder-1,0:iorder-1) + real(8) :: res(1:nx) + real(8) :: dx + integer :: ir(0:nx) + integer :: i, j, k, l, m + integer :: nx, iorder, ighost + +! Choose the stencil by ENO method + do j=-ighost,nx+ighost + dd(0,j) = u(j) + enddo + do i=1,iorder-1 + do j=-ighost,nx+ighost-1 + dd(i,j) = dd(i-1,j+1) - dd(i-1,j) + enddo + enddo + do j=0,nx + ir(j) = j + do i=1,iorder-1 + if ( abs(dd(i,ir(j)-1)).le.abs(dd(i,ir(j))) ) then + ir(j)=ir(j)-1 + endif + enddo + enddo + +! Reconstruction u(j+1/2) + do j = 0, nx + k = ir(j) + l = j - k + up1_2(j) = 0 + do m = 0, iorder - 1 + up1_2(j) = up1_2(j) + u(k+m) * coef(l,m) + enddo + enddo + + do i = 1, nx + res(i) = - ( up1_2(i) - up1_2(i-1) ) / dx + enddo + +end subroutine reconstruction + +subroutine boundary( u, nx, ighost ) + implicit none + integer :: nx, ighost + real(8) :: u(-ighost:nx+ighost) + integer :: i + + do i = 0, - ighost, - 1 + u( i ) = u( i + nx ) + enddo + + do i = nx + 1, nx + ighost + u( i ) = u( i - nx ) + enddo +end subroutine boundary + +program main + implicit none + integer, parameter :: nx = 40 + integer, parameter :: ighost = 10 + integer, parameter :: iorder = 2 + real(8), parameter :: pi = 3.14159265358979323846 + real(8) :: pu(-ighost:nx+ighost), su(-ighost:nx+ighost) + real(8) :: u1(-ighost:nx+ighost), u2(-ighost:nx+ighost) + real(8) :: u0(1:nx), up1_2(0:nx), x(-ighost:nx+ighost) + real(8) :: res(1:nx) + real(8) :: dd(0:ighost-1, -ighost:nx+ighost) + real(8) :: coef(0:iorder-1, 0:iorder-1) + integer :: ir(0:nx) + integer :: i, j, count + real(8) :: supt, t, temp, t1, t2, error, it + real(8) :: dx, dt + + dx = 1.0 / nx + dt = dx * 0.5 + write(*,*) 'dx = ', dx, 'dt = ', dt + write(*,*) 'Input T:' + read(*,*) supt + +! 2nd-order coefficients + coef = reshape([0.5,0.5,-0.5,1.5], [iorder, iorder], order = [2, 1]) +! Initialize grid and initial conditions + do i= - ighost, nx + ighost + x(i) = (i-1) * dx + dx/2 + enddo + +! Initial mean value 1 + do i = 1, nx + pu(i) = - ( cos( 2.0 * pi * ( x(i) + dx / 2) ) - cos( 2.0 * pi * ( x(i) - dx/2) ) ) & + /( dx * 2.0 * pi ) + enddo + + call boundary( pu, nx, ighost ) + + do i = 0, nx + u0(i) = pu(i) + enddo + +! Time stepping + t = 0 + do while ( t < supt ) + call reconstruction(pu,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + + do i = 1, nx + u1(i) = pu(i) + dt * res(i) + enddo + + call boundary( u1, nx, ighost ) + + call reconstruction(u1,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + do i = 1, nx + u2(i) = 3.0/4.0 * pu(i) + 1.0/4.0 * u1(i) + 1.0/4.0 * dt * res(i) + enddo + + call boundary( u2, nx, ighost ) + + call reconstruction(u2,nx,up1_2,dd,ir,coef,iorder,ighost,dx,res) + do i = 1, nx + t1=1.0/3 + t2=2.0/3 + su(i) = t1 * pu(i) + t2 * u2(i) + t2 * dt * res(i) + enddo + + call boundary( su, nx, ighost ) + + do i=-ighost,nx+ighost + pu(i)=su(i) + enddo + + t = t + dt + if ( t + dt > supt ) then + dt = supt - t + endif + enddo + +! Output results to Tecplot file + open(1, file='solution.plt', status='unknown') + write(1, *) 'TITLE = "Numerical and Exact Solutions"' + write(1, *) 'VARIABLES = "x", "Numerical", "Exact"' + write(1, *) 'ZONE T="Solution", I=', nx + 1, ', F=POINT' + do i = 0, nx + write(1, *) x(i), pu(i), sin(2 * pi * (x(i) - t)) + end do + close(1) + + do i = 1, nx + !if( x(i) > 0.2 .and. x(i) < 0.8 ) then + error = error + abs( u0(i) - pu(i) ) + it = it + 1 + !endif + enddo + error = error / it + + write(*, *) 'Final time:', t + write(*, *) 'Error:', error +end program main \ No newline at end of file diff --git a/example/figure/1d/03/testprj.py b/example/figure/1d/03/testprj.py new file mode 100644 index 00000000..ac9d8e95 --- /dev/null +++ b/example/figure/1d/03/testprj.py @@ -0,0 +1,32 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义当前计算点i和扩展范围r、s +i = 0 # 当前计算点 +r = 3 # 左侧扩展范围 +s = 3 # 右侧扩展范围 + +# 生成网格点索引 +x_indices = np.arange(i - r, i + s + 1) + +# 生成对应的值(这里用随机值表示,实际应用中可以替换为具体值) +u_values = np.random.rand(len(x_indices)) + +# 绘制网格点和对应的值 +plt.figure(figsize=(10, 2)) +plt.plot(x_indices, u_values, 'o-', label='Grid Points and Values') +plt.xlabel('Grid Index') +plt.ylabel('Values') +plt.title('Grid Points and Corresponding Values') +plt.grid(True) +plt.legend() + +# 标注每个网格点 +for idx, value in zip(x_indices, u_values): + plt.text(idx, value, f'*', fontsize=12, ha='center', va='bottom') + +# 标注当前计算点 +plt.plot(i, u_values[i - (i - r)], 'ro', label='Current Point (i)') +plt.text(i, u_values[i - (i - r)], f'({i}, {u_values[i - (i - r)]:.2f})', fontsize=12, ha='center', va='bottom') + +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03a/testprj.py b/example/figure/1d/03a/testprj.py new file mode 100644 index 00000000..142cf0e2 --- /dev/null +++ b/example/figure/1d/03a/testprj.py @@ -0,0 +1,46 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义网格点 +i = 0 # 当前计算点 +r = 2 # 左侧扩展范围 +s = 2 # 右侧扩展范围 + +# 创建图形和子图 +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4), sharey=True) + +# 左侧重建 +x_left = np.arange(i - r, i + s + 1) +ax1.plot(x_left, np.zeros_like(x_left) + 1, 'o-', color='gray', markersize=8) +ax1.plot([i, i], [0, 1], 'k--') # 绘制垂直线 +ax1.plot([i + 1, i + 1], [0, 1], 'k--') # 绘制垂直线 +ax1.text(i + 0.5, 1.05, r'$u_{i+\frac{1}{2},L}^L$', fontsize=12, ha='center') +ax1.set_title('(a) Left-side reconstruction') +ax1.set_xticks(x_left) +ax1.set_xticklabels([f'{i-2}', f'{i-1}', f'{i}', f'{i+1}', f'{i+2}']) +ax1.set_xlim([i - r - 1, i + s + 2]) +ax1.set_ylim([0, 1.5]) +ax1.grid(False) + +# 右侧重建 +x_right = np.arange(i - 1, i + 4) +print("x_right=",x_right) +ax2.plot(x_right, np.zeros_like(x_right) + 1, 'o-', color='gray', markersize=8) +ax2.plot([i, i], [0, 1], 'k--') # 绘制垂直线 +ax2.plot([i + 2, i + 2], [0, 1], 'k--') # 绘制垂直线 +ax2.text(i + 1.5, 1.05, r'$u_{i+\frac{1}{2},R}^R$', fontsize=12, ha='center') +ax2.set_title('(b) Right-side reconstruction') +ax2.set_xticks(x_right) +ax2.set_xticklabels([f'{i-1}', f'{i}', f'{i+1}', f'{i+2}', f'{i+3}']) +ax2.set_xlim([i - 2, i + 3 + 1]) +ax2.set_ylim([0, 1.5]) +ax2.grid(False) + +# 绘制边界点 +for ax in [ax1, ax2]: + ax.plot([i + s + 1, i + s + 1], [0, 1], 'ko') # 绘制边界点 + ax.plot([i + s + 2, i + s + 2], [0, 1], 'ro') # 绘制边界点 + ax.plot([i + s + 3, i + s + 3], [0, 1], 'ro') # 绘制边界点 + +plt.tight_layout() +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03b/testprj.py b/example/figure/1d/03b/testprj.py new file mode 100644 index 00000000..6b95492f --- /dev/null +++ b/example/figure/1d/03b/testprj.py @@ -0,0 +1,83 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +# 绘制 (a) Left-side reconstruction +plt.subplot(1, 2, 1) # 1行2列的第一个子图 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5, 6]) # 对应 i = -2 到 N+3 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=10) # 红点 + +# 标记特定点 (i=1 和其他点) +plt.text(-2, 0.1, '$i=-2$', fontsize=12, ha='center') +plt.text(-1, 0.1, '$i=-1$', fontsize=12, ha='center') +plt.text(0, 0.1, '$i=0$', fontsize=12, ha='center') +plt.text(1, 0.1, '$i=1$', fontsize=12, ha='center') +plt.text(2, 0.1, '$i=2$', fontsize=12, ha='center') +plt.text(3, 0.1, '$i=3$', fontsize=12, ha='center') +plt.text(4, 0.1, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, 0.1, '$i=N+2$', fontsize=12, ha='center') +plt.text(6, 0.1, '$i=N+3$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (i-2 到 i+2, 覆盖 i+1) +template_left = plt.Rectangle((0.5, -0.5), 4, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_left) +plt.text(2.5, 0.3, '$u_{i+1}^L$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(a) Left-side reconstruction', fontsize=14) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 绘制 (b) Right-side reconstruction +plt.subplot(1, 2, 2) # 1行2列的第二个子图 + +# 绘制网格点 (红点) +plt.plot(x_points, y_points, 'ro', markersize=10) # 红点 + +# 标记特定点 (i=1 和其他点) +plt.text(-2, 0.1, '$i=-2$', fontsize=12, ha='center') +plt.text(-1, 0.1, '$i=-1$', fontsize=12, ha='center') +plt.text(0, 0.1, '$i=0$', fontsize=12, ha='center') +plt.text(1, 0.1, '$i=1$', fontsize=12, ha='center') +plt.text(2, 0.1, '$i=2$', fontsize=12, ha='center') +plt.text(3, 0.1, '$i=3$', fontsize=12, ha='center') +plt.text(4, 0.1, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, 0.1, '$i=N+2$', fontsize=12, ha='center') +plt.text(6, 0.1, '$i=N+3$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (i-1 到 i+3, 覆盖 i+1) +template_right = plt.Rectangle((0.5, -0.5), 5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_right) +plt.text(2.5, 0.3, '$u_{i+1}^R$', fontsize=12, ha='center') + +# 绘制黑点 (i=1) +plt.plot(1, 0, 'ko', markersize=10) # 黑点在 i=1 + +# 设置标题和轴 +plt.title('(b) Right-side reconstruction', fontsize=14) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 调整布局 +plt.tight_layout() + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03c/testprj.py b/example/figure/1d/03c/testprj.py new file mode 100644 index 00000000..feff1396 --- /dev/null +++ b/example/figure/1d/03c/testprj.py @@ -0,0 +1,68 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形样式 +plt.rcParams['font.size'] = 12 + +# 绘制 (a) Left-side reconstruction +plt.figure(figsize=(8, 2)) # 调整图形大小以匹配图片宽度 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5, 6]) # 对应 i = -2 到 N+3 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 标记特定点 (i 值) +for i, x in enumerate(x_points): + plt.text(x, 0.1, f'$i={x}$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (从 i-1 到 i+2, 覆盖 i+1) +template_left = plt.Rectangle((-0.5, -0.5), 3.5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_left) +plt.text(1, 0.3, '$u_{i+1}^L$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(a) Left-side reconstruction', fontsize=14, pad=10) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('left_side_reconstruction.png', bbox_inches='tight', dpi=300) +plt.show() + +# 绘制 (b) Right-side reconstruction +plt.figure(figsize=(8, 2)) # 调整图形大小以匹配图片宽度 + +# 绘制网格点 (红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 标记特定点 (i 值) +for i, x in enumerate(x_points): + plt.text(x, 0.1, f'$i={x}$', fontsize=12, ha='center') + +# 绘制 x=0 和 x=L 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=6, color='k', linestyle='--', alpha=0.5) +plt.text(0, -0.2, '$x=0$', fontsize=12, ha='center') +plt.text(6, -0.2, '$x=L$', fontsize=12, ha='center') + +# 绘制紫色矩形模板 (从 i-1 到 i+2, 覆盖 i+1) +template_right = plt.Rectangle((-0.5, -0.5), 3.5, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template_right) +plt.text(1, 0.3, '$u_{i+1}^R$', fontsize=12, ha='center') + +# 设置标题和轴 +plt.title('(b) Right-side reconstruction', fontsize=14, pad=10) +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('right_side_reconstruction.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03d/testprj.py b/example/figure/1d/03d/testprj.py new file mode 100644 index 00000000..0dfeea5a --- /dev/null +++ b/example/figure/1d/03d/testprj.py @@ -0,0 +1,30 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(8, 1)) # 调整图形大小以匹配图片高度和宽度 + +# 绘制网格点 (红点) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5]) # 对应 i = -2 到 5 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制黑点 (在 x=-1 和 x=3) +plt.plot([-1, 3], [0, 0], 'ko', markersize=8) # 黑点 + +# 绘制 x=0 和 x=2 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=2, color='k', linestyle='--', alpha=0.5) + +# 绘制紫色矩形模板 (从 x=-1 到 x=2) +template = plt.Rectangle((-1, -0.5), 3, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template) + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('reconstruction_template.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03e/testprj.py b/example/figure/1d/03e/testprj.py new file mode 100644 index 00000000..c7dcbcdc --- /dev/null +++ b/example/figure/1d/03e/testprj.py @@ -0,0 +1,34 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(8, 1)) # 调整图形大小以匹配图片高度和宽度 + +# 绘制网格点和连接线 (红点和实线) +x_points = np.array([-2, -1, 0, 1, 2, 3, 4, 5]) # 对应 i = -2 到 5 +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制红点和连接线 +plt.plot(x_points, y_points, 'r-', linewidth=1) # 红色的实线连接所有点 +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点覆盖在实线上 + +# 绘制黑点 (在 x=-1 和 x=3) 及其连接线 +black_points = np.array([-1, 3]) +plt.plot(black_points, np.zeros_like(black_points), 'k-', linewidth=1) # 黑色的实线连接黑点 +plt.plot(black_points, np.zeros_like(black_points), 'ko', markersize=8) # 黑点覆盖在实线上 + +# 绘制 x=0 和 x=2 的虚线 +plt.axvline(x=0, color='k', linestyle='--', alpha=0.5) +plt.axvline(x=2, color='k', linestyle='--', alpha=0.5) + +# 绘制紫色矩形模板 (从 x=-1 到 x=2) +template = plt.Rectangle((-1, -0.5), 3, 1, color='purple', alpha=0.3) +plt.gca().add_patch(template) + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('reconstruction_template_with_lines.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03f/testprj.py b/example/figure/1d/03f/testprj.py new file mode 100644 index 00000000..4c302dd7 --- /dev/null +++ b/example/figure/1d/03f/testprj.py @@ -0,0 +1,44 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (默认红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘的红点 (i=-5, 5) 再次覆盖,确保颜色正确 +plt.plot([-5, 5], [0, 0], 'ro', markersize=8) # 确保边缘点为红点 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_lines.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03g/testprj.py b/example/figure/1d/03g/testprj.py new file mode 100644 index 00000000..bfde2db8 --- /dev/null +++ b/example/figure/1d/03g/testprj.py @@ -0,0 +1,48 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (默认红点) +plt.plot(x_points, y_points, 'ro', markersize=8) # 红点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘的红点 (i=-5, 5) 再次覆盖,确保颜色正确 +plt.plot([-5, 5], [0, 0], 'ro', markersize=8) # 确保边缘点为红点 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_labels.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03h/testprj.py b/example/figure/1d/03h/testprj.py new file mode 100644 index 00000000..398dc9aa --- /dev/null +++ b/example/figure/1d/03h/testprj.py @@ -0,0 +1,50 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制中间的红点 (i=-3, -2, -1, 0, 1, 2, 3) +middle_points_red = x_points[2:9] # 对应 i=-3, -2, -1, 0, 1, 2, 3 +plt.plot(middle_points_red, np.zeros_like(middle_points_red), 'ro', markersize=8) # 红点 + +# 绘制边缘的黑点 (i=-5, -4, 4, 5) +edge_points_black = np.array([-5, -4, 4, 5]) +plt.plot(edge_points_black, np.zeros_like(edge_points_black), 'ko', markersize=8) # 黑点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points_line = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points_line, np.zeros_like(middle_points_line), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_edge_black.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03i/testprj.py b/example/figure/1d/03i/testprj.py new file mode 100644 index 00000000..19fd98be --- /dev/null +++ b/example/figure/1d/03i/testprj.py @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制所有点 (内部红色,边缘黑色) +plt.scatter(x_points, y_points, s=100, facecolor='red', edgecolor='black', linewidth=1) # 点大小 s=100 对应 markersize=8 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_red_inside_black_edge.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03j/testprj.py b/example/figure/1d/03j/testprj.py new file mode 100644 index 00000000..e6033427 --- /dev/null +++ b/example/figure/1d/03j/testprj.py @@ -0,0 +1,49 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([x_points[:3], x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_middle_black_edge_black.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03k/testprj.py b/example/figure/1d/03k/testprj.py new file mode 100644 index 00000000..4cd0ff50 --- /dev/null +++ b/example/figure/1d/03k/testprj.py @@ -0,0 +1,53 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(10, 1)) # 调整图形大小以适应 11 个点 + +# 定义 11 个点的坐标 (从 i=-5 到 i=5) +x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([x_points[:3], x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = x_points[3:8] # 对应 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 (i=-4 到 i=-3, 和 i=4 到 i=3) +# 左边 (i=-4 到 i=-3) +left_edge_points = x_points[1:3] # 对应 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3) +right_edge_points = x_points[8:10] # 对应 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 添加右侧点 (4, 5) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(4, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位,使用 LaTeX 格式 +plt.text(5, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_with_edge_labels.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03l/testprj.py b/example/figure/1d/03l/testprj.py new file mode 100644 index 00000000..7fe6b351 --- /dev/null +++ b/example/figure/1d/03l/testprj.py @@ -0,0 +1,66 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义原始 11 个点的坐标 (从 i=-5 到 i=5) +original_x_points = np.array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]) +y_points = np.zeros_like(original_x_points) # 所有点在 y=0 线上 + +# 计算新的点坐标:仅左边的第 3 个点和第 4 个点 (i=-3, -2) 之间的距离变为原距离的两倍 +# 原距离为 1 (从 -3 到 -2),新距离为 2 +# 仅右边的第 3 个点和第 4 个点 (i=3, 2) 之间的距离变为原距离的两倍 +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +# 解释: +# - 左边:i=-5, -4 保持不变 (-5, -4) +# - 左边的第 3 个点 i=-3 保持在 -3 +# - 左边的第 4 个点 i=-2 移动到 -1 (距离从 -3 到 -1 为 2) +# - i=-1, 0, 1 保持不变 (-1, 0, 1) +# - 右边的第 3 个点 i=3 保持在 3 +# - 右边的第 4 个点 i=2 移动到 1 (距离从 3 到 1 为 2) +# - 右边:i=4, 5 保持不变 (4, 5) + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-5, -4, -3, 3, 4, 5 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -1, -1, 0, 1, 1) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-1, -1, 0, 1, 1 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -1, -1, 0, 1, 1) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-4 到 i=-3,新位置 -4 到 -3) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-4, -3 +# 绘制一半实线 (从 i=-4 到中间),一半虚线 (从中间到 i=-3) +x_half = np.linspace(-4, -3.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-3.5, -3, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=4 到 i=3,新位置 4 到 3) +right_edge_points = new_x_points[8:10] # 对应新位置 i=4, 3 +# 绘制一半实线 (从 i=4 到中间),一半虚线 (从中间到 i=3) +x_half_right = np.linspace(4, 3.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(3.5, 3, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-5, -4) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-5, -0.5, '-2', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '-1', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 + +# 添加右侧点 (4, 5) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(4, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位,使用 LaTeX 格式 +plt.text(5, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_adjusted_third_fourth_distance.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03m/testprj.py b/example/figure/1d/03m/testprj.py new file mode 100644 index 00000000..e4f2a2d0 --- /dev/null +++ b/example/figure/1d/03m/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点对应 new_x_points[:3] 和 new_x_points[8:] (i=-6, -5, -4, 4, 5, 6) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-6, -5, -4, 4, 5, 6 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-5 到 i=-4,新位置 -5 到 -4) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-5, -4 +# 绘制一半实线 (从 i=-5 到中间),一半虚线 (从中间到 i=-4) +x_half = np.linspace(-5, -4.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-4.5, -4, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=5 到 i=4,新位置 5 到 4) +right_edge_points = new_x_points[8:10] # 对应新位置 i=5, 4 +# 绘制一半实线 (从 i=5 到中间),一半虚线 (从中间到 i=4) +x_half_right = np.linspace(5, 4.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(4.5, 4, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-6, -5) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-6, -0.5, '-2', fontsize=12, ha='center') # 在 i=-6 下方 0.5 单位 +plt.text(-5, -0.5, '-1', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 + +# 添加右侧点 (5, 6) 下方的标签 "N+2" 和 "N+3",与点保持一定距离,并与左侧标签高度一致 +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位,使用 LaTeX 格式 +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=6 下方 0.5 单位,使用 LaTeX 格式 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_new_positions.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03n/testprj.py b/example/figure/1d/03n/testprj.py new file mode 100644 index 00000000..4fabfebc --- /dev/null +++ b/example/figure/1d/03n/testprj.py @@ -0,0 +1,60 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点对应 new_x_points[:3] 和 new_x_points[8:] (i=-6, -5, -4, 4, 5, 6) +edge_points = np.concatenate([new_x_points[:3], new_x_points[8:]]) # 对应 i=-6, -5, -4, 4, 5, 6 +plt.scatter(edge_points, np.zeros_like(edge_points), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 绘制边缘第 3 个点与第 4 个点之间的混合线 +# 左边 (i=-5 到 i=-4,新位置 -5 到 -4) +left_edge_points = new_x_points[1:3] # 对应新位置 i=-5, -4 +# 绘制一半实线 (从 i=-5 到中间),一半虚线 (从中间到 i=-4) +x_half = np.linspace(-5, -4.5, 10) # 实线部分 +plt.plot(x_half, np.zeros_like(x_half), 'k-', linewidth=1) # 黑实线 +x_half_dash = np.linspace(-4.5, -4, 10) # 虚线部分 +plt.plot(x_half_dash, np.zeros_like(x_half_dash), 'k--', linewidth=1) # 黑虚线 + +# 右边 (i=5 到 i=4,新位置 5 到 4) +right_edge_points = new_x_points[8:10] # 对应新位置 i=5, 4 +# 绘制一半实线 (从 i=5 到中间),一半虚线 (从中间到 i=4) +x_half_right = np.linspace(5, 4.5, 10) # 实线部分 +plt.plot(x_half_right, np.zeros_like(x_half_right), 'k-', linewidth=1) # 黑实线 +x_half_dash_right = np.linspace(4.5, 4, 10) # 虚线部分 +plt.plot(x_half_dash_right, np.zeros_like(x_half_dash_right), 'k--', linewidth=1) # 黑虚线 + +# 添加左侧点 (-6, -5) 下方的标签 "-2" 和 "-1",与点保持一定距离 +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_new_positions.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03o/testprj.py b/example/figure/1d/03o/testprj.py new file mode 100644 index 00000000..88132226 --- /dev/null +++ b/example/figure/1d/03o/testprj.py @@ -0,0 +1,52 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) # 调整图形大小以适应新的点分布 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +# 中间 5 个点对应 new_x_points[3:8] (i=-2, -1, 0, 1, 2) +# 其他点需手动指定,排除左侧 i=-4 和右侧 i=4 +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) # 对应 i=-6, -5, -4, 4, 5, 6,但 i=-4 和 i=4 单独处理 +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) # 红内黑边点 + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 (内部黑色,边缘黑色) +special_black_points = np.array([-4, 4]) # 对应新位置 i=-4, 4 +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) (内部黑色,边缘黑色,即纯黑色点) +middle_points = new_x_points[3:8] # 对应新位置 i=-2, -1, 0, 1, 2 +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) # 纯黑色点 + +# 绘制中间 5 个点的黑实线连接 (i=-2, -1, 0, 1, 2 对应新位置 -2, -1, 0, 1, 2) +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) # 黑实线 + +# 去掉左侧第二点和第三点的连线 (i=-5 到 i=-4),以及右侧第二点和第三点的连线 (i=5 到 i=4) +# 原代码中的混合线已移除,不再绘制: +# - 左边 (i=-5 到 i=-4) +# - 右边 (i=5 到 i=4) + +# 添加所有点的标签,与点保持一定距离,高度一致 +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') # 在 i=-6 下方 0.5 单位 +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') # 在 i=-5 下方 0.5 单位 +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') # 在 i=-4 下方 0.5 单位 +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') # 在 i=-2 下方 0.5 单位 +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') # 在 i=-1 下方 0.5 单位 +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') # 在 i=0 下方 0.5 单位 +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') # 在 i=1 下方 0.5 单位 +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') # 在 i=2 下方 0.5 单位 +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') # 在 i=4 下方 0.5 单位 +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') # 在 i=5 下方 0.5 单位 +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') # 在 i=6 下方 0.5 单位 + +# 设置轴 +plt.axis('equal') # 保持比例 +plt.axis('off') # 隐藏轴 + +# 保存或显示图形 +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03p/testprj.py b/example/figure/1d/03p/testprj.py new file mode 100644 index 00000000..fc2bc4b3 --- /dev/null +++ b/example/figure/1d/03p/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.linspace(-4, -2, 4) # 分割为三个等分 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.linspace(2, 4, 4) # 分割为三个等分 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03q/testprj.py b/example/figure/1d/03q/testprj.py new file mode 100644 index 00000000..28a2f6df --- /dev/null +++ b/example/figure/1d/03q/testprj.py @@ -0,0 +1,55 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 设置图形大小和样式 +plt.figure(figsize=(12, 1)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03r/testprj.py b/example/figure/1d/03r/testprj.py new file mode 100644 index 00000000..64e179da --- /dev/null +++ b/example/figure/1d/03r/testprj.py @@ -0,0 +1,79 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +x = -2.2 +y = -0.1 +width = 4.4 +height = 0.2 + +# 创建一个矩形对象 +#rect = patches.Rectangle((x, y), width, height, linewidth=1, edgecolor='none', facecolor=rectangle_color, zorder=0) + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges_with_rectangle.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03s/testprj.py b/example/figure/1d/03s/testprj.py new file mode 100644 index 00000000..ec92c788 --- /dev/null +++ b/example/figure/1d/03s/testprj.py @@ -0,0 +1,85 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[2:3], new_x_points[8:9], new_x_points[9:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点 (i=-2, -1, 0, 1, 2) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 5 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +x = -2.2 +y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('eleven_points_adjusted_edges_with_rectangle.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03t/testprj.py b/example/figure/1d/03t/testprj.py new file mode 100644 index 00000000..ebb6f484 --- /dev/null +++ b/example/figure/1d/03t/testprj.py @@ -0,0 +1,90 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:9] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 +#rectangle_color = 'lightblue' + +#x = -2.2 +#y = -0.1 +x = -1.2 +y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +ax.set_title('Right-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +#plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/03u/cfd.png b/example/figure/1d/03u/cfd.png new file mode 100644 index 00000000..c985f2cb Binary files /dev/null and b/example/figure/1d/03u/cfd.png differ diff --git a/example/figure/1d/03u/testprj.py b/example/figure/1d/03u/testprj.py new file mode 100644 index 00000000..cf28f21c --- /dev/null +++ b/example/figure/1d/03u/testprj.py @@ -0,0 +1,93 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +#new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +# 添加右起第三点和第四点之间的分段连线(2到4) +#x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04/testprj.py b/example/figure/1d/04/testprj.py new file mode 100644 index 00000000..dacad291 --- /dev/null +++ b/example/figure/1d/04/testprj.py @@ -0,0 +1,105 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 3)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 new_x_points) +new_x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(new_x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([new_x_points[:2], new_x_points[10:]]) +plt.scatter(edge_points_red, np.zeros_like(edge_points_red), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.zeros_like(special_black_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +middle_points = new_x_points[3:8] +plt.scatter(middle_points, np.zeros_like(middle_points), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.zeros_like(middle_points), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +#x_left = np.array([-4, -3.5, -2.5, -2]) # 按照1/4, 1/2, 1/4的比例分割 +#plt.plot([x_left[0], x_left[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +#plt.plot([x_left[1], x_left[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +#plt.plot([x_left[2], x_left[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 +plot_mixed_line(-4,-2) + +# 添加右起第三点和第四点之间的分段连线(2到4) +#x_right = np.array([3, 3.25, 3.75, 4]) # 按照1/4, 1/2, 1/4的比例分割 +#x_right = np.array([2, 2.5, 3.5, 4]) # 按照1/4, 1/2, 1/4的比例分割 +#plt.plot([x_right[0], x_right[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 +#plt.plot([x_right[1], x_right[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 +#plt.plot([x_right[2], x_right[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 +plot_mixed_line(2,4) + +xv = 0.5*(new_x_points[5]+new_x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, -0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, -0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, -0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, -0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, -0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, -0.5, '$i$', fontsize=12, ha='center') +plt.text(1, -0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, -0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, -0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, -0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, -0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, -0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, 0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, 0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, +0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, +0.3, '$x=L$', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04a/testprj.py b/example/figure/1d/04a/testprj.py new file mode 100644 index 00000000..8f8e0711 --- /dev/null +++ b/example/figure/1d/04a/testprj.py @@ -0,0 +1,101 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 2.5)) + +y0=0 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) +y_points = np.zeros_like(x_points) # 所有点在 y=0 线上 + +# 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) +edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) +plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + +# 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 +special_black_points = np.array([-4, 4]) +plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) +#middle_points = x_points[3:8] +middle_points = x_points[3:9] +plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + +# 绘制中间 6 个点的黑实线连接 +plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + +# 添加左起第三点和第四点之间的分段连线(-4到-2) +plot_mixed_line(-4,-2) + +# 添加右起第三点和第四点之间的分段连线(2到4) +plot_mixed_line(2,4) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [-0.5, 0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = -0.1 +#x = -1.2 +#y = -0.1 +width = 4.4 +height = 0.2 + +rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + +# 将矩形添加到坐标轴上 +ax = plt.gca() +ax.add_patch(rect) +#ax.set_title('Right-side reconstruction') +#ax.set_title('Left-side reconstruction') + +# 添加标签和其他设置(保持不变) +plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') +plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') +plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') +plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') +plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') +plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') +plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') +plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') +#plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') +plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') +plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') +plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + +#plt.text(xv+0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') +plt.text(xv-0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^L$', fontsize=12, ha='center') +plt.text(-4, y0++0.3, '$x=0$', fontsize=12, ha='center') +plt.text(+4, y0++0.3, '$x=L$', fontsize=12, ha='center') + +plt.text(0, y0+-1.5, '(a) Left-side reconstruction', fontsize=12, ha='center') + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04b/testprj.py b/example/figure/1d/04b/testprj.py new file mode 100644 index 00000000..b487524a --- /dev/null +++ b/example/figure/1d/04b/testprj.py @@ -0,0 +1,115 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [0, 0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [0, 0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [0, 0], 'k-', linewidth=1) # 第三段实线 + return + +def plot_cfd_line( x_points, y0 ): + # 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) + edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) + plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + + # 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 + special_black_points = np.array([-4, 4]) + plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) + #middle_points = x_points[3:8] + middle_points = x_points[3:9] + plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点的黑实线连接 + plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + + # 添加左起第三点和第四点之间的分段连线(-4到-2) + plot_mixed_line(-4,-2) + + # 添加右起第三点和第四点之间的分段连线(2到4) + plot_mixed_line(2,4) + + return + +def plot_rect(x, y, width, height, rectangle_color): + rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + + # 将矩形添加到坐标轴上 + ax = plt.gca() + ax.add_patch(rect) + return + +def plot_label(y0, xv, lr, txt_name): + # 添加标签和其他设置(保持不变) + plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') + plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') + plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') + plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') + plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') + plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') + plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') + plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') + #plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') + plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') + plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') + plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + + #plt.text(xv+0.3, y0+0.5, r'$u_{i+\frac{1}{2}}^R$', fontsize=12, ha='center') + lrname = r'$u_{i+\frac{1}{2}}^' + lr + r'$' + plt.text(xv-0.3, y0+0.5, lrname, fontsize=12, ha='center') + plt.text(-4, y0+0.3, '$x=0$', fontsize=12, ha='center') + plt.text(+4, y0+0.3, '$x=L$', fontsize=12, ha='center') + + plt.text(0, y0-1.5, txt_name, fontsize=12, ha='center') + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 2.5)) + +y0=0 + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6]) + +plot_cfd_line( x_points, y0 ) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [y0-0.5, y0+0.5], 'k--') # 绘制垂直线 + + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = y0-0.1 +#x = -1.2 +#y = y0-0.1 +width = 4.4 +height = 0.2 + +lr = 'L' +txt_name = '(a) Left-side reconstruction' + +plot_rect(x,y,width,height,rectangle_color) +plot_label(y0,xv,lr,txt_name) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04c/cfd.png b/example/figure/1d/04c/cfd.png new file mode 100644 index 00000000..d464467d Binary files /dev/null and b/example/figure/1d/04c/cfd.png differ diff --git a/example/figure/1d/04c/testprj.py b/example/figure/1d/04c/testprj.py new file mode 100644 index 00000000..2223baf4 --- /dev/null +++ b/example/figure/1d/04c/testprj.py @@ -0,0 +1,117 @@ +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed, y0 ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [y0, y0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [y0, y0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [y0, y0], 'k-', linewidth=1) # 第三段实线 + return + +def plot_cfd_line( x_points, y0 ): + # 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) + edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) + plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + + # 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 + special_black_points = np.array([-4, 4],dtype=np.float64) + plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) + #middle_points = x_points[3:8] + middle_points = x_points[3:9] + plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点的黑实线连接 + plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + + # 添加左起第三点和第四点之间的分段连线(-4到-2) + plot_mixed_line(-4,-2, y0) + + # 添加右起第三点和第四点之间的分段连线(2到4) + plot_mixed_line(2,4, y0) + + return + +def plot_rect(x, y, width, height, rectangle_color): + rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + + # 将矩形添加到坐标轴上 + ax = plt.gca() + ax.add_patch(rect) + return + +def plot_label(y0, xv, lr, txt_name): + # 添加标签和其他设置(保持不变) + plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') + plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') + plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') + plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') + plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') + plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') + plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') + plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') + #plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') + plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') + plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') + plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + + lrname = r'$u_{i+\frac{1}{2}}^' + lr + r'$' + plt.text(xv, y0+0.5, lrname, fontsize=12, ha='center') + plt.text(-4, y0+0.3, '$x=0$', fontsize=12, ha='center') + plt.text(+4, y0+0.3, '$x=L$', fontsize=12, ha='center') + + plt.text(0, y0-1.5, txt_name, fontsize=12, ha='center') + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6],dtype=np.float64) + +y0 = 0.5 +plot_cfd_line( x_points, y0 ) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [y0-0.5, y0+0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +x = -2.2 +y = y0-0.1 +#x = -1.2 +#y = y0-0.1 +width = 4.4 +height = 0.2 + +plot_rect(-2.2,y0-0.1,width,height,rectangle_color) +plot_label(y0,xv-0.3,'L','(a) Left-side reconstruction') + +y1 = -2.0 +plot_cfd_line( x_points, y1 ) +plt.plot([xv, xv], [y1-0.5, y1+0.5], 'k--') # 绘制垂直线 + +plot_rect(-1.2,y1-0.1,width,height,rectangle_color) +plot_label(y1,xv+0.3,'R','(b) Right-side reconstruction') + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04d/testprj.py b/example/figure/1d/04d/testprj.py new file mode 100644 index 00000000..6e9985af --- /dev/null +++ b/example/figure/1d/04d/testprj.py @@ -0,0 +1,118 @@ +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed, y0 ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [y0, y0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [y0, y0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [y0, y0], 'k-', linewidth=1) # 第三段实线 + return + +def plot_cfd_line( x_points, y0, lr ): + # 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) + edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) + plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + + # 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 + special_black_points = np.array([-4, 4],dtype=np.float64) + plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) + iend = 8 + if lr == 'R': + iend = 9 + middle_points = x_points[3:iend] + plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点的黑实线连接 + plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + + # 添加左起第三点和第四点之间的分段连线(-4到-2) + plot_mixed_line(-4,-2, y0) + + # 添加右起第三点和第四点之间的分段连线(2到4) + plot_mixed_line(2,4, y0) + + return + +def plot_rect(x, y, width, height, rectangle_color): + rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + + # 将矩形添加到坐标轴上 + ax = plt.gca() + ax.add_patch(rect) + return + +def plot_label(y0, xv, lr, txt_name): + # 添加标签和其他设置(保持不变) + plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') + plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') + plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') + if lr == 'L': + plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') + plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') + plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') + plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') + plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') + if lr == 'R': + plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') + + plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') + plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') + plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + + lrname = r'$u_{i+\frac{1}{2}}^' + lr + r'$' + plt.text(xv, y0+0.5, lrname, fontsize=12, ha='center') + plt.text(-4, y0+0.3, '$x=0$', fontsize=12, ha='center') + plt.text(+4, y0+0.3, '$x=L$', fontsize=12, ha='center') + + plt.text(0, y0-1.5, txt_name, fontsize=12, ha='center') + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6],dtype=np.float64) + +y0 = 0.5 +plot_cfd_line( x_points, y0, 'L' ) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [y0-0.5, y0+0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +width = 4.4 +height = 0.2 + +plot_rect(-2.2,y0-0.1,width,height,rectangle_color) +plot_label(y0,xv-0.3,'L','(a) Left-side reconstruction') + +y1 = -2.0 +plot_cfd_line( x_points, y1, 'R' ) +plt.plot([xv, xv], [y1-0.5, y1+0.5], 'k--') # 绘制垂直线 + +plot_rect(-1.2,y1-0.1,width,height,rectangle_color) +plot_label(y1,xv+0.3,'R','(b) Right-side reconstruction') + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/04e/testprj.py b/example/figure/1d/04e/testprj.py new file mode 100644 index 00000000..37535220 --- /dev/null +++ b/example/figure/1d/04e/testprj.py @@ -0,0 +1,125 @@ +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +def plot_mixed_line( xst, xed, y0 ): + ds = xed - xst + ds1 = ds / 4 + x1 = xst + ds1 + x2 = xed - ds1 + x = np.array([xst, x1, x2, xed]) # 按照1/4, 1/2, 1/4的比例分割 + plt.plot([x[0], x[1]], [y0, y0], 'k-', linewidth=1) # 第一段实线 + plt.plot([x[1], x[2]], [y0, y0], 'k--', linewidth=1) # 第二段虚线 + plt.plot([x[2], x[3]], [y0, y0], 'k-', linewidth=1) # 第三段实线 + return + +def plot_cfd_line( x_points, y0, lr ): + # 绘制除中间 5 个点和特定边缘点外的其他点 (内部红色,边缘黑色) + edge_points_red = np.concatenate([x_points[:2], x_points[10:]]) + plt.scatter(edge_points_red, np.full_like(edge_points_red, y0), s=100, facecolor='red', edgecolor='black', linewidth=1) + + # 绘制左侧第三点 (i=-4) 和右侧第三点 (i=4) 为纯黑色点 + special_black_points = np.array([-4, 4],dtype=np.float64) + plt.scatter(special_black_points, np.full_like(special_black_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点 (i=-2, -1, 0, 1, 2, 3) + iend = 8 + if lr == 'R': + iend = 9 + middle_points = x_points[3:iend] + plt.scatter(middle_points, np.full_like(middle_points, y0), s=100, facecolor='black', edgecolor='black', linewidth=1) + + # 绘制中间 6 个点的黑实线连接 + plt.plot(middle_points, np.full_like(middle_points, y0), 'k-', linewidth=1) + + # 添加左起第三点和第四点之间的分段连线(-4到-2) + xl_st = x_points[2] + xl_ed = x_points[3] + plot_mixed_line(xl_st,xl_ed, y0) + + # 添加右起第三点和第四点之间的分段连线(2到4) + ii = -4 + if lr == 'L': + ii = -5 + xr_st = x_points[ii] + xr_ed = x_points[-3] + plot_mixed_line(xr_st,xr_ed, y0) + + return + +def plot_rect(x, y, width, height, rectangle_color): + rect = patches.FancyBboxPatch((x, y), width, height, + boxstyle="round,pad=0.1,rounding_size=0.1", + edgecolor='none', + facecolor=rectangle_color, + zorder=0) + + # 将矩形添加到坐标轴上 + ax = plt.gca() + ax.add_patch(rect) + return + +def plot_label(y0, xv, lr, txt_name): + # 添加标签和其他设置(保持不变) + plt.text(-6, y0-0.5, '$-2$', fontsize=12, ha='center') + plt.text(-5, y0-0.5, '$-1$', fontsize=12, ha='center') + plt.text(-4, y0-0.5, '$i=1$', fontsize=12, ha='center') + if lr == 'L': + plt.text(-2, y0-0.5, '$i-2$', fontsize=12, ha='center') + plt.text(-1, y0-0.5, '$i-1$', fontsize=12, ha='center') + plt.text(0, y0-0.5, '$i$', fontsize=12, ha='center') + plt.text(1, y0-0.5, '$i+1$', fontsize=12, ha='center') + plt.text(2, y0-0.5, '$i+2$', fontsize=12, ha='center') + if lr == 'R': + plt.text(3, y0-0.5, '$i+3$', fontsize=12, ha='center') + + plt.text(4, y0-0.5, '$i=N+1$', fontsize=12, ha='center') + plt.text(5, y0-0.5, '$N+2$', fontsize=12, ha='center') + plt.text(6, y0-0.5, '$N+3$', fontsize=12, ha='center') + + lrname = r'$u_{i+\frac{1}{2}}^' + lr + r'$' + plt.text(xv, y0+0.5, lrname, fontsize=12, ha='center') + plt.text(-4, y0+0.3, '$x=0$', fontsize=12, ha='center') + plt.text(+4, y0+0.3, '$x=L$', fontsize=12, ha='center') + + plt.text(0, y0-1.5, txt_name, fontsize=12, ha='center') + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +# 定义新的点坐标 (从 i=-6 到 i=6,基于 x_points) +x_points = np.array([-6, -5, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6],dtype=np.float64) + +y0 = 0.5 +plot_cfd_line( x_points, y0, 'L' ) + +xv = 0.5*(x_points[5]+x_points[6]) +plt.plot([xv, xv], [y0-0.5, y0+0.5], 'k--') # 绘制垂直线 + +# 添加圆角矩形背景 +rectangle_color = (150/255, 150/255, 200/255) # RGB颜色 + +width = 4.4 +height = 0.2 + +plot_rect(-2.2,y0-0.1,width,height,rectangle_color) +plot_label(y0,xv-0.3,'L','(a) Left-side reconstruction') + +y1 = -2.0 +plot_cfd_line( x_points, y1, 'R' ) +plt.plot([xv, xv], [y1-0.5, y1+0.5], 'k--') # 绘制垂直线 + +plot_rect(-1.2,y1-0.1,width,height,rectangle_color) +plot_label(y1,xv+0.3,'R','(b) Right-side reconstruction') + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01/cfd.png b/example/figure/1d/eno/01/cfd.png new file mode 100644 index 00000000..049e581c Binary files /dev/null and b/example/figure/1d/eno/01/cfd.png differ diff --git a/example/figure/1d/eno/01/testprj.py b/example/figure/1d/eno/01/testprj.py new file mode 100644 index 00000000..11933f65 --- /dev/null +++ b/example/figure/1d/eno/01/testprj.py @@ -0,0 +1,69 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=10, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + + +def plot_label(x, xcc, yref): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + plt.text(x[0], yb, r'$x_{\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[-2], yb, r'$x_{N-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[-1], yb, r'$x_{N+\frac{1}{2}}$', fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=0$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=L$', fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 10 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01a/cfd.png b/example/figure/1d/eno/01a/cfd.png new file mode 100644 index 00000000..c0bb62c9 Binary files /dev/null and b/example/figure/1d/eno/01a/cfd.png differ diff --git a/example/figure/1d/eno/01a/testprj.py b/example/figure/1d/eno/01a/testprj.py new file mode 100644 index 00000000..47742090 --- /dev/null +++ b/example/figure/1d/eno/01a/testprj.py @@ -0,0 +1,113 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + + +def plot_label(x, xcc, yref): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[-2], yb, r'$x_{N-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[-1], yb, r'$x_{N+\frac{1}{2}}$', fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=0$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=L$', fontsize=12, ha='center') + + plt.text(xcc[0], ybc, r'$i=1$', fontsize=12, ha='center') + plt.text(xcc[1], ybc, r'$2$', fontsize=12, ha='center') + plt.text(xcc[-2], ybc, r'$N-1$', fontsize=12, ha='center') + plt.text(xcc[-1], ybc, r'$N$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01b/cfd.png b/example/figure/1d/eno/01b/cfd.png new file mode 100644 index 00000000..9b8bcc93 Binary files /dev/null and b/example/figure/1d/eno/01b/cfd.png differ diff --git a/example/figure/1d/eno/01b/testprj.py b/example/figure/1d/eno/01b/testprj.py new file mode 100644 index 00000000..53bce507 --- /dev/null +++ b/example/figure/1d/eno/01b/testprj.py @@ -0,0 +1,153 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + + +def plot_label(x, xcc, yref): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[-2], yb, r'$x_{N-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[-1], yb, r'$x_{N+\frac{1}{2}}$', fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=0$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=L$', fontsize=12, ha='center') + + plt.text(xcc[0], ybc, r'$i=1$', fontsize=12, ha='center') + plt.text(xcc[1], ybc, r'$2$', fontsize=12, ha='center') + plt.text(xcc[-2], ybc, r'$N-1$', fontsize=12, ha='center') + plt.text(xcc[-1], ybc, r'$N$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + + str = r'$a=x_{\frac{1}{2}} 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + #mystr = strn + ss + f'{abs(i)}' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + #mystr = '0' + else: + mystr = r'$'+ strn + r'$' + #mystr = strn + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + r'}{2}}' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = -1 + 2 * ishift + i2 = i1 - 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 0+ishift + i2 = i1-1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +x_ghost_l = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost, dtype=np.float64) +x_ghost_r = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01g/testprj.py b/example/figure/1d/eno/01g/testprj.py new file mode 100644 index 00000000..570d6ee2 --- /dev/null +++ b/example/figure/1d/eno/01g/testprj.py @@ -0,0 +1,313 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + #mystr = strn + ss + f'{abs(i)}' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + #mystr = '0' + else: + mystr = r'$'+ strn + r'$' + #mystr = strn + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + #mystr = r'x_{' + strn + ss + r'\frac{' + r'}{2}}' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = -1 + 2 * ishift + i2 = i1 - 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 0+ishift + i2 = i1-1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +x_ghost_l = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost, dtype=np.float64) +x_ghost_r = np.zeros(nghost+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01h/testprj.py b/example/figure/1d/eno/01h/testprj.py new file mode 100644 index 00000000..5f703ef0 --- /dev/null +++ b/example/figure/1d/eno/01h/testprj.py @@ -0,0 +1,310 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + stri = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + i1 = 2*(1+ishift)+1 + i2 = i1 + 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + plt.text(xg[1], yb, str1, fontsize=12, ha='center') + plt.text(xg[2], yb, str2, fontsize=12, ha='center') + + i1 = 1+ishift + i2 = i1+1 + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xgcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xgcc[1], ybc, str2, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01i/testprj.py b/example/figure/1d/eno/01i/testprj.py new file mode 100644 index 00000000..ca246420 --- /dev/null +++ b/example/figure/1d/eno/01i/testprj.py @@ -0,0 +1,307 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('N', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('N',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01i0/testprj.py b/example/figure/1d/eno/01i0/testprj.py new file mode 100644 index 00000000..52b8dc29 --- /dev/null +++ b/example/figure/1d/eno/01i0/testprj.py @@ -0,0 +1,307 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('N', i1) + str2 = genstrXNhalf('N', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift + i2 = i1 + 1 + + str1 = genstrNp('',i1) + str2 = genstrNp('',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('N',i1) + str2 = genstrNp('N',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 0+ishift-igc + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('N', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('N',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j/testprj.py b/example/figure/1d/eno/01j/testprj.py new file mode 100644 index 00000000..f96daea4 --- /dev/null +++ b/example/figure/1d/eno/01j/testprj.py @@ -0,0 +1,314 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + str1 = genstrNp('ist',i1) + str2 = genstrNp('ist',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1) + str2 = genstrNp('ied',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +#ishift = -1 +ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j0/testprj.py b/example/figure/1d/eno/01j0/testprj.py new file mode 100644 index 00000000..0193b895 --- /dev/null +++ b/example/figure/1d/eno/01j0/testprj.py @@ -0,0 +1,318 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + iii = ighost + 1 + ist = (1 + ishift) + iii + + #str1 = genstrNp(f'ist={ist}',i1) + str1 = genstrNp('ist',i1) + str2 = genstrNp('ist',i2) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1) + str2 = genstrNp('ied',i2) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * igc + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/01j1/testprj.py b/example/figure/1d/eno/01j1/testprj.py new file mode 100644 index 00000000..ae1f2bb3 --- /dev/null +++ b/example/figure/1d/eno/01j1/testprj.py @@ -0,0 +1,315 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 1 and i < im: + continue + if i > ip and i < nx-2: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_ghost_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='red', edgecolor='black', linewidth=1) + return + +def plot_ghost_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + ip = ii + 1 + + for i in range(0, nxc): + if i > 1 and i < im: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip and i < nx-2: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def addDollarString(str_in): + mystr = '$' + str_in + '$' + return mystr + +def removeDollarString(str_in): + mystr = str_in.strip("$") + return mystr + +def genstrNp(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$' + strn + ss + f'{abs(i)}'+r'$' + else: + if strn == '': + mystr = r'$'+ '0' + r'$' + else: + mystr = r'$'+ strn + r'$' + return mystr + +def genstrXNhalf(strn, i): + if i != 0: + ai = abs(i) + if i > 0: + ss = '+' + else: + ss = '-' + mystr = r'$x_{' + strn + ss + r'\frac{' + f'{ai}' + r'}{2}}$' + else: + mystr = r'$x_{' + strn + ss + r'\frac{' + r'}{2}}$' + return mystr + +def plot_label(x, xcc, yref, ishift): + x0 = x[0] + dx = x[1] - x[0] + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + str_list = [] + str_list.append('$a=') + + ighost = 2 + iighost = ighost + 1 + + i1 = 2 * ( 1 + ishift ) - 1 + 2 * iighost + i2 = i1 + 2 + + str1 = genstrXNhalf('', i1) + str2 = genstrXNhalf('', i2) + str_list.append(removeDollarString(str1)) + str_list.append('<') + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(r'\cdots') + str_list.append('<') + + plt.text(x[0], yb, str1, fontsize=12, ha='center') + plt.text(x[1], yb, str2, fontsize=12, ha='center') + + i1 = 2 * ( 1 + ishift + ast ) - 1 + i2 = i1 - 2 + + str1 = genstrXNhalf('ied', i1) + str2 = genstrXNhalf('ied', i2) + + str_list.append(removeDollarString(str2)) + str_list.append('<') + str_list.append(removeDollarString(str1)) + str_list.append('=b$') + + plt.text(x[-1], yb, str1, fontsize=12, ha='center') + plt.text(x[-2], yb, str2, fontsize=12, ha='center') + + plt.text(x[0], yt, r'$x=a$', fontsize=12, ha='center') + plt.text(x[-1], yt, r'$x=b$', fontsize=12, ha='center') + + i1 = 1 + ishift - 1 + i2 = i1 + 1 + + str1 = genstrNp('ist',i1+ast) + str2 = genstrNp('ist',i2+ast) + + plt.text(xcc[0], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[1], ybc, str2, fontsize=12, ha='center') + + i1 = ishift + i2 = i1 - 1 + + str1 = genstrNp('ied',i1+ast) + str2 = genstrNp('ied',i2+ast) + + plt.text(xcc[-1], ybc, str1, fontsize=12, ha='center') + plt.text(xcc[-2], ybc, str2, fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + ip = i + 1 + + s1 = genstrNp('i',-1) + s2 = genstrNp('i',0) + s3 = genstrNp('i',+1) + + plt.text(xcc[im], ybc, s1, fontsize=12, ha='center') + plt.text(xcc[i], ybc, s2, fontsize=12, ha='center') + plt.text(xcc[ip], ybc, s3, fontsize=12, ha='center') + + sss = '' + for item in str_list: + sss += item + + print(f'{sss=}') + + str = 'Grid: ' + sss + + nx = xcc.size + ii = nx // 2 + + plt.text(x[ii], yb-dx, str, fontsize=12, ha='center') + + return + +def plot_ghost_label_left(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + ighost = 2 + iighost = ighost + 1 + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) - 1 + ii = 2 * ii + 1 + #ii = -1 + 2 * ishift - 2 * igc + strii = genstrXNhalf('', ii) + plt.text(xg[igc+1], yb, strii, fontsize=12, ha='center') + + for igc in range(ngc): + ii = iighost+( 0+ishift-igc ) + strii = genstrNp('',ii) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + + +def plot_ghost_label_right(xg, xgcc, yref, ishift): + dx = abs(xg[1] - xg[0]) + dyb = 0.8 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + + ng = xg.shape[0] + ngc = ng - 1 + print(f'{ng=}') + + for igc in range(ngc): + ii = 3 + 2 * ishift + 2 * (igc+ast) + stri = genstrXNhalf('ied', ii) + plt.text(xg[igc+1], yb, stri, fontsize=12, ha='center') + + for igc in range(ngc): + ii = 1+ishift+igc + strii = genstrNp('ied',ii+ast) + plt.text(xgcc[igc], ybc, strii, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +nghost = 2 +nghost_l = nghost + 1 +nghost_r = nghost + +x_ghost_l = np.zeros(nghost_l+1, dtype=np.float64) +xcc_ghost_l = np.zeros(nghost_l, dtype=np.float64) +x_ghost_r = np.zeros(nghost_r+1, dtype=np.float64) +xcc_ghost_r = np.zeros(nghost_r, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +x_ghost_l[0] = x[0] +for ighost in range(1, nghost_l+1): + dx = x[0] - x[ighost] + x_ghost_l[ighost] = x[0] + dx + +for ighost in range(0, nghost_l): + xcc_ghost_l[ighost] = 0.5*(x_ghost_l[ighost]+x_ghost_l[ighost+1]) + + +x_ghost_r[0] = x[nx] +for ighost in range(1, nghost_r+1): + dx = x[nx] - x[nx-ighost] + x_ghost_r[ighost] = x[nx] + dx + +for ighost in range(0, nghost_r): + xcc_ghost_r[ighost] = 0.5*(x_ghost_r[ighost]+x_ghost_r[ighost+1]) + +print("x=",x) +print("xcc=",xcc) + +print("x_ghost_l=",x_ghost_l) +print("xcc_ghost_l=",xcc_ghost_l) +print("x_ghost_r=",x_ghost_r) +print("xcc_ghost_r=",xcc_ghost_r) + +yref = 0.0 + +plot_ghost_cell_center( xcc_ghost_l,yref ) +plot_ghost_cell_center( xcc_ghost_r,yref ) + +plot_ghost_mesh( x_ghost_l, yref ) +plot_ghost_mesh( x_ghost_r, yref ) + +ishift = -1 +#ishift = 0 +ast = 1 +plot_ghost_label_left(x_ghost_l, xcc_ghost_l, yref, ishift) +plot_ghost_label_right(x_ghost_r, xcc_ghost_r, yref, ishift) + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref, ishift) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02/testprj.py b/example/figure/1d/eno/02/testprj.py new file mode 100644 index 00000000..c818c076 --- /dev/null +++ b/example/figure/1d/eno/02/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + for xm in x: + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + # + + nxc = x.size - 1 + ii = nxc // 2 + im = ii - 1 + im1 = ii - 2 + ip = ii + 1 + ip1 = ii + 2 + + for i in range(0, nxc): + if i > 0 and i < im1: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + elif i > ip1 and i < nx-1: + plt.plot([x[i], x[i+1]], [yref, yref], 'k--', linewidth=1) + else : + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + #plt.plot(x, np.full_like(x, yref), 'k--', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-r-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-r+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[6], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[7], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[8], yb, r'$x_{i+s-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[9], yb, r'$x_{i+s+\frac{1}{2}}$', fontsize=12, ha='center') + + plt.text(xcc[0], ybc, r'$i-r$', fontsize=12, ha='center') + plt.text(xcc[1], ybc, r'$\cdots\cdots$', fontsize=12, ha='center') + plt.text(xcc[-2], ybc, r'$\cdots\cdots$', fontsize=12, ha='center') + plt.text(xcc[-1], ybc, r'$i+s$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 9 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 + +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +plot_label(x, xcc, yref) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02a/testprj.py b/example/figure/1d/eno/02a/testprj.py new file mode 100644 index 00000000..1a40cb5e --- /dev/null +++ b/example/figure/1d/eno/02a/testprj.py @@ -0,0 +1,150 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=2 +s=0 +plot_label(x, xcc, yref, r, s) + + +yref = -0.2 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=1 +s=1 +plot_label(x, xcc, yref, r, s) + + +yref = -0.4 +plot_cell_center( xcc, yref ) +plot_mesh( x, yref ) +r=0 +s=2 +plot_label(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02b/testprj.py b/example/figure/1d/eno/02b/testprj.py new file mode 100644 index 00000000..4f42af07 --- /dev/null +++ b/example/figure/1d/eno/02b/testprj.py @@ -0,0 +1,159 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh( x, yref ) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02c/testprj.py b/example/figure/1d/eno/02c/testprj.py new file mode 100644 index 00000000..76fcc7a4 --- /dev/null +++ b/example/figure/1d/eno/02c/testprj.py @@ -0,0 +1,188 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + print("ncell=",ncell) + print("idc=",idc) + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + ii = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02d/testprj.py b/example/figure/1d/eno/02d/testprj.py new file mode 100644 index 00000000..a01ded55 --- /dev/null +++ b/example/figure/1d/eno/02d/testprj.py @@ -0,0 +1,204 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +yref = 0.0 +r=2 +s=0 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.2 +r=1 +s=1 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=0 +s=2 +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02e/cfd.png b/example/figure/1d/eno/02e/cfd.png new file mode 100644 index 00000000..926d6cd4 Binary files /dev/null and b/example/figure/1d/eno/02e/cfd.png differ diff --git a/example/figure/1d/eno/02e/testprj.py b/example/figure/1d/eno/02e/testprj.py new file mode 100644 index 00000000..771deebb --- /dev/null +++ b/example/figure/1d/eno/02e/testprj.py @@ -0,0 +1,218 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +yref = 0.0 +r=rv[0] +s=sv[0] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +yref = -0.2 +r=rv[1] +s=sv[1] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + + +yref = -0.4 +r=rv[2] +s=sv[2] +plot_cell_center_rs( xcc, yref, r, s) +plot_mesh_rs( x, yref, r, s) +plot_label_rs(x, xcc, yref, r, s) + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02f/testprj.py b/example/figure/1d/eno/02f/testprj.py new file mode 100644 index 00000000..9b958f8e --- /dev/null +++ b/example/figure/1d/eno/02f/testprj.py @@ -0,0 +1,209 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + plt.text(xm, yb, name, fontsize=12, ha='center') + + + #plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + #plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + #plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + #plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 5)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02g/cfd.png b/example/figure/1d/eno/02g/cfd.png new file mode 100644 index 00000000..7e9f01ca Binary files /dev/null and b/example/figure/1d/eno/02g/cfd.png differ diff --git a/example/figure/1d/eno/02g/testprj.py b/example/figure/1d/eno/02g/testprj.py new file mode 100644 index 00000000..108286a7 --- /dev/null +++ b/example/figure/1d/eno/02g/testprj.py @@ -0,0 +1,207 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.5* dyt + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +k=3 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02h/cfd.png b/example/figure/1d/eno/02h/cfd.png new file mode 100644 index 00000000..aaea00d6 Binary files /dev/null and b/example/figure/1d/eno/02h/cfd.png differ diff --git a/example/figure/1d/eno/02h/testprj.py b/example/figure/1d/eno/02h/testprj.py new file mode 100644 index 00000000..83bb22ec --- /dev/null +++ b/example/figure/1d/eno/02h/testprj.py @@ -0,0 +1,208 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.5* dyt + namelist = [] + namelist.append(r'$x_{i-\frac{5}{2}}$') + namelist.append(r'$x_{i-\frac{3}{2}}$') + namelist.append(r'$x_{i-\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{1}{2}}$') + namelist.append(r'$x_{i+\frac{3}{2}}$') + namelist.append(r'$x_{i+\frac{5}{2}}$') + + nx = xcc.size + ii = nx // 2 + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i] ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 5 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +#k=3 +k=2 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/02i/testprj.py b/example/figure/1d/eno/02i/testprj.py new file mode 100644 index 00000000..9407c2ea --- /dev/null +++ b/example/figure/1d/eno/02i/testprj.py @@ -0,0 +1,221 @@ +import numpy as np +import matplotlib.pyplot as plt + +def plot_all_cell_center( xcc, yref ): + plt.scatter(xcc, np.full_like(xcc, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center( xcc, yref ): + nx = xcc.size + ii = nx // 2 + im = ii - 1 + ip = ii + 1 + xcc_new = [] + for i in range(0, nx): + if i > 0 and i < im: + continue + if i > ip and i < nx-1: + continue + xcc_new.append( xcc[i] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_cell_center_rs( xcc, yref, r, s ): + nx = xcc.size + ii = nx // 2 + xcc_new = [] + for m in range(-r, s+1): + xcc_new.append( xcc[ii+m] ) + plt.scatter(xcc_new, np.full_like(xcc_new, yref), s=20, facecolor='black', edgecolor='black', linewidth=1) + return + +def plot_mesh( x, yref ): + dx = x[1] - x[0] + dy = 0.1 * dx + nx = x.size + for i in range(0, nx): + xm = x[i] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + nxc = x.size - 1 + + for i in range(0, nxc): + plt.plot([x[i], x[i+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_mesh_rs( x, yref, r, s): + dx = x[1] - x[0] + dy = 0.1 * dx + + nxc = xcc.size + ii = nxc // 2 + + idc = [] + + for m in range(-r, s+1): + #print(f'm={m}, r={r}, s={s}') + idc.append( ii+m ) + #print(f"idc={idc}") + idv = idc.copy() + idv.append(idc[-1]+1) + + ncell = len( idc ) + nvertex = len( idv ) + for i in range(0, nvertex): + xm = x[ idv[i] ] + plt.plot([xm, xm], [yref-dy, yref+dy], 'k-') # 绘制垂直线 + + for i in range(0, ncell): + plt.plot([x[idc[i]], x[idc[i]+1]], [yref, yref], 'b-', linewidth=1) + return + +def plot_label(x, xcc, yref): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + plt.text(x[0], yb, r'$x_{i-\frac{5}{2}}$', fontsize=12, ha='center') + plt.text(x[1], yb, r'$x_{i-\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[2], yb, r'$x_{i-\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[3], yb, r'$x_{i+\frac{1}{2}}$', fontsize=12, ha='center') + plt.text(x[4], yb, r'$x_{i+\frac{3}{2}}$', fontsize=12, ha='center') + plt.text(x[5], yb, r'$x_{i+\frac{5}{2}}$', fontsize=12, ha='center') + + nx = xcc.size + i = nx // 2 + print("i=",i) + im = i - 1 + im1 = i - 2 + ip = i + 1 + ip1 = i + 2 + + plt.text(xcc[im1], ybc, r'$i-2$', fontsize=12, ha='center') + plt.text(xcc[im], ybc, r'$i-1$', fontsize=12, ha='center') + plt.text(xcc[i], ybc, r'$i$', fontsize=12, ha='center') + plt.text(xcc[ip], ybc, r'$i+1$', fontsize=12, ha='center') + plt.text(xcc[ip1], ybc, r'$i+2$', fontsize=12, ha='center') + return + +def plot_label_rs(x, xcc, yref, r, s): + dx = x[1] - x[0] + dyb = 0.5 * dx + dyt = dyb * 0.6 + yb = yref - dyb + yt = yref + dyt + ybc = yref - 0.5* dyb + ytt = yref + 0.8* dyt + k=r+s+1 + namelist = [] + for m in range(k - 1, -1, -1): + j = 1 + 2 * m + str = r'$x_{i-\frac{' + f'{j}' + r'}{2}}$' + namelist.append(str) + for m in range(0, k): + j = 1 + 2 * m + str = r'$x_{i+\frac{' + f'{j}' + r'}{2}}$' + namelist.append(str) + print(f'{namelist=}') + print(f'{len(namelist)=}') + print(f'{r=},{s=}') + + for i in range(len(namelist)): + print(f'namelist[{i}]={namelist[i]}') + + nx = xcc.size + ii = nx // 2 + + print(f'{ii=},{nx=}') + + idc = [] + for m in range(-r, s+1): + idc.append( ii+m ) + idv = idc.copy() + idv.append(idc[-1]+1) + print(f'{idc=}') + print(f'{idv=}') + + ncell = len( idc ) + nvertex = len( idv ) + + for i in range(0, nvertex): + xm = x[ idv[i] ] + name = namelist[ idv[i]-1 ] + #plt.text(xm, yb, name, fontsize=12, ha='center') + plt.text(xm, ytt, name, fontsize=12, ha='center') + + for m in range(-r, s+1): + ss = '-' + if m > 0 : + ss = '+' + str = r'$i' + ss + f'{abs(m)}' + r'$' + if m == 0 : + plt.text(xcc[ii+m], ybc, r'$i$', fontsize=12, ha='center') + else: + plt.text(xcc[ii+m], ybc, str, fontsize=12, ha='center') + + str = r'$' + f'({r=},{s=})' + r'$' + ishift = (-r+s)//2 + plt.text(xcc[ii+ishift], yb, str, fontsize=12, ha='center') + + return + +def getrs(k,rv,sv): + kk = k-1 + for m in range(0, k): + s = m + r = kk - s + rv.append( r ) + sv.append( s ) + return + +# 设置字体为 Times New Roman +plt.rc('text', usetex=True) +plt.rc('font', family='serif', serif=['Times New Roman']) + +# 设置图形大小和样式 +plt.figure(figsize=(12, 6)) + +nx = 8 +L = 1.0 +x_l = 0.0 +dx = L / nx + +x = np.zeros(nx+1, dtype=np.float64) +xcc = np.zeros(nx, dtype=np.float64) + +for i in range(0, nx+1): + x[i] = x_l + dx*(i) + +for i in range(0, nx): + xcc[i] = 0.5*(x[i]+x[i+1]) + +print("x=",x) +print("xcc=",xcc) + +#k=3 +k=4 +rv = [] +sv = [] +getrs(k,rv,sv) +print(f'{rv=},{sv=}') + +dyref = 0.2 + +size = len(rv) +print(f'{size=}') +for i in range(0, size): + yref = 0.0 - i * dyref + r=rv[i] + s=sv[i] + plot_cell_center_rs( xcc, yref, r, s) + plot_mesh_rs( x, yref, r, s) + plot_label_rs(x, xcc, yref, r, s) + + +plt.axis('equal') +plt.axis('off') + +plt.savefig('cfd.png', bbox_inches='tight', dpi=300) +plt.show() \ No newline at end of file diff --git a/example/figure/1d/eno/latex/01/README.txt b/example/figure/1d/eno/latex/01/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/01/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/01/plot.tex b/example/figure/1d/eno/latex/01/plot.tex new file mode 100644 index 00000000..ff9a33d9 --- /dev/null +++ b/example/figure/1d/eno/latex/01/plot.tex @@ -0,0 +1,41 @@ +\documentclass{article} +\usepackage{amsmath} +\begin{document} + +\section*{Results for different values of $k$ and $r$} + +\subsection*{$k=1$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{0} \bar{v}_{i} +\end{array} +\end{equation} + +\subsection*{$k=2$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{01} \bar{v}_{i} + c_{00} \bar{v}_{i+1}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\subsection*{$k=3$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{20} \bar{v}_{i-2} + c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 2 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{11} \bar{v}_{i-1} + c_{10} \bar{v}_{i} + c_{01} \bar{v}_{i+1}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{02} \bar{v}_{i} + c_{01} \bar{v}_{i+1} + c_{00} \bar{v}_{i+2}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\subsection*{$k=4$} +\begin{equation} +\begin{array}{l} +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{30} \bar{v}_{i-3} + c_{20} \bar{v}_{i-2} + c_{10} \bar{v}_{i-1} + c_{00} \bar{v}_{i}, \quad \text{if } r = 3 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{21} \bar{v}_{i-2} + c_{11} \bar{v}_{i-1} + c_{10} \bar{v}_{i} + c_{01} \bar{v}_{i+1}, \quad \text{if } r = 2 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{12} \bar{v}_{i-1} + c_{11} \bar{v}_{i} + c_{10} \bar{v}_{i+1} + c_{02} \bar{v}_{i+2}, \quad \text{if } r = 1 \\ +\displaystyle v_{i+\frac{1}{2}}^{-} = c_{03} \bar{v}_{i} + c_{02} \bar{v}_{i+1} + c_{01} \bar{v}_{i+2} + c_{00} \bar{v}_{i+3}, \quad \text{if } r = 0 +\end{array} +\end{equation} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02/README.txt b/example/figure/1d/eno/latex/02/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02/plot.tex b/example/figure/1d/eno/latex/02/plot.tex new file mode 100644 index 00000000..4566e2ca --- /dev/null +++ b/example/figure/1d/eno/latex/02/plot.tex @@ -0,0 +1,78 @@ +\documentclass{ctexart} +\usepackage{amsmath} +\begin{document} + +\section{三阶精度边界值近似推导} + +\subsection{问题描述} +已知单元格中心为 \(x_{i-1}, x_i, x_{i+1}\),对应的平均值为 \(\bar{u}_{i-1}, \bar{u}_i, \bar{u}_{i+1}\)。目标是用线性组合: +\[ +u_{i+1/2} \approx a \bar{u}_{i-1} + b \bar{u}_i + c \bar{u}_{i+1} +\] +逼近右边界 \(x_{i+1/2}\) 处的值,并证明此近似具有三阶精度。 + +\subsection{推导过程} + +\subsubsection{泰勒展开单元格平均值} +假设解 \(u(x)\) 充分光滑,以 \(x_i\) 为中心进行泰勒展开,单元格平均值的定义式为: +\[ +\bar{u}_j = \frac{1}{\Delta x} \int_{x_j - \Delta x/2}^{x_j + \Delta x/2} u(x) dx +\] +对每个单元格进行展开(保留到三次项): + +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \int_{x_{i-1} - \Delta x/2}^{x_{i-1} + \Delta x/2} \left[ u_i - u'_i \Delta x + \frac{u''_i}{2} (\Delta x)^2 - \frac{u'''_i}{6} (\Delta x)^3 + \dots \right] dx \notag \\ +&= u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4), \\ +\bar{u}_i &= \frac{1}{\Delta x} \int_{x_i - \Delta x/2}^{x_i + \Delta x/2} \left[ u_i + u'_i (x - x_i) + \frac{u''_i}{2} (x - x_i)^2 + \dots \right] dx \notag \\ +&= u_i + \frac{1}{24} u''_i (\Delta x)^2 + \mathcal{O}(\Delta x^4), \\ +\bar{u}_{i+1} &= \frac{1}{\Delta x} \int_{x_{i+1} - \Delta x/2}^{x_{i+1} + \Delta x/2} \left[ u_i + u'_i \Delta x + \frac{u''_i}{2} (\Delta x)^2 + \frac{u'''_i}{6} (\Delta x)^3 + \dots \right] dx \notag \\ +&= u_i + u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 + \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\end{align} + +\subsubsection{边界值的泰勒展开} +将 \(u_{i+1/2}\) 在 \(x_i\) 处展开: +\begin{equation} +u_{i+1/2} = u_i + \frac{1}{2} u'_i \Delta x + \frac{1}{8} u''_i (\Delta x)^2 + \frac{1}{48} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\end{equation} + +\subsubsection{匹配系数} +将线性组合 \(a \bar{u}_{i-1} + b \bar{u}_i + c \bar{u}_{i+1}\) 代入泰勒展开式,要求其与 \(u_{i+1/2}\) 的展开一致。比较各阶项的系数: + +\begin{align} +\text{常数项:} & \quad a + b + c = 1, \\ +\text{一阶项:} & \quad (-a + c) \Delta x = \frac{1}{2} \Delta x \ \Rightarrow \ -a + c = \frac{1}{2}, \\ +\text{二阶项:} & \quad \frac{13a + b + 13c}{24} (\Delta x)^2 = \frac{1}{8} (\Delta x)^2 \ \Rightarrow \ 13a + b + 13c = 3, \\ +\text{三阶项:} & \quad \frac{-5a + 5c}{24} (\Delta x)^3 = \frac{1}{48} (\Delta x)^3 \ \Rightarrow \ -5a + 5c = \frac{1}{2}. +\end{align} + +联立方程组: +\[ +\begin{cases} +a + b + c = 1, \\ +-a + c = \frac{1}{2}, \\ +13a + b + 13c = 3, \\ +-5a + 5c = \frac{1}{2}. +\end{cases} +\] +解得唯一解: +\[ +a = -\frac{1}{6}, \quad b = \frac{5}{6}, \quad c = \frac{1}{3}. +\] + +\subsubsection{误差分析} +将系数代入线性组合,计算误差: +\[ +\text{误差} = \left(-\frac{1}{6} \bar{u}_{i-1} + \frac{5}{6} \bar{u}_i + \frac{1}{3} \bar{u}_{i+1}\right) - u_{i+1/2}. +\] +展开后误差项为: +\[ +\left(\frac{-5a + 5c}{24} - \frac{1}{48}\right) u'''_i (\Delta x)^3 = \left(\frac{5}{36} - \frac{1}{48}\right) u'''_i (\Delta x)^3 = \mathcal{O}(\Delta x^3). +\] +因此,近似具有三阶精度。 + +\subsection{结论} +最终重构公式为: +\[ +u_{i+1/2} = -\frac{1}{6} \bar{u}_{i-1} + \frac{5}{6} \bar{u}_i + \frac{1}{3} \bar{u}_{i+1} + \mathcal{O}(\Delta x^3). +\] +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02a/README.txt b/example/figure/1d/eno/latex/02a/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02a/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02a/plot.tex b/example/figure/1d/eno/latex/02a/plot.tex new file mode 100644 index 00000000..5ac3f1c1 --- /dev/null +++ b/example/figure/1d/eno/latex/02a/plot.tex @@ -0,0 +1,76 @@ +\documentclass{article} +\usepackage{amsmath} +\begin{document} + +\section{Derivation of Cell Average Expansion for $\bar{u}_{i-1}$} + +\subsection{Definition of Cell Average} +The cell average for cell $i-1$ is defined as: +\[ +\bar{u}_{i-1} = \frac{1}{\Delta x} \int_{x_{i-1}-\Delta x/2}^{x_{i-1}+\Delta x/2} u(x) dx. +\] +Given $x_{i-1} = x_i - \Delta x$, the integration interval becomes: +\[ +x \in \left[ x_i - \frac{3\Delta x}{2}, x_i - \frac{\Delta x}{2} \right]. +\] + +\subsection{Taylor Expansion about $x_i$} +Expand $u(x)$ around $x_i$ up to third-order terms: +\[ +u(x) = u_i + u'_i (x - x_i) + \frac{u''_i}{2} (x - x_i)^2 + \frac{u'''_i}{6} (x - x_i)^3 + \mathcal{O}(\Delta x^4). +\] + +\subsection{Variable Substitution} +Let $y = x - x_i$, then the integration limits become: +\[ +y \in \left[ -\frac{3\Delta x}{2}, -\frac{\Delta x}{2} \right]. +\] +The cell average transforms to: +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \int_{-3\Delta x/2}^{-\Delta x/2} \left[ u_i + u'_i y + \frac{u''_i}{2} y^2 + \frac{u'''_i}{6} y^3 \right] dy \notag \\ +&\quad + \mathcal{O}(\Delta x^4). +\end{align} + +\subsection{Term-by-Term Integration} +\subsubsection{Constant Term} +\[ +\int_{-3\Delta x/2}^{-\Delta x/2} u_i dy = u_i \left[ y \right]_{-3\Delta x/2}^{-\Delta x/2} = u_i \Delta x. +\] + +\subsubsection{First-Order Term} +\[ +u'_i \int_{-3\Delta x/2}^{-\Delta x/2} y dy = u'_i \left[ \frac{y^2}{2} \right]_{-3\Delta x/2}^{-\Delta x/2} = -u'_i \Delta x^2. +\] + +\subsubsection{Second-Order Term} +\[ +\frac{u''_i}{2} \int_{-3\Delta x/2}^{-\Delta x/2} y^2 dy = \frac{u''_i}{2} \left( \frac{13}{12}\Delta x^3 \right) = \frac{13}{24} u''_i \Delta x^3. +\] + +\subsubsection{Third-Order Term} +\[ +\frac{u'''_i}{6} \int_{-3\Delta x/2}^{-\Delta x/2} y^3 dy = \frac{u'''_i}{6} \left( -\frac{5}{4}\Delta x^4 \right) = -\frac{5}{24} u'''_i \Delta x^4. +\] + +\subsection{Combine Results} +Assemble all integrated terms and divide by $\Delta x$: +\begin{align} +\bar{u}_{i-1} &= \frac{1}{\Delta x} \bigg[ u_i \Delta x - u'_i \Delta x^2 + \frac{13}{24} u''_i \Delta x^3 \notag \\ +&\quad - \frac{5}{24} u'''_i \Delta x^4 \bigg] + \mathcal{O}(\Delta x^4) \\ +&= u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 \notag \\ +&\quad + \mathcal{O}(\Delta x^4). +\end{align} + +\subsection{Coefficient Verification} +Key integration results that determine coefficients: +\begin{align} +\int_{-3\Delta x/2}^{-\Delta x/2} y^2 dy &= \frac{( -\Delta x/2 )^3 - ( -3\Delta x/2 )^3}{3} = \frac{13\Delta x^3}{12}, \\ +\int_{-3\Delta x/2}^{-\Delta x/2} y^3 dy &= \frac{( -\Delta x/2 )^4 - ( -3\Delta x/2 )^4}{4} = -\frac{5\Delta x^4}{4}. +\end{align} + +\subsection{Final Result} +The complete Taylor expansion of the cell average is: +\[ +\bar{u}_{i-1} = u_i - u'_i \Delta x + \frac{13}{24} u''_i (\Delta x)^2 - \frac{5}{24} u'''_i (\Delta x)^3 + \mathcal{O}(\Delta x^4). +\] +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02b/README.txt b/example/figure/1d/eno/latex/02b/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02b/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02b/plot.tex b/example/figure/1d/eno/latex/02b/plot.tex new file mode 100644 index 00000000..445a42c1 --- /dev/null +++ b/example/figure/1d/eno/latex/02b/plot.tex @@ -0,0 +1,56 @@ +\documentclass{ctexart} +\usepackage{amsmath} % 数学公式 +\usepackage{geometry} % 调整页面布局 +\usepackage{amsfonts} % 数学字体 + +% 设置页面边距 +\geometry{a4paper, left=2cm, right=2cm, top=2cm, bottom=2cm} + +\title{ENO插值系数 $c_{rj}$ 的推导} +\author{} +\date{} + +\begin{document} +\maketitle + +\section{推导过程} + +\subsection{模板选择与多项式构造} +ENO方法通过自适应选择模板构造插值多项式。对于模板偏移量 $r$,选取节点: +\[ +\left\{x_{i-r+q-\frac{1}{2}}\right\}_{q=0}^k +\] +构造 $k$ 阶多项式 $P_r(x)$,使其满足: +\begin{equation} +P_r\left(x_{i-r+m-\frac{1}{2}}\right) = u_{i-r+m}, \quad m = 0,1,\dots,k +\end{equation} + +\subsection{拉格朗日插值基函数} +基函数 $L_m(x)$ 定义为: +\begin{equation} +L_m(x) = \prod_{\substack{l=0 \\ l \neq m}}^{k} \frac{x - x_{i-r+l-\frac{1}{2}}}{x_{i-r+m-\frac{1}{2}} - x_{i-r+l-\frac{1}{2}}} +\end{equation} + +\subsection{界面处插值计算} +在界面 $x_{i+\frac{1}{2}}$ 处的多项式值为: +\begin{align} +P_r\left(x_{i+\frac{1}{2}}\right) &= \sum_{m=0}^{k} u_{i-r+m} L_m\left(x_{i+\frac{1}{2}}\right) \\ +&= \sum_{m=0}^{k} u_{i-r+m} \left[ \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{\prod_{\substack{q=0 \\ q \neq m,l}}^{k} \left(x_{i+\frac{1}{2}} - x_{i-r+q-\frac{1}{2}}\right)}{\prod_{\substack{l=0 \\ l \neq m}}^{k} \left(x_{i-r+m-\frac{1}{2}} - x_{i-r+l-\frac{1}{2}}\right)} \right] +\end{align} + +\subsection{系数组合与加权} +通过以下步骤得到最终系数: +\begin{enumerate} + \item 外层求和范围 $m = j+1$ 到 $k$ + \item 分子排除 $q=m$ 和 $q=l$ 的项 + \item 分母为基函数的标准分母 + \item 乘以网格间距 $\Delta x_{i-r+j}$ +\end{enumerate} + +\section{最终结果} +ENO插值系数 $c_{rj}$ 的表达式为: +\begin{equation} +c_{rj} = \sum_{m=j+1}^{k} \left( \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{\prod_{\substack{q=0 \\ q \neq m,l}}^{k} \left( x_{i+\frac{1}{2}} - x_{i - r + q - \frac{1}{2}} \right)}{\prod_{\substack{l=0 \\ l \neq m}}^{k} \left( x_{i - r + m - \frac{1}{2}} - x_{i - r + l - \frac{1}{2}} \right)} \right) \Delta x_{i - r + j}. +\end{equation} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02c/README.txt b/example/figure/1d/eno/latex/02c/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02c/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02c/plot.tex b/example/figure/1d/eno/latex/02c/plot.tex new file mode 100644 index 00000000..1cf0c374 --- /dev/null +++ b/example/figure/1d/eno/latex/02c/plot.tex @@ -0,0 +1,115 @@ +\documentclass{ctexart} +\usepackage{amsmath, amssymb, geometry} +\usepackage{enumitem} +\geometry{a4paper, margin=2cm} + +\title{ENO插值系数$c_{rj}$的推导思考过程} +\author{} +\date{} + +\begin{document} +\maketitle + +\section{初步分析} +\begin{itemize}[leftmargin=*] + \item \textbf{公式结构观察}: + \[ + c_{rj} = \sum_{m=j+1}^{k} \left( \sum_{\substack{l=0 \\ l \neq m}}^{k} \frac{ + \prod_{\substack{q=0 \\ q \neq m,l}}^{k} (x_{i+1/2} - x_{i-r+q-1/2}) + }{ + \prod_{\substack{l=0 \\ l \neq m}}^{k} (x_{i-r+m-1/2} - x_{i-r+l-1/2}) + } \right) \Delta x_{i-r+j} + \] + 包含双重求和与排除性乘积,暗示与拉格朗日插值相关。 + + \item \textbf{关键疑问标记}: + \begin{itemize} + \item 分子中的$\prod_{q\neq m,l}$是否对应双重排除的基函数? + \item 分母是否为标准拉格朗日分母$\prod_{l\neq m}(x_m - x_l)$? + \item 外层求和$m=j+1$到$k$的物理意义为何? + \end{itemize} +\end{itemize} + +\section{数学工具关联} +\subsection{拉格朗日插值再审视} +标准基函数形式: +\[ +L_m(x) = \prod_{\substack{l=0 \\ l \neq m}}^{k} \frac{x - x_l}{x_m - x_l} +\] +对比发现分子部分存在差异,需解释$q \neq m,l$的双重排除。 + +\subsection{导数近似可能性} +考虑基函数导数形式: +\[ +L'_m(x) = \sum_{l \neq m} \frac{1}{x_m-x_l} \prod_{\substack{q=0 \\ q \neq m,l}}^{k} \frac{x-x_q}{x_m-x_q} +\] +发现与原式分子结构相似,但分母处理不同。 + +\section{具体案例验证} +\subsection{k=1特殊情况} +节点集合$\{x_{i-r-1/2}, x_{i-r+1/2}\}$,计算$c_{r0}$: +\[ +c_{r0} = \frac{\prod_{\substack{q=0 \\ q \neq 1,0}}^{1} (\cdot)}{\prod_{l\neq1} (\cdot)} \Delta x_{i-r} = \frac{1}{\Delta x_{i-r}} \Delta x_{i-r} = 1 +\] +结果提示可能对应一阶迎风格式。 + +\subsection{k=2情况推演} +需计算三节点情况下的双重求和: +\[ +\begin{aligned} +c_{r0} &= \sum_{m=1}^2 \Bigg( \sum_{\substack{l=0 \\ l \neq m}}^2 \frac{ + \prod_{\substack{q=0 \\ q \neq m,l}}^2 (x_{i+1/2}-x_{i-r+q-1/2}) +}{ + \prod_{\substack{l=0 \\ l \neq m}}^2 (x_{i-r+m-1/2}-x_{i-r+l-1/2}) +} \Bigg) \Delta x_{i-r} +\end{aligned} +\] +展开后呈现二阶精度特征。 + +\section{推导路径分析} +\begin{enumerate}[label=路径\arabic*:] + \item \textbf{牛顿-柯特斯积分}:假设系数来自非均匀网格积分公式 + \[ + \int_{x_j}^{x_{j+1}} P(x)dx = \sum c_{rj} \Delta x_{i-r+j} + \] + 但分子结构不匹配典型积分公式 + + \item \textbf{通量重构理论}:考虑有限体积法中界面通量计算 + \[ + \hat{f}_{i+1/2} = \sum c_{rj} f_{i-r+j} + \] + 需验证是否对应守恒形式 + + \item \textbf{误差控制机制}:ENO的核心思想体现 + \begin{itemize} + \item 分子中的双重排除可能对应光滑性检测 + \item 外层求和$m=j+1$反映模板扩展策略 + \end{itemize} +\end{enumerate} + +\section{关键突破点} +\begin{itemize} + \item 发现分子可重组为: + \[ + \prod_{q\neq m} (x_{i+1/2}-x_q) \bigg/ (x_{i+1/2}-x_l) + \] + \item 分母可分解为: + \[ + (x_m-x_l) \prod_{\substack{l'\neq m \\ l'\neq l}} (x_m-x_{l'}) + \] + \item 结合后得到: + \[ + \frac{\prod_{q\neq m} (x_{i+1/2}-x_q)}{\prod_{l'\neq m} (x_m-x_{l'})} \sum_{l\neq m} \frac{1}{x_{i+1/2}-x_l} + \] + 最终指向分段多项式的光滑性度量 +\end{itemize} + +\section{结论性推导} +通过将ENO的模板选择过程形式化,最终验证系数公式满足: +\begin{itemize} + \item 保持$k$阶精度:泰勒展开匹配至$O(\Delta x^k)$ + \item 本质无振荡:分子结构自动抑制高频分量 + \item 网格适应性:显式包含$\Delta x_{i-r+j}$项 +\end{itemize} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02d/README.txt b/example/figure/1d/eno/latex/02d/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02d/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02d/plot.tex b/example/figure/1d/eno/latex/02d/plot.tex new file mode 100644 index 00000000..a24958b6 --- /dev/null +++ b/example/figure/1d/eno/latex/02d/plot.tex @@ -0,0 +1,38 @@ +\documentclass{ctexart} +\usepackage{amsmath} + +\begin{document} + +\section*{牛顿-柯特斯积分公式} + +牛顿-柯特斯积分公式是数值积分方法中的一种,它通过多项式逼近被积函数,然后对多项式进行积分以近似原函数的积分。这种方法是由牛顿和柯特斯共同提出的,因此得名。 + +\subsection*{专业解释} + +牛顿- 柯特斯积分公式基于多项式插值理论,其基本思想是:在积分区间 $[a, b]$ 上选取 $n+1$ 个点 $x_0, x_1, \ldots, x_n$,构造一个 $n$ 次插值多项式 $P_n(x)$ 来逼近被积函数 $f(x)$。然后对 $P_n(x)$ 进行积分,得到原函数积分的近似值。 + +牛顿- 柯特斯公式的一般形式为: +\begin{equation} +\int_{a}^{b} f(x) dx \approx \sum_{j=0}^{n} w_j f(x_j) +\end{equation} +其中,$w_j$ 是权重系数,$f(x_j)$ 是函数在节点 $x_j$ 处的值。 + +\subsection*{简单例子} + +\begin{enumerate} + \item 梯形法则:当 $n=1$ 时,牛顿-柯特斯公式退化为梯形法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{b-a}{2} [f(a) + f(b)] + \end{equation} + + \item 辛普森一三法则:当 $n=2$ 时,牛顿-柯特斯公式为辛普森一三法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{b-a}{6} [f(a) + 4f\left(\frac{a+b}{2}\right) + f(b)] + \end{equation} + \item 辛普森三八法则:当 $n=4$ 时,牛顿-柯特斯公式为辛普森三八法则: + \begin{equation} + \int_{a}^{b} f(x) dx \approx \frac{3(b-a)}{8} [f(a) + 3f\left(\frac{3a+b}{4}\right) + 3f\left(\frac{a+b}{2}\right) + f(b)] + \end{equation} +\end{enumerate} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02e/README.txt b/example/figure/1d/eno/latex/02e/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02e/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02e/plot.tex b/example/figure/1d/eno/latex/02e/plot.tex new file mode 100644 index 00000000..2b29609a --- /dev/null +++ b/example/figure/1d/eno/latex/02e/plot.tex @@ -0,0 +1,47 @@ +\documentclass{ctexart} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{hyperref} + +\begin{document} + +\section{一维标量方程的 ENO 和 weighted ENO 格式} + +\subsection{积分平均型格式或者有限体积型格式} + +将原方程在区间 $I_i$ 上积分,并整理得 +\begin{equation} +\frac{d}{dt} \int_{x_{i-\frac{1}{2}}}^{x_{i+\frac{1}{2}}} u(x,t) dx + f\left(u\left(x_{i+\frac{1}{2}}, t\right)\right) - f\left(u\left(x_{i-\frac{1}{2}}, t\right)\right) = 0. +\end{equation} +\label{eq:eno1} + +定义函数 $u(x,t)$ 的单元平均值 +\begin{equation} +\bar{u}_i(t) = \frac{1}{\Delta x_i} \int_{x_{i-\frac{1}{2}}}^{x_{i+\frac{1}{2}}} u(x,t) dx, +\end{equation} +\label{eq:eno2} + +则有 +\begin{equation} +\frac{d}{dt} \bar{u}_i + \frac{1}{\Delta x_i} \left[f\left(u\left(x_{i+\frac{1}{2}, t\right)\right) - f\left(u\left(x_{i-\frac{1}{2}, t}\right)\right)\right] = 0, +\end{equation} +\label{eq:eno3} + +这里由于只有单元平均值已知,所以需要构造函数在单元边界点(半网格节点)上的值 $u_{i-1/2}, i=0,1,\cdots,N$。此时有限体积格式可写为 +\begin{equation} +\frac{d}{dt} \bar{u}_i + \frac{1}{\Delta x_i} \left[f\left(u_{i+\frac{1}{2}}\right) - f\left(u_{i-\frac{1}{2}}\right)\right] = 0. +\end{equation} +\label{eq:eno4} + +假定周期边界条件,即假定在计算区域外的数值解是可以得到的(这也适合于具有紧致支集的问题)。对于一致网格剖分 $\Delta x_i = \Delta x$,我们可以如下构造单元节点上的函数值: + +\begin{enumerate} + \item 确定一个模板。 + \item 构造一个多项式,设为 $p(x)$,使其满足 + \begin{equation} + \frac{1}{\Delta x_j} \int_{x_{j-\frac{1}{2}}}^{x_{j+\frac{1}{2}}} p(x) dx = \bar{u}_j, \quad j = i-1, i, i+1 + \end{equation} + 在所选择的模板上成立。上述模板下多项式 $p(x)$ 是惟一确定的不超过二次 +\end{enumerate} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02etest/README.txt b/example/figure/1d/eno/latex/02etest/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/02etest/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02etest/plot.tex b/example/figure/1d/eno/latex/02etest/plot.tex new file mode 100644 index 00000000..ce1dc1b1 --- /dev/null +++ b/example/figure/1d/eno/latex/02etest/plot.tex @@ -0,0 +1,12 @@ +\documentclass{ctexart} +\usepackage{amsmath} + +\begin{document} + +\begin{align} +E &= mc^2 \tag{\label{eq:Einstein}} \\ % 手动编号 +a &= b \tag{\label{eq:myeq}} \\ + &= c +\end{align} + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02f/README.txt b/example/figure/1d/eno/latex/02f/README.txt new file mode 100644 index 00000000..0808f5c5 --- /dev/null +++ b/example/figure/1d/eno/latex/02f/README.txt @@ -0,0 +1,3 @@ +pdflatex plot.tex +d:\github\OneFLOW\example\figure\1d\eno\latex\02f\build\ +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/1d/eno/latex/02f/plot.tex b/example/figure/1d/eno/latex/02f/plot.tex new file mode 100644 index 00000000..2e8d688c --- /dev/null +++ b/example/figure/1d/eno/latex/02f/plot.tex @@ -0,0 +1,29 @@ +\documentclass{article} +\usepackage{amsmath} +\usepackage[UTF8]{ctex} % For Chinese support + +\begin{document} + +\section{8.1} + +\begin{equation} +w_t + (f(w))_x = 0, \quad x \in (a, b), \quad t > 0 +\label{eq:8.1} +\end{equation} + +\begin{equation} +w(x, 0) = w^0(x), \quad x \in [a, b] +\label{eq:8.2} +\end{equation} + +\begin{equation} +a = x_{\frac{1}{2}} < x_{\frac{3}{2}} < \cdots < x_{N-\frac{1}{2}} = b +\label{eq:8.3} +\end{equation} + +其中计算点为 \( x_i = \frac{x_{i-1/2} + x_{i+1/2}}{2} \),步长为 \( \Delta x_i \)。 +\( \Delta x = \max \Delta x_i \),表示最大网格步长。 + +加权ENO方法是一种高阶、非振荡的数值方法,适用于求解偏微分方程。 + +\end{document} \ No newline at end of file diff --git a/example/figure/1d/eno/latex/README.txt b/example/figure/1d/eno/latex/README.txt new file mode 100644 index 00000000..fa25c195 --- /dev/null +++ b/example/figure/1d/eno/latex/README.txt @@ -0,0 +1,2 @@ +pdflatex plot.tex +pdflatex ../plot.tex \ No newline at end of file diff --git a/example/figure/arrow/01/testprj.py b/example/figure/arrow/01/testprj.py new file mode 100644 index 00000000..7a8f8a7e --- /dev/null +++ b/example/figure/arrow/01/testprj.py @@ -0,0 +1,29 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +# 创建一个新的图形 +fig, ax = plt.subplots() + +# 添加一条竖向线段 +line = ax.plot([0, 0], [0, 1], color='blue')[0] + +# 在线段末端添加箭头 +arrow = patches.FancyArrowPatch( + (0, 1), # 箭头起点坐标 + (0, 0), # 箭头终点坐标 + arrowstyle='->', # 箭头样式 + mutation_scale=20 # 箭头大小 +) + +# 将箭头添加到图形中 +ax.add_patch(arrow) + +# 设置坐标轴的范围 +ax.set_xlim(-0.1, 0.1) +ax.set_ylim(-0.1, 1.1) + +# 隐藏坐标轴 +ax.axis('off') + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/arrow/01a/testprj.py b/example/figure/arrow/01a/testprj.py new file mode 100644 index 00000000..84f6a5b9 --- /dev/null +++ b/example/figure/arrow/01a/testprj.py @@ -0,0 +1,32 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 定义函数值 +x = np.array([0, 1, 2, 3]) +y = np.array([1, 4, 9, 16]) + +# 绘制原始点 +plt.scatter(x, y, color='blue', label='Data Points') + +# 绘制0阶差商 +for i in range(len(x)): + plt.plot([x[i], x[i]], [y[i], y[i]], 'k--') # 绘制水平线 + +# 绘制1阶差商 +for i in range(len(x) - 1): + plt.plot([x[i], x[i+1]], [y[i], y[i+1]], 'r--') # 绘制斜线 + +# 绘制2阶差商 +for i in range(len(x) - 2): + plt.plot([x[i], x[i+2]], [y[i], y[i+2]], 'g--') # 绘制更长的斜线 + +# 添加图例 +plt.legend(['Data Points', '0th Order Differences', '1st Order Differences', '2nd Order Differences']) + +# 添加标题和标签 +plt.title('Difference Quotient Visualization') +plt.xlabel('x') +plt.ylabel('f(x)') + +# 显示图形 +plt.show() \ No newline at end of file diff --git a/example/figure/integral/latex/01/README.txt b/example/figure/integral/latex/01/README.txt new file mode 100644 index 00000000..bcbf055d --- /dev/null +++ b/example/figure/integral/latex/01/README.txt @@ -0,0 +1 @@ +pdflatex plot.tex \ No newline at end of file diff --git a/example/figure/integral/latex/01/plot.tex b/example/figure/integral/latex/01/plot.tex new file mode 100644 index 00000000..b7ec8fa7 --- /dev/null +++ b/example/figure/integral/latex/01/plot.tex @@ -0,0 +1,42 @@ +\documentclass{standalone} +\usepackage{tikz} +\usepackage{pgfplots} +\pgfplotsset{compat=newest} + +\begin{document} +\begin{tikzpicture} +\begin{axis}[ + axis lines = middle, + xlabel = \(z\), + ylabel = {\(f(x^{2})\)}, + ymin=-1.5, ymax=1.5, + xmin=-0.1, xmax=1.1, + width=10cm, + height=6cm, + grid=both, + grid style={line width=.1pt, draw=gray!10}, + major grid style={line width=.2pt,draw=gray!50}, + minor tick num=5, + enlargelimits={abs=0.5}, + samples=100, + domain=0:1, + legend pos=north west, +] + +% 绘制函数曲线 +\addplot [domain=0:1, samples=100, color=blue, thick] {sin(2*pi*x)}; +\addlegendentry{\(f(x) = \sin(2\pi x)\)} + +% 绘制网格点 +\foreach \x in {0, 0.1, ..., 1} { + \addplot[mark=*, mark size=3, color=red] coordinates {(\x, {sin(2*pi*\x)})}; +} + +% 绘制积分区域 +\foreach \x in {0, 0.1, ..., 0.9} { + \addplot [fill=gray!30, draw=none, domain=\x:{\x+0.1}] {sin(2*pi*x)} \closedcycle; +} + +\end{axis} +\end{tikzpicture} +\end{document} \ No newline at end of file diff --git a/example/figure/integral/python/01/testprj.py b/example/figure/integral/python/01/testprj.py new file mode 100644 index 00000000..1c0f93db --- /dev/null +++ b/example/figure/integral/python/01/testprj.py @@ -0,0 +1,33 @@ +import numpy as np +import matplotlib.pyplot as plt + +# 定义积分区间和函数 +a = 0 +b = 1 +n = 10 # 网格点数量 +x = np.linspace(a, b, n+1) +f = lambda x: np.sin(2 * np.pi * x) # 定义函数 f(x) = sin(2πx) + +# 计算函数值 +y = f(x) + +# 绘制函数曲线 +plt.figure(figsize=(8, 4)) +plt.plot(x, y, label='f(x) = sin(2πx)', color='blue', linewidth=2) + +# 绘制网格点 +plt.scatter(x, y, color='red', zorder=5) + +# 绘制积分区域 +for i in range(n): + plt.fill_between([x[i], x[i+1]], [0, 0], [y[i], y[i+1]], color='gray', alpha=0.3) + +# 添加标题和标签 +plt.title('One-Dimensional Line Integral', fontsize=14) +plt.xlabel('x', fontsize=12) +plt.ylabel('f(x)', fontsize=12) +plt.legend(fontsize=12) +plt.grid(True) + +# 显示图表 +plt.show() \ No newline at end of file diff --git a/example/figure/latex/01/README.txt b/example/figure/latex/01/README.txt new file mode 100644 index 00000000..bcbf055d --- /dev/null +++ b/example/figure/latex/01/README.txt @@ -0,0 +1 @@ +pdflatex plot.tex \ No newline at end of file diff --git a/example/figure/latex/01/plot.tex b/example/figure/latex/01/plot.tex new file mode 100644 index 00000000..7d080f19 --- /dev/null +++ b/example/figure/latex/01/plot.tex @@ -0,0 +1,70 @@ +\documentclass{article} +\usepackage{tikz} +\usepackage{geometry} +\geometry{a4paper, margin=1cm} + +\begin{document} + +% 左侧重构 (Left-side reconstruction) +\begin{tikzpicture} + % 设置坐标和样式 + \tikzset{ + dot/.style={circle, fill=red, inner sep=2pt}, + template/.style={rectangle, fill=purple, fill opacity=0.3, draw=none}, + } + + % 绘制网格点 (红点) 并命名节点 + \foreach \x in {-2,-1,0,1,2,3,4,5,6} { + \node[dot] (p\x) at (\x,0) {}; + \node[above=2pt] at (\x,0) {\(i=\x\)}; + } + + % 绘制虚线 (x=0 和 x=L) + \draw[dashed, gray] (0,-0.5) -- (0,0.5); + \draw[dashed, gray] (6,-0.5) -- (6,0.5); + \node[below=2pt] at (0,0) {\(x=0\)}; + \node[below=2pt] at (6,0) {\(x=L\)}; + + % 绘制紫色模板 (从 i-1 到 i+2, 覆盖 i+1) + \node[template, minimum width=3.5cm, minimum height=1cm] at (1,0) {}; + \node at (1,0.3) {\(u_{i+1}^L\)}; + + % 设置标题 + \node[above=10pt] at (current bounding box.north) {(a) Left-side reconstruction}; + + % 隐藏坐标轴 + \path[use as bounding box] (-2.5,-0.7) rectangle (6.5,0.7); +\end{tikzpicture} + +% 右侧重构 (Right-side reconstruction) +\begin{tikzpicture} + % 设置坐标和样式 + \tikzset{ + dot/.style={circle, fill=red, inner sep=2pt}, + template/.style={rectangle, fill=purple, fill opacity=0.3, draw=none}, + } + + % 绘制网格点 (红点) 并命名节点 + \foreach \x in {-2,-1,0,1,2,3,4,5,6} { + \node[dot] (p\x) at (\x,0) {}; + \node[above=2pt] at (\x,0) {\(i=\x\)}; + } + + % 绘制虚线 (x=0 和 x=L) + \draw[dashed, gray] (0,-0.5) -- (0,0.5); + \draw[dashed, gray] (6,-0.5) -- (6,0.5); + \node[below=2pt] at (0,0) {\(x=0\)}; + \node[below=2pt] at (6,0) {\(x=L\)}; + + % 绘制紫色模板 (从 i-1 到 i+2, 覆盖 i+1) + \node[template, minimum width=3.5cm, minimum height=1cm] at (1,0) {}; + \node at (1,0.3) {\(u_{i+1}^R\)}; + + % 设置标题 + \node[above=10pt] at (current bounding box.north) {(b) Right-side reconstruction}; + + % 隐藏坐标轴 + \path[use as bounding box] (-2.5,-0.7) rectangle (6.5,0.7); +\end{tikzpicture} + +\end{document} \ No newline at end of file diff --git a/example/grid/1d/01/Mesh/CMakeLists.txt b/example/grid/1d/01/Mesh/CMakeLists.txt new file mode 100644 index 00000000..dc0c69f3 --- /dev/null +++ b/example/grid/1d/01/Mesh/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.31) + +project(Mesh VERSION 1.0) + +set ( PRJ_COMPILE_FEATURES ) +set ( PRJ_COMPILE_DEFINITIONS ) +set ( PRJ_LIBRARIES ) +set ( PRJ_INCLUDE_DIRS ) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(Qt6 REQUIRED COMPONENTS Widgets) + +list ( APPEND PRJ_LIBRARIES Qt6::Widgets ) +list ( APPEND PRJ_COMPILE_FEATURES cxx_std_23 ) + +set ( CGNS_INCLUDE_DIRS $ENV{CGNS_INC} ) +set ( CGNS_LIBRARIES $ENV{CGNS_LIB_SHARED_NAME} ) + +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Windows" ) + set ( CGNS_ROOT "C:/dev/cgns/4.4.0" ) + set ( CGNS_LIBNAME "cgnsdll.lib" ) + + set ( CGNS_INCLUDE_DIRS "${CGNS_ROOT}/include" CACHE PATH "path to CGNS headers" ) + set ( CGNS_LIBRARIES "${CGNS_ROOT}/lib/${CGNS_LIBNAME}" CACHE PATH "path to CGNS library" ) +endif() + +list ( APPEND PRJ_LIBRARIES ${CGNS_LIBRARIES} ) +list ( APPEND PRJ_INCLUDE_DIRS ${CGNS_INCLUDE_DIRS} ) + +if ( WIN32 ) + list ( APPEND PRJ_COMPILE_DEFINITIONS USE_DLL ) +endif () + +message( STATUS "PRJ_INCLUDE_DIRS = ${PRJ_INCLUDE_DIRS}") + +if ( MSVC ) + set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME} ) +endif() + +set( PROJECT_SOURCES + main.cpp + grid.h grid.cpp + mainwindow.h mainwindow.cpp mainwindow.ui + meshdialog.h meshdialog.cpp meshdialog.ui +) + +set( PRJ_SOURCES ) +foreach(source ${PROJECT_SOURCES}) + #list( APPEND PRJ_SOURCES "codes/${source}" ) + list( APPEND PRJ_SOURCES "${source}" ) +endforeach() + +foreach(source ${PRJ_SOURCES}) + #message( STATUS "source=${source}" ) +endforeach() + +add_executable( ${PROJECT_NAME} + #images/res.qrc +) + +target_sources( ${PROJECT_NAME} + PRIVATE + ${PRJ_SOURCES} +) + +target_include_directories ( ${PROJECT_NAME} + PRIVATE + ${PRJ_INCLUDE_DIRS} +) + +target_link_libraries( ${PROJECT_NAME} + PRIVATE + ${PRJ_LIBRARIES} +) + +target_compile_features ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_FEATURES} +) + +target_compile_definitions ( ${PROJECT_NAME} + PRIVATE + ${PRJ_COMPILE_DEFINITIONS} +) diff --git a/example/grid/1d/01/Mesh/CMakeLists.txt.user b/example/grid/1d/01/Mesh/CMakeLists.txt.user new file mode 100644 index 00000000..ed7af13d --- /dev/null +++ b/example/grid/1d/01/Mesh/CMakeLists.txt.user @@ -0,0 +1,462 @@ + + + + + + EnvironmentId + {762d27bf-d7ff-4b95-a1d2-6c0057e05a84} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 0 + 80 + true + true + 1 + 0 + false + true + false + 2 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + false + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 8 + true + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop Qt 6.8.1 MSVC2022 64bit + Desktop Qt 6.8.1 MSVC2022 64bit + qt.qt6.681.win64_msvc2022_64_kit + 0 + 0 + 0 + + Debug + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Debug +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + 0 + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + Release + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=Release +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Release + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-RelWithDebInfo + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Release with Debug Information + CMakeProjectManager.CMakeBuildConfiguration + + + RelWithDebInfo + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + 0 + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Profile + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Profile + CMakeProjectManager.CMakeBuildConfiguration + + + MinSizeRel + 2 + false + + -DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON +-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_BUILD_TYPE:STRING=MinSizeRel +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} + D:\github\OneFLOW\example\grid\1d\01\Mesh\build\Desktop_Qt_6_8_1_MSVC2022_64bit-MinSizeRel + + + + + all + + false + + true + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Minimum Size Release + CMakeProjectManager.CMakeBuildConfiguration + + 5 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + + + + + + + + false + + true + ApplicationManagerPlugin.Deploy.CMakePackageStep + + + install-package --acknowledge + true + Install Application Manager package + ApplicationManagerPlugin.Deploy.InstallPackageStep + + + + + + + + 2 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ApplicationManagerPlugin.Deploy.Configuration + + 2 + + true + true + 0 + true + + 2 + + false + -e cpu-cycles --call-graph "dwarf,4096" -F 250 + Mesh + CMakeProjectManager.CMakeRunConfiguration. + Mesh + false + true + true + true + D:/github/OneFLOW/example/grid/1d/01/Mesh/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/example/grid/1d/01/Mesh/README.txt b/example/grid/1d/01/Mesh/README.txt new file mode 100644 index 00000000..eafaa046 --- /dev/null +++ b/example/grid/1d/01/Mesh/README.txt @@ -0,0 +1 @@ +cmake .. -D CMAKE_PREFIX_PATH:PATH="C:/local/Qt/6.8.1/msvc2022_64/" \ No newline at end of file diff --git a/example/grid/1d/01/Mesh/grid.cpp b/example/grid/1d/01/Mesh/grid.cpp new file mode 100644 index 00000000..3520fb67 --- /dev/null +++ b/example/grid/1d/01/Mesh/grid.cpp @@ -0,0 +1,109 @@ +#include "grid.h" + +void write_grid_str( const std::string & gridfilename, int ni, double xstart, double xend ) +{ + int index_file, icelldim, iphysdim, index_base; + int index_zone, index_coord; + char basename[ 33 ], zonename[ 33 ]; + + // A++++++++B + // o-------->i + // x_l x_r + // 1 ni + std::vector x(ni); + + double x_l = xstart; + double x_r = xend; + + double dx = ( x_r - x_l ) / ( ni - 1 ); + + for ( int i = 0; i < ni; ++ i ) + { + x[ i ] = x_l + i * dx; + } + + if ( cg_open( gridfilename.c_str(), CG_MODE_WRITE, &index_file ) ) cg_error_exit(); + /* create base (user can give any name) */ + strcpy_s( basename, "Base" ); + icelldim = 1; + iphysdim = 1; + + std::vector isize( icelldim * 3, 0 ); + + cg_base_write( index_file, basename, icelldim, iphysdim, &index_base ); + /* vertex size */ + isize[ 0 ] = ni; + /* cell size */ + isize[ 1 ] = ni - 1; + /* boundary vertex size (always zero for structured grids) */ + isize[ 2 ] = 0; + + /* define zone 1 name (user can give any name) */ + strcpy_s( zonename, "Zone1" ); + /* create zone */ + cg_zone_write( index_file, index_base, zonename, isize.data(), CGNS_ENUMV( Structured ), &index_zone ); + /* write grid coordinates (user must use SIDS-standard names here) */ + cg_coord_write( index_file, index_base, index_zone, CGNS_ENUMV( RealDouble ), "CoordinateX", x.data(), &index_coord ); + + cg_close(index_file); +} + +void write_bc_str( const std::string & gridfilename, BC &left, BC &right ) +{ + std::printf( "\nProgram write_bc_str\n" ); + + int index_file = -1; + if ( cg_open( gridfilename.c_str(), CG_MODE_MODIFY, &index_file ) ) cg_error_exit(); + + int index_base = 1; + int icelldim = -1; + int iphysdim = -1; + char basename[ 33 ]; + cg_base_read( index_file, index_base, basename, &icelldim, &iphysdim ); + + std::cout << "icelldim = " << icelldim << " iphysdim = " << iphysdim << "\n"; + + /* get number of zones (should be 1 for our case) */ + int nzone = -1; + cg_nzones( index_file, index_base, &nzone ); + if ( nzone != 1 ) + { + std::printf( "\nError. This program expects 1 zones. %d read.\n", nzone ); + return; + } + + std::vector isize( icelldim * 3, 0 ); + std::vector ipnts( 2 * icelldim ); + + char zonename[ 33 ]; + + int index_zone = 1; + cg_zone_read( index_file, index_base, index_zone, zonename, isize.data() ); + + DumpZoneBc( index_file, index_base, index_zone, isize.data(), ipnts, left, right ); + + cg_close(index_file); +} + +void DumpZoneBc( int index_file, int index_base, int index_zone, cgsize_t *isize, std::vector &ipnts, BC &left, BC &right ) +{ + int ilo = 1; + int ihi = isize[ 0 ]; + int index_bc = -1; + + /* lower point of range */ + ipnts[ 0 ] = ilo; + /* upper point of range */ + ipnts[ 1 ] = ilo; + + cg_boco_write( index_file, index_base, index_zone, left.bcName.c_str(), left.bctype, CGNS_ENUMV( PointRange ), 2, ipnts.data(), &index_bc ); + + /* lower point of range */ + ipnts[ 0 ] = ihi; + /* upper point of range */ + ipnts[ 1 ] = ihi; + + cg_boco_write( index_file, index_base, index_zone, right.bcName.c_str(), right.bctype, CGNS_ENUMV( PointRange ), 2, ipnts.data(), &index_bc ); +} + + diff --git a/example/grid/1d/01/Mesh/grid.h b/example/grid/1d/01/Mesh/grid.h new file mode 100644 index 00000000..ae778a1e --- /dev/null +++ b/example/grid/1d/01/Mesh/grid.h @@ -0,0 +1,15 @@ +#include "cgnslib.h" +#include +#include +#include + +class BC +{ +public: + std::string bcName; + BCType_t bctype; +}; + +void write_grid_str( const std::string & gridfilename, int ni, double xstart, double xend ); +void write_bc_str( const std::string & gridfilename, BC &left, BC &right ); +void DumpZoneBc( int index_file, int index_base, int index_zone, cgsize_t * isize, std::vector & ipnts, BC &left, BC &right ); diff --git a/example/grid/1d/01/Mesh/main.cpp b/example/grid/1d/01/Mesh/main.cpp new file mode 100644 index 00000000..818a6e1e --- /dev/null +++ b/example/grid/1d/01/Mesh/main.cpp @@ -0,0 +1,12 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.setWindowTitle("Mesh"); + w.show(); + return a.exec(); +} diff --git a/example/grid/1d/01/Mesh/mainwindow.cpp b/example/grid/1d/01/Mesh/mainwindow.cpp new file mode 100644 index 00000000..0786d498 --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.cpp @@ -0,0 +1,33 @@ +#include "mainwindow.h" +#include "./ui_mainwindow.h" +#include "meshdialog.h" + + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + this->menuFile = new QMenu("&File", this); + this->ui->menubar->addMenu( this->menuFile ); + this->actNew = new QAction("New"); + this->menuFile->addAction( this->actNew ); + QObject::connect(this->actNew, &QAction::triggered, this, &MainWindow::triggerNew); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::triggerNew() +{ + showDialog(); +} + +void MainWindow::showDialog() +{ + MeshDialog dialog(this); + dialog.exec(); // 显示对话框,阻塞直到关闭 +} diff --git a/example/grid/1d/01/Mesh/mainwindow.h b/example/grid/1d/01/Mesh/mainwindow.h new file mode 100644 index 00000000..e05442b8 --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.h @@ -0,0 +1,30 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QMenu; +class QAction; + +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); +public: + void triggerNew(); + void showDialog(); +private: + Ui::MainWindow *ui; + QMenu * menuFile; + QAction * actNew; +}; +#endif // MAINWINDOW_H diff --git a/example/grid/1d/01/Mesh/mainwindow.ui b/example/grid/1d/01/Mesh/mainwindow.ui new file mode 100644 index 00000000..7bff7e1d --- /dev/null +++ b/example/grid/1d/01/Mesh/mainwindow.ui @@ -0,0 +1,31 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + 0 + 0 + 800 + 21 + + + + + + + + diff --git a/example/grid/1d/01/Mesh/meshdialog.cpp b/example/grid/1d/01/Mesh/meshdialog.cpp new file mode 100644 index 00000000..c936ec25 --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.cpp @@ -0,0 +1,78 @@ +#include "meshdialog.h" +#include "ui_meshdialog.h" +#include "grid.h" + +std::map bctype_map{ + {"BCTypeNull", BCTypeNull}, + {"BCAxisymmetricWedge", BCAxisymmetricWedge}, + {"BCDegenerateLine", BCDegenerateLine}, + {"BCDegeneratePoint", BCDegeneratePoint}, + {"BCDirichlet", BCDirichlet}, + {"BCExtrapolate", BCExtrapolate}, + {"BCFarfield", BCFarfield}, + {"BCGeneral", BCGeneral}, + {"BCInflow", BCInflow}, + {"BCInflowSubsonic", BCInflowSubsonic}, + {"BCOutflowSupersonic", BCOutflowSupersonic}, + {"BCSymmetryPlane", BCSymmetryPlane}, + {"BCSymmetryPolar", BCSymmetryPolar}, + {"BCTunnelInflow", BCTunnelInflow}, + {"BCTunnelOutflow", BCTunnelOutflow}, + {"BCWall", BCWall}, + {"BCWallInviscid", BCWallInviscid}, + {"BCWallViscous", BCWallViscous}, + {"BCWallViscousHeatFlux", BCWallViscousHeatFlux}, + {"BCWallViscousIsothermal", BCWallViscousIsothermal}, + {"FamilySpecified", FamilySpecified} +}; + +MeshDialog::MeshDialog(QWidget *parent) + : QDialog(parent) + , ui(new Ui::MeshDialog) +{ + ui->setupUi(this); + this->AddBcItems(ui->comboBoxBcL); + this->AddBcItems(ui->comboBoxBcR); +} + +MeshDialog::~MeshDialog() +{ + delete ui; +} + +void MeshDialog::AddBcItems(QComboBox *comBox) +{ + for( std::map::iterator iter = bctype_map.begin(); iter != bctype_map.end(); ++ iter ) + { + comBox->addItem(QString::fromStdString(iter->first)); + } + +} + +void MeshDialog::on_buttonBox_accepted() +{ + qDebug() << "MeshDialog::on_buttonBox_accepted()"; + QString txt = ui->npoints_lineEdit->text(); + int nPoints = txt.toInt(); + qDebug() << "nPoints = " << nPoints; + double xstart = ui->lineEdit_Start_X->text().toDouble(); + double xend = ui->lineEdit_End_X->text().toDouble(); + + std::string gridfilename = ui->lineEditGrid->text().toStdString(); + BC left, right; + left.bcName = ui->lineEditBcNameL->text().toStdString(); + std::map::iterator iterL = bctype_map.find(ui->comboBoxBcL->currentText().toStdString()); + left.bctype = iterL->second; + right.bcName = ui->lineEditBcNameR->text().toStdString(); + std::map::iterator iterR = bctype_map.find(ui->comboBoxBcR->currentText().toStdString()); + right.bctype = iterR->second; + + DumpGrid( gridfilename, nPoints, xstart, xend, left, right ); +} + +void MeshDialog::DumpGrid( const std::string &gridfilename, int nPoints, double xstart, double xend, BC &left, BC &right ) +{ + write_grid_str( gridfilename, nPoints, xstart, xend ); + write_bc_str( gridfilename, left, right ); +} + diff --git a/example/grid/1d/01/Mesh/meshdialog.h b/example/grid/1d/01/Mesh/meshdialog.h new file mode 100644 index 00000000..7b6957ee --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.h @@ -0,0 +1,30 @@ +#ifndef MESHDIALOG_H +#define MESHDIALOG_H + +#include + +namespace Ui { +class MeshDialog; +} + +class BC; +class QComboBox; + +class MeshDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MeshDialog(QWidget *parent = nullptr); + ~MeshDialog(); + +private slots: + void on_buttonBox_accepted(); +private: + void DumpGrid( const std::string &gridfilename, int nPoints, double xstart, double xend, BC &left, BC &right ); + void AddBcItems(QComboBox *comBox); +private: + Ui::MeshDialog *ui; +}; + +#endif // MESHDIALOG_H diff --git a/example/grid/1d/01/Mesh/meshdialog.ui b/example/grid/1d/01/Mesh/meshdialog.ui new file mode 100644 index 00000000..9eab1aeb --- /dev/null +++ b/example/grid/1d/01/Mesh/meshdialog.ui @@ -0,0 +1,296 @@ + + + MeshDialog + + + + 0 + 0 + 512 + 383 + + + + Dialog + + + + + 120 + 320 + 341 + 32 + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + + + + 30 + 40 + 71 + 21 + + + + N + + + + + + 30 + 80 + 53 + 15 + + + + start + + + + + + 120 + 40 + 113 + 21 + + + + 101 + + + + + + 120 + 80 + 113 + 21 + + + + 0 + + + + + + 120 + 120 + 113 + 21 + + + + 1 + + + + + + 30 + 120 + 53 + 15 + + + + end + + + + + + 30 + 290 + 53 + 15 + + + + grid file + + + + + + 120 + 290 + 191 + 21 + + + + mygrid.cgns + + + + + + 30 + 160 + 53 + 15 + + + + Left BC + + + + + + 161 + 188 + 191 + 21 + + + + + + + 30 + 230 + 53 + 15 + + + + Right BC + + + + + + 161 + 260 + 191 + 21 + + + + + + + 161 + 161 + 191 + 21 + + + + Left + + + + + + 90 + 160 + 53 + 15 + + + + Name + + + + + + 90 + 190 + 53 + 15 + + + + Type + + + + + + 90 + 230 + 53 + 15 + + + + Name + + + + + + 90 + 260 + 53 + 15 + + + + Type + + + + + + 161 + 233 + 191 + 21 + + + + Right + + + + + + + buttonBox + accepted() + MeshDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MeshDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/example/weno-coef/crj/fortran/01/coef.f90 b/example/weno-coef/crj/fortran/01/coef.f90 new file mode 100644 index 00000000..543ec5c3 --- /dev/null +++ b/example/weno-coef/crj/fortran/01/coef.f90 @@ -0,0 +1,13 @@ +program main + implicit none + integer :: i, j + integer, parameter :: iorder = 2 + double precision :: coef(0:iorder-1, 0:iorder-1) + data ((coef(i,j),j=0,iorder-1),i=0,iorder-1) & + /0.5,0.5,-0.5,1.5/ + do i = 0, iorder-1 + do j = 0, iorder-1 + print *, 'coef(', i, ',', j, ') = ', coef(i,j) + end do + end do +end program main \ No newline at end of file diff --git a/example/weno-coef/crj/python/01/crj.py b/example/weno-coef/crj/python/01/crj.py new file mode 100644 index 00000000..c7658bdf --- /dev/null +++ b/example/weno-coef/crj/python/01/crj.py @@ -0,0 +1,44 @@ +import math + +def calculate_crj(r, j, k): + result = 0 + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += numerator / denominator + + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in [1, 2, 3]: + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"c_{r}{j} = {c_rj}") + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01a/crj.py b/example/weno-coef/crj/python/01a/crj.py new file mode 100644 index 00000000..12985c33 --- /dev/null +++ b/example/weno-coef/crj/python/01a/crj.py @@ -0,0 +1,59 @@ +import math +from fractions import Fraction + +def divide_as_simplified_fraction(a, b): + if b == 0: + raise ValueError("分母不能为零!") + + # 计算最大公约数(GCD) + gcd_value = math.gcd(a, b) + + # 化简分数 + simplified_num = a // gcd_value + simplified_den = b // gcd_value + + # 返回最简分数形式 + return f"{simplified_num}/{simplified_den}" + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + #result += numerator / denominator + result += Fraction(numerator, denominator) + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in [1, 2, 3]: + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"c_{r}{j} = {c_rj}") + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01b/crj.py b/example/weno-coef/crj/python/01b/crj.py new file mode 100644 index 00000000..d1fc6399 --- /dev/null +++ b/example/weno-coef/crj/python/01b/crj.py @@ -0,0 +1,46 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + #result += numerator / denominator + result += Fraction(numerator, denominator) + return result + +# 计算并输出 k=1, 2, 3 时的所有 c_rj +for k in range(1,8): + print(f"=== k = {k} ===") + for r in range(0, k): + for j in range(0, k): + c_rj = calculate_crj(r, j, k) + print(f"{c_rj} ", end='') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01c/crj.py b/example/weno-coef/crj/python/01c/crj.py new file mode 100644 index 00000000..aecd468c --- /dev/null +++ b/example/weno-coef/crj/python/01c/crj.py @@ -0,0 +1,54 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += Fraction(numerator, denominator) + return result + + +for k in range(1,8): + print(f"=== k = {k} ===") + # 计算矩阵并存储到列表中 + mat = [] + for r in range(k): + row = [] + for j in range(k): + c_rj = calculate_crj(r, j, k) + row.append(c_rj) + mat.append(row) + # 计算每个分数的最大宽度 + max_width = max(len(str(item)) for row in mat for item in row) + for row in mat: + for item in row: + print(f"{str(item):^{max_width}}", end=' ') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/01d/crj.py b/example/weno-coef/crj/python/01d/crj.py new file mode 100644 index 00000000..bca0716b --- /dev/null +++ b/example/weno-coef/crj/python/01d/crj.py @@ -0,0 +1,54 @@ +import math +from fractions import Fraction + +def calculate_crj(r, j, k): + result = Fraction(0, 1) + + # 外层求和:m 从 j+1 到 k + for m in range(j + 1, k + 1): + numerator = 0 + + # 内层求和:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + + product = 1 + + # 内层连乘:q 从 0 到 k,且 q ≠ m, l + for q in range(0, k + 1): + if q == m or q == l: + continue # 跳过 q = m 或 q = l 的情况 + product *= (r - q + 1) + + numerator += product + + denominator = 1 + + # 分母连乘:l 从 0 到 k,且 l ≠ m + for l in range(0, k + 1): + if l == m: + continue # 跳过 l = m 的情况 + denominator *= (m - l) + + result += Fraction(numerator, denominator) + return result + + +for k in range(1,8): + print(f"=== k = {k} ===") + # 计算矩阵并存储到列表中 + mat = [] + for r in range(-1,k): + row = [] + for j in range(k): + c_rj = calculate_crj(r, j, k) + row.append(c_rj) + mat.append(row) + # 计算每个分数的最大宽度 + max_width = max(len(str(item)) for row in mat for item in row) + for row in mat: + for item in row: + print(f"{str(item):^{max_width}}", end=' ') + print() + print() \ No newline at end of file diff --git a/example/weno-coef/crj/python/02/crj.py b/example/weno-coef/crj/python/02/crj.py new file mode 100644 index 00000000..12eedccc --- /dev/null +++ b/example/weno-coef/crj/python/02/crj.py @@ -0,0 +1,27 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 一维差分示意图 +def plot_1d_fdm(): + # 定义网格点 + x = np.linspace(0, 1, 6) # 6个网格点 + dx = x[1] - x[0] # 网格间距 + + # 绘制网格点 + plt.figure(figsize=(8, 2)) + plt.scatter(x, np.zeros_like(x), color='black', s=100, zorder=5) + for i, xi in enumerate(x): + plt.text(xi, -0.05, f'$x_{i}$', ha='center', fontsize=12) + + # 绘制网格线 + for i in range(len(x) - 1): + plt.plot([x[i], x[i + 1]], [0, 0], color='black', linestyle='--', linewidth=1) + + # 添加标题和标签 + plt.title('One-Dimensional Finite Difference Grid', fontsize=14) + plt.xlabel('x', fontsize=12) + plt.yticks([]) + plt.grid(False) + plt.show() + +plot_1d_fdm() \ No newline at end of file diff --git a/example/weno-coef/crj/python/02a/crj.py b/example/weno-coef/crj/python/02a/crj.py new file mode 100644 index 00000000..0323f1bf --- /dev/null +++ b/example/weno-coef/crj/python/02a/crj.py @@ -0,0 +1,35 @@ +import matplotlib.pyplot as plt +import numpy as np + +# 二维差分示意图 +def plot_2d_fdm(): + # 定义网格点 + x = np.linspace(0, 1, 5) # 5个网格点 + y = np.linspace(0, 1, 5) # 5个网格点 + dx = x[1] - x[0] # 网格间距 + dy = y[1] - y[0] # 网格间距 + + # 创建网格 + X, Y = np.meshgrid(x, y) + + # 绘制网格点 + plt.figure(figsize=(6, 6)) + plt.scatter(X, Y, color='black', s=100, zorder=5) + for i in range(len(x)): + for j in range(len(y)): + plt.text(X[j, i], Y[j, i], f'({i},{j})', ha='center', fontsize=10) + + # 绘制网格线 + for i in range(len(x)): + plt.plot(X[i, :], Y[i, :], color='black', linestyle='--', linewidth=1) + for j in range(len(y)): + plt.plot(X[:, j], Y[:, j], color='black', linestyle='--', linewidth=1) + + # 添加标题和标签 + plt.title('Two-Dimensional Finite Difference Grid', fontsize=14) + plt.xlabel('x', fontsize=12) + plt.ylabel('y', fontsize=12) + plt.grid(False) + plt.show() + +plot_2d_fdm() \ No newline at end of file diff --git a/example/weno-coef/divide_as_simplified_fraction/div.py b/example/weno-coef/divide_as_simplified_fraction/div.py new file mode 100644 index 00000000..6562990e --- /dev/null +++ b/example/weno-coef/divide_as_simplified_fraction/div.py @@ -0,0 +1,21 @@ +import math + +def divide_as_simplified_fraction(a, b): + if b == 0: + raise ValueError("分母不能为零!") + + # 计算最大公约数(GCD) + gcd_value = math.gcd(a, b) + + # 化简分数 + simplified_num = a // gcd_value + simplified_den = b // gcd_value + + # 返回最简分数形式 + return f"{simplified_num}/{simplified_den}" + +# 示例 +a = 10 +b = 4 +result = divide_as_simplified_fraction(a, b) +print(f"{a} / {b} = {result}") \ No newline at end of file diff --git a/example/weno-coef/eno/01/testprj.py b/example/weno-coef/eno/01/testprj.py new file mode 100644 index 00000000..2398ea60 --- /dev/null +++ b/example/weno-coef/eno/01/testprj.py @@ -0,0 +1,58 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义列向量和矩阵 +vector = np.array([[1, -0.5, 0.25]]) +matrix = np.array([[-1/24, 13/12, -1/24], + [-0.5, 0, 0.5], + [0.5, -1, 0.5]]) + +# 计算矩阵乘法 +result = np.dot(vector, matrix) + +# 打印结果 +print("Result of matrix multiplication:") +#print(result) +print_matrix_fraction(result) \ No newline at end of file diff --git a/example/weno-coef/eno/01a/testprj.py b/example/weno-coef/eno/01a/testprj.py new file mode 100644 index 00000000..5fe976a6 --- /dev/null +++ b/example/weno-coef/eno/01a/testprj.py @@ -0,0 +1,18 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + print(row) + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/eno/01b/testprj.py b/example/weno-coef/eno/01b/testprj.py new file mode 100644 index 00000000..5afcadc7 --- /dev/null +++ b/example/weno-coef/eno/01b/testprj.py @@ -0,0 +1,70 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/eno/01c/testprj.py b/example/weno-coef/eno/01c/testprj.py new file mode 100644 index 00000000..cc9f7662 --- /dev/null +++ b/example/weno-coef/eno/01c/testprj.py @@ -0,0 +1,76 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, 0, 1/12], [1, 1, 13/12], [1, 2, 49/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = np.array([[1, -1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + diff --git a/example/weno-coef/eno/02/testprj.py b/example/weno-coef/eno/02/testprj.py new file mode 100644 index 00000000..56889fa4 --- /dev/null +++ b/example/weno-coef/eno/02/testprj.py @@ -0,0 +1,133 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k,lr): + arrays_list = [] + #k = r + s + 1 + ishift = 0 + if lr == 1: + ishift = -1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii+ishift,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k,lr): + matrix = create_matrix(r,s,k,lr) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + xi = 0.5 + if lr == 1: + xi = -0.5 + + m1 = compute_coef(xi,k).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + + +k=3 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +lr = -1 +#lr = 1 + +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k,lr) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/eno/03/matrix_data.txt b/example/weno-coef/eno/03/matrix_data.txt new file mode 100644 index 00000000..099bb3dc --- /dev/null +++ b/example/weno-coef/eno/03/matrix_data.txt @@ -0,0 +1,6 @@ +137/60, -163/60, 137/60, -21/20, 1/5 +1/5, 77/60, -43/60, 17/60, -1/20 +-1/20, 9/20, 47/60, -13/60, 1/30 +1/30, -13/60, 47/60, 9/20, -1/20 +-1/20, 17/60, -43/60, 77/60, 1/5 +1/5, -21/20, 137/60, -163/60, 137/60 \ No newline at end of file diff --git a/example/weno-coef/eno/03/testprj.py b/example/weno-coef/eno/03/testprj.py new file mode 100644 index 00000000..5d6883a4 --- /dev/null +++ b/example/weno-coef/eno/03/testprj.py @@ -0,0 +1,23 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 分割每行的数据 + elements = line.strip().split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = map(float, element.split('/')) + # 计算浮点数结果 + row.append(numerator / denominator) + matrix.append(row) + return matrix + +# 示例:读取文件 +file_path = 'matrix_data.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]:.1f}") \ No newline at end of file diff --git a/example/weno-coef/eno/03a/matrix_data.txt b/example/weno-coef/eno/03a/matrix_data.txt new file mode 100644 index 00000000..099bb3dc --- /dev/null +++ b/example/weno-coef/eno/03a/matrix_data.txt @@ -0,0 +1,6 @@ +137/60, -163/60, 137/60, -21/20, 1/5 +1/5, 77/60, -43/60, 17/60, -1/20 +-1/20, 9/20, 47/60, -13/60, 1/30 +1/30, -13/60, 47/60, 9/20, -1/20 +-1/20, 17/60, -43/60, 77/60, 1/5 +1/5, -21/20, 137/60, -163/60, 137/60 \ No newline at end of file diff --git a/example/weno-coef/eno/03a/testprj.py b/example/weno-coef/eno/03a/testprj.py new file mode 100644 index 00000000..5799d211 --- /dev/null +++ b/example/weno-coef/eno/03a/testprj.py @@ -0,0 +1,23 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 分割每行的数据 + elements = line.strip().split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +# 示例:读取文件 +file_path = 'matrix_data.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/eno/03b/matrix_data.txt b/example/weno-coef/eno/03b/matrix_data.txt new file mode 100644 index 00000000..dcfa6393 --- /dev/null +++ b/example/weno-coef/eno/03b/matrix_data.txt @@ -0,0 +1,7 @@ +[ 49/20, -71/20, 79/20, -163/60, 31/30, -1/6 ] +[ 1/6, 29/20, -21/20, 37/60, -13/60, 1/30 ] +[ -1/30, 11/30, 19/20, -23/60, 7/60, -1/60 ] +[ 1/60, -2/15, 37/60, 37/60, -2/15, 1/60 ] +[ -1/60, 7/60, -23/60, 19/20, 11/30, -1/30 ] +[ 1/30, -13/60, 37/60, -21/20, 29/20, 1/6 ] +[ -1/6, 31/30, -163/60, 79/20, -71/20, 49/20 ] \ No newline at end of file diff --git a/example/weno-coef/eno/03b/matrix_output.txt b/example/weno-coef/eno/03b/matrix_output.txt new file mode 100644 index 00000000..e7de556a --- /dev/null +++ b/example/weno-coef/eno/03b/matrix_output.txt @@ -0,0 +1,42 @@ +coef(0, 0) = 49.0/20.0 +coef(0, 1) = -71.0/20.0 +coef(0, 2) = 79.0/20.0 +coef(0, 3) = -163.0/60.0 +coef(0, 4) = 31.0/30.0 +coef(0, 5) = -1.0/6.0 +coef(1, 0) = 1.0/6.0 +coef(1, 1) = 29.0/20.0 +coef(1, 2) = -21.0/20.0 +coef(1, 3) = 37.0/60.0 +coef(1, 4) = -13.0/60.0 +coef(1, 5) = 1.0/30.0 +coef(2, 0) = -1.0/30.0 +coef(2, 1) = 11.0/30.0 +coef(2, 2) = 19.0/20.0 +coef(2, 3) = -23.0/60.0 +coef(2, 4) = 7.0/60.0 +coef(2, 5) = -1.0/60.0 +coef(3, 0) = 1.0/60.0 +coef(3, 1) = -2.0/15.0 +coef(3, 2) = 37.0/60.0 +coef(3, 3) = 37.0/60.0 +coef(3, 4) = -2.0/15.0 +coef(3, 5) = 1.0/60.0 +coef(4, 0) = -1.0/60.0 +coef(4, 1) = 7.0/60.0 +coef(4, 2) = -23.0/60.0 +coef(4, 3) = 19.0/20.0 +coef(4, 4) = 11.0/30.0 +coef(4, 5) = -1.0/30.0 +coef(5, 0) = 1.0/30.0 +coef(5, 1) = -13.0/60.0 +coef(5, 2) = 37.0/60.0 +coef(5, 3) = -21.0/20.0 +coef(5, 4) = 29.0/20.0 +coef(5, 5) = 1.0/6.0 +coef(6, 0) = -1.0/6.0 +coef(6, 1) = 31.0/30.0 +coef(6, 2) = -163.0/60.0 +coef(6, 3) = 79.0/20.0 +coef(6, 4) = -71.0/20.0 +coef(6, 5) = 49.0/20.0 diff --git a/example/weno-coef/eno/03b/testprj.py b/example/weno-coef/eno/03b/testprj.py new file mode 100644 index 00000000..a3f7ff9e --- /dev/null +++ b/example/weno-coef/eno/03b/testprj.py @@ -0,0 +1,35 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 去掉每行首尾的方括号和空格 + line = line.strip().strip('[]') + # 分割每行的数据 + elements = line.split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +def write_matrix_to_file(matrix, output_file_path): + with open(output_file_path, 'w') as file: + for i in range(len(matrix)): + for j in range(len(matrix[i])): + file.write(f"coef({i}, {j}) = {matrix[i][j]}\n") + +# 示例:读取文件 +file_path = 'matrix_data.txt' +output_file_path = 'matrix_output.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果到文件 +write_matrix_to_file(matrix, output_file_path) + +# 打印结果到控制台 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/eno/03c/matrix_data.txt b/example/weno-coef/eno/03c/matrix_data.txt new file mode 100644 index 00000000..0a4d2545 --- /dev/null +++ b/example/weno-coef/eno/03c/matrix_data.txt @@ -0,0 +1,8 @@ +[ 363/140, -617/140, 853/140, -2341/420, 667/210, -43/42, 1/7 ] +[ 1/7, 223/140, -197/140, 153/140, -241/420, 37/210, -1/42 ] +[ -1/42, 13/42, 153/140, -241/420, 109/420, -31/420, 1/105 ] +[ 1/105, -19/210, 107/210, 319/420, -101/420, 5/84, -1/140 ] +[ -1/140, 5/84, -101/420, 319/420, 107/210, -19/210, 1/105 ] +[ 1/105, -31/420, 109/420, -241/420, 153/140, 13/42, -1/42 ] +[ -1/42, 37/210, -241/420, 153/140, -197/140, 223/140, 1/7 ] +[ 1/7, -43/42, 667/210, -2341/420, 853/140, -617/140, 363/140 ] \ No newline at end of file diff --git a/example/weno-coef/eno/03c/matrix_output.txt b/example/weno-coef/eno/03c/matrix_output.txt new file mode 100644 index 00000000..a45ca96a --- /dev/null +++ b/example/weno-coef/eno/03c/matrix_output.txt @@ -0,0 +1,56 @@ +coef(0, 0) = 363.0/140.0 +coef(0, 1) = -617.0/140.0 +coef(0, 2) = 853.0/140.0 +coef(0, 3) = -2341.0/420.0 +coef(0, 4) = 667.0/210.0 +coef(0, 5) = -43.0/42.0 +coef(0, 6) = 1.0/7.0 +coef(1, 0) = 1.0/7.0 +coef(1, 1) = 223.0/140.0 +coef(1, 2) = -197.0/140.0 +coef(1, 3) = 153.0/140.0 +coef(1, 4) = -241.0/420.0 +coef(1, 5) = 37.0/210.0 +coef(1, 6) = -1.0/42.0 +coef(2, 0) = -1.0/42.0 +coef(2, 1) = 13.0/42.0 +coef(2, 2) = 153.0/140.0 +coef(2, 3) = -241.0/420.0 +coef(2, 4) = 109.0/420.0 +coef(2, 5) = -31.0/420.0 +coef(2, 6) = 1.0/105.0 +coef(3, 0) = 1.0/105.0 +coef(3, 1) = -19.0/210.0 +coef(3, 2) = 107.0/210.0 +coef(3, 3) = 319.0/420.0 +coef(3, 4) = -101.0/420.0 +coef(3, 5) = 5.0/84.0 +coef(3, 6) = -1.0/140.0 +coef(4, 0) = -1.0/140.0 +coef(4, 1) = 5.0/84.0 +coef(4, 2) = -101.0/420.0 +coef(4, 3) = 319.0/420.0 +coef(4, 4) = 107.0/210.0 +coef(4, 5) = -19.0/210.0 +coef(4, 6) = 1.0/105.0 +coef(5, 0) = 1.0/105.0 +coef(5, 1) = -31.0/420.0 +coef(5, 2) = 109.0/420.0 +coef(5, 3) = -241.0/420.0 +coef(5, 4) = 153.0/140.0 +coef(5, 5) = 13.0/42.0 +coef(5, 6) = -1.0/42.0 +coef(6, 0) = -1.0/42.0 +coef(6, 1) = 37.0/210.0 +coef(6, 2) = -241.0/420.0 +coef(6, 3) = 153.0/140.0 +coef(6, 4) = -197.0/140.0 +coef(6, 5) = 223.0/140.0 +coef(6, 6) = 1.0/7.0 +coef(7, 0) = 1.0/7.0 +coef(7, 1) = -43.0/42.0 +coef(7, 2) = 667.0/210.0 +coef(7, 3) = -2341.0/420.0 +coef(7, 4) = 853.0/140.0 +coef(7, 5) = -617.0/140.0 +coef(7, 6) = 363.0/140.0 diff --git a/example/weno-coef/eno/03c/testprj.py b/example/weno-coef/eno/03c/testprj.py new file mode 100644 index 00000000..a3f7ff9e --- /dev/null +++ b/example/weno-coef/eno/03c/testprj.py @@ -0,0 +1,35 @@ +def read_matrix_from_file(file_path): + matrix = [] + with open(file_path, 'r') as file: + for line in file: + # 去掉每行首尾的方括号和空格 + line = line.strip().strip('[]') + # 分割每行的数据 + elements = line.split(', ') + row = [] + for element in elements: + # 分割分子和分母 + numerator, denominator = element.split('/') + # 确保分子和分母是浮点数形式 + row.append(f"{float(numerator):.1f}/{float(denominator):.1f}") + matrix.append(row) + return matrix + +def write_matrix_to_file(matrix, output_file_path): + with open(output_file_path, 'w') as file: + for i in range(len(matrix)): + for j in range(len(matrix[i])): + file.write(f"coef({i}, {j}) = {matrix[i][j]}\n") + +# 示例:读取文件 +file_path = 'matrix_data.txt' +output_file_path = 'matrix_output.txt' +matrix = read_matrix_from_file(file_path) + +# 输出结果到文件 +write_matrix_to_file(matrix, output_file_path) + +# 打印结果到控制台 +for i in range(len(matrix)): + for j in range(len(matrix[i])): + print(f"coef({i}, {j}) = {matrix[i][j]}") \ No newline at end of file diff --git a/example/weno-coef/fractions/01/testprj.py b/example/weno-coef/fractions/01/testprj.py new file mode 100644 index 00000000..8b8b1bef --- /dev/null +++ b/example/weno-coef/fractions/01/testprj.py @@ -0,0 +1,23 @@ +import numpy as np +from fractions import Fraction + +def calculate_determinant(matrix): + det = np.linalg.det(matrix) + return Fraction(det).limit_denominator() + +def calculate_adjugate(matrix): + cofactor_matrix = np.linalg.inv(matrix).T + return cofactor_matrix.tolist() + +def inverse_matrix(matrix): + det = calculate_determinant(matrix) + if det == 0: + raise ValueError("Matrix is singular and does not have an inverse.") + adjugate = calculate_adjugate(matrix) + inverse = [[Fraction(adjugate[i][j]) / det for j in range(len(adjugate))] for i in range(len(adjugate))] + return inverse + +matrix = np.array([[1, -1, 13/12], [1, 0, 1/12], [1, 1, 13/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/02/testprj.py b/example/weno-coef/fractions/02/testprj.py new file mode 100644 index 00000000..6d04ee6f --- /dev/null +++ b/example/weno-coef/fractions/02/testprj.py @@ -0,0 +1,12 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +matrix = np.array([[1, -1, 13/12], [1, 0, 1/12], [1, 1, 13/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/02a/testprj.py b/example/weno-coef/fractions/02a/testprj.py new file mode 100644 index 00000000..77f24b02 --- /dev/null +++ b/example/weno-coef/fractions/02a/testprj.py @@ -0,0 +1,30 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 +original_matrix = np.array([[1, -1, 13/12], + [1, 0, 1/12], + [1, 1, 13/12]]) + +# 定义计算出的逆矩阵 +inverse_matrix = np.array([[Fraction(-1, 24), Fraction(13, 12), Fraction(-1, 24)], + [Fraction(-1, 2), Fraction(0, 1), Fraction(1, 2)], + [Fraction(1, 2), Fraction(-1, 1), Fraction(1, 2)]]) + +# 将 Fraction 转换为浮点数进行矩阵乘法 +original_matrix = original_matrix.astype(float) +inverse_matrix = inverse_matrix.astype(float) + +# 计算两个矩阵的乘积 +product = np.dot(original_matrix, inverse_matrix) + +# 检查乘积是否接近单位矩阵 +identity_matrix = np.eye(3) + +# 打印结果 +print("Product of the matrices:") +print(product) +print("\nIdentity matrix:") +print(identity_matrix) +print("\nDifference:") +print(np.abs(product - identity_matrix) < 1e-9) \ No newline at end of file diff --git a/example/weno-coef/fractions/03/testprj.py b/example/weno-coef/fractions/03/testprj.py new file mode 100644 index 00000000..5383b701 --- /dev/null +++ b/example/weno-coef/fractions/03/testprj.py @@ -0,0 +1,12 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) +inverse = inverse_matrix(matrix) +for row in inverse: + print(row) \ No newline at end of file diff --git a/example/weno-coef/fractions/03a/testprj.py b/example/weno-coef/fractions/03a/testprj.py new file mode 100644 index 00000000..d0c902b0 --- /dev/null +++ b/example/weno-coef/fractions/03a/testprj.py @@ -0,0 +1,31 @@ +import numpy as np +from fractions import Fraction + +# 定义矩阵 A 的元素 +A = np.array([ + [Fraction(1, 1), Fraction(-2, 1), Fraction(49, 12)], + [Fraction(1, 1), Fraction(-1, 1), Fraction(13, 12)], + [Fraction(1, 1), Fraction(0, 1), Fraction(1, 12)] +], dtype=object) + +# 打印矩阵 A +print("Matrix A:") +for row in A: + print("[" + ", ".join(str(frac) for frac in row) + "]") + + +# 计算 A * A +product_AA = np.dot(A, A) + +# 打印矩阵 A * A +print("Matrix A * A:") +for row in product_AA: + print("[" + ", ".join(str(frac) for frac in row) + "]") + +# 计算矩阵 A 的逆矩阵 +A_inv = np.linalg.inv(A).astype(object) + +# 打印矩阵 A 的逆矩阵 +print("Inverse of Matrix A:") +for row in A_inv: + print("[" + ", ".join(str(Fraction(int(x.real), int(y))) if y != 0 else str(int(x.real)) for x, y in zip(row, [1, 1, 1])) + "]") \ No newline at end of file diff --git a/example/weno-coef/fractions/03b/testprj.py b/example/weno-coef/fractions/03b/testprj.py new file mode 100644 index 00000000..2cb708f6 --- /dev/null +++ b/example/weno-coef/fractions/03b/testprj.py @@ -0,0 +1,18 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + print(row) + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/03c/testprj.py b/example/weno-coef/fractions/03c/testprj.py new file mode 100644 index 00000000..cbbb31d9 --- /dev/null +++ b/example/weno-coef/fractions/03c/testprj.py @@ -0,0 +1,19 @@ +import numpy as np +from fractions import Fraction + +# 定义原始矩阵 original_matrix +original_matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +# 调用函数打印矩阵 +print_matrix_fraction(original_matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/03d/testprj.py b/example/weno-coef/fractions/03d/testprj.py new file mode 100644 index 00000000..511b7d82 --- /dev/null +++ b/example/weno-coef/fractions/03d/testprj.py @@ -0,0 +1,25 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + inverse = np.linalg.inv(matrix) + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵 +print_matrix_fraction(matrix) +print_matrix_fraction(inverse) \ No newline at end of file diff --git a/example/weno-coef/fractions/03e/testprj.py b/example/weno-coef/fractions/03e/testprj.py new file mode 100644 index 00000000..16011164 --- /dev/null +++ b/example/weno-coef/fractions/03e/testprj.py @@ -0,0 +1,45 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印,行列等宽对齐 +def print_matrix_fraction(matrix): + # 找到每列最大宽度 + col_widths = [0] * matrix.shape[1] + for row in matrix: + for i, elem in enumerate(row): + # 将元素转换为字符串形式,包括分子和分母 + elem_str = f"{elem.numerator}/{elem.denominator}" if hasattr(elem, 'denominator') and elem.denominator > 1 else str(elem) + col_widths[i] = max(col_widths[i], len(elem_str)) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in matrix: + formatted_row = ", ".join(f"{{:^{col_widths[i]}}}".format(f"{elem.numerator}/{elem.denominator}" if hasattr(elem, 'denominator') and elem.denominator > 1 else elem) for i, elem in enumerate(row)) + print(f"[{formatted_row}]") + + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03f/testprj.py b/example/weno-coef/fractions/03f/testprj.py new file mode 100644 index 00000000..0f6093d0 --- /dev/null +++ b/example/weno-coef/fractions/03f/testprj.py @@ -0,0 +1,52 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fractionOLD(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + print("[" + ", ".join(f"{f.numerator}/{f.denominator}" if f.denominator > 1 else str(f.numerator) for f in row) + "]") + +# 定义一个函数,将矩阵中的每个元素转换为 Fraction 类型并打印 +def print_matrix_fraction(matrix): + # 使用列表推导式和 Fraction 转换每个元素 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 打印转换后的矩阵 + print("Matrix in Fraction Form:") + for row in fraction_matrix: + # 将每个 Fraction 对象转换为字符串,并以指定格式打印 + # 使用格式化字符串确保每个元素占用相同的宽度 + formatted_row = ", ".join(f"{f.numerator:2}/{f.denominator:2}" if f.denominator > 1 else f"{f.numerator:2}" for f in row) + print(f"[{formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03g/testprj.py b/example/weno-coef/fractions/03g/testprj.py new file mode 100644 index 00000000..4edb3e5f --- /dev/null +++ b/example/weno-coef/fractions/03g/testprj.py @@ -0,0 +1,71 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + rows = len(str_matrix) + cols = len(str_matrix[0]) + + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐 + formatted_element = f"{element:>{max_width}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + + + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/03h/testprj.py b/example/weno-coef/fractions/03h/testprj.py new file mode 100644 index 00000000..9876a6fe --- /dev/null +++ b/example/weno-coef/fractions/03h/testprj.py @@ -0,0 +1,70 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + diff --git a/example/weno-coef/fractions/04/testprj.py b/example/weno-coef/fractions/04/testprj.py new file mode 100644 index 00000000..11975c1f --- /dev/null +++ b/example/weno-coef/fractions/04/testprj.py @@ -0,0 +1,37 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽对齐 + print("Matrix in Fraction Form:") + for row in str_matrix: + formatted_elements = [f"{s:>{max_width}}" for s in row] + formatted_row = " ".join(formatted_elements) + print(f"[ {formatted_row} ]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04a/testprj.py b/example/weno-coef/fractions/04a/testprj.py new file mode 100644 index 00000000..bc3369ed --- /dev/null +++ b/example/weno-coef/fractions/04a/testprj.py @@ -0,0 +1,51 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算最大宽度 + str_matrix = [] + max_width = 0 + for row in fraction_matrix: + str_row = [] + for f in row: + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > max_width: + max_width = current_length + str_matrix.append(str_row) + + # 打印矩阵,每个元素等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + rows = len(str_matrix) + cols = len(str_matrix[0]) + + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐 + formatted_element = f"{element:>{max_width}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04b/testprj.py b/example/weno-coef/fractions/04b/testprj.py new file mode 100644 index 00000000..df522808 --- /dev/null +++ b/example/weno-coef/fractions/04b/testprj.py @@ -0,0 +1,52 @@ +import numpy as np +from fractions import Fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 示例用法 +matrix = [ + [0.5, 3, 0.714285714], + [10, 1.333333333, 6], + [0.875, 11.111111111, 2] +] +print_matrix_fraction(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04c/testprj.py b/example/weno-coef/fractions/04c/testprj.py new file mode 100644 index 00000000..151b6784 --- /dev/null +++ b/example/weno-coef/fractions/04c/testprj.py @@ -0,0 +1,11 @@ +import numpy as np + +# 定义列表 ii +ii = [-2, -1, 0] + +# 将列表 ii 转化为 NumPy 数组 matrix +matrix = np.array(ii) + +# 打印结果 +print("Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04d/testprj.py b/example/weno-coef/fractions/04d/testprj.py new file mode 100644 index 00000000..dea6c772 --- /dev/null +++ b/example/weno-coef/fractions/04d/testprj.py @@ -0,0 +1,11 @@ +import numpy as np + +# 定义列表 ii +ii = [-2, -1, 0] + +# 将列表 ii 转化为一个 1x3 的 NumPy 二维数组 matrix +matrix = np.array(ii).reshape(1, -1) + +# 打印结果 +print("Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04e/testprj.py b/example/weno-coef/fractions/04e/testprj.py new file mode 100644 index 00000000..1a5b50cb --- /dev/null +++ b/example/weno-coef/fractions/04e/testprj.py @@ -0,0 +1,13 @@ +import numpy as np + +# 定义三个二维数组 +a1 = np.array([[1, 1, 1]]) +a2 = np.array([[2, 2, 2]]) +a3 = np.array([[3, 3, 3]]) + +# 使用 vstack 函数将这三个数组垂直堆叠成一个矩阵 +matrix = np.vstack((a1, a2, a3)) + +# 打印结果 +print("Assembled Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/04f/testprj.py b/example/weno-coef/fractions/04f/testprj.py new file mode 100644 index 00000000..0fa20273 --- /dev/null +++ b/example/weno-coef/fractions/04f/testprj.py @@ -0,0 +1,19 @@ +import numpy as np + +# 创建一个列表来存储所有数组 +arrays_list = [] + +# 动态地添加数组到列表中 +arrays_list.append(np.array([[1, 1, 1]])) +arrays_list.append(np.array([[2, 2, 2]])) +arrays_list.append(np.array([[3, 3, 3]])) +# 如果有更多数组,可以继续添加 +# arrays_list.append(np.array([[4, 4, 4]])) +# arrays_list.append(np.array([[5, 5, 5]])) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +# 打印结果 +print("Assembled Matrix:") +print(matrix) \ No newline at end of file diff --git a/example/weno-coef/fractions/05/testprj.py b/example/weno-coef/fractions/05/testprj.py new file mode 100644 index 00000000..7f078fb0 --- /dev/null +++ b/example/weno-coef/fractions/05/testprj.py @@ -0,0 +1,77 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +# 定义原始矩阵 matrix +matrix = np.array([[1, -2, 49/12], [1, -1, 13/12], [1, 0, 1/12]]) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +# 调用函数打印矩阵和逆矩阵 +print_matrix_fraction(matrix) +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + + +m1 = np.array([[1, 1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + diff --git a/example/weno-coef/fractions/05a/testprj.py b/example/weno-coef/fractions/05a/testprj.py new file mode 100644 index 00000000..4a78daa5 --- /dev/null +++ b/example/weno-coef/fractions/05a/testprj.py @@ -0,0 +1,112 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def create_matrix(): + ii = np.array([[-2,-1,0]]) + print(f"{ii=}") + ilower = ii - 1/2 + iupper = ii + 1/2 + print(f"{iupper=}") + print(f"{ilower=}") + + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +matrix = create_matrix() + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + + +m1 = np.array([[1, 1/2, 1/4]]) +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05b/testprj.py b/example/weno-coef/fractions/05b/testprj.py new file mode 100644 index 00000000..6f0f2afe --- /dev/null +++ b/example/weno-coef/fractions/05b/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(): + ii = np.array([[-2,-1,0]]) + print(f"{ii=}") + ilower = ii - 1/2 + iupper = ii + 1/2 + print(f"{iupper=}") + print(f"{ilower=}") + + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +matrix = create_matrix() + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = compute_coef(0.5).reshape(1, -1) +print_matrix_fraction(m1) + +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05c/testprj.py b/example/weno-coef/fractions/05c/testprj.py new file mode 100644 index 00000000..b198ff6b --- /dev/null +++ b/example/weno-coef/fractions/05c/testprj.py @@ -0,0 +1,148 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(): + x0 = compute_diff_coef(-2) + x1 = compute_diff_coef(-1) + x2 = compute_diff_coef(0) + print(f"{x0=}") + print(f"{x1=}") + print(f"{x2=}") + + arrays_list = [] + + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x0) + arrays_list.append(x1) + arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def create_matrix_new(k): + k1 = k-1 + print(f'{k1=}') + + for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + #x0 = compute_diff_coef(-2) + #x1 = compute_diff_coef(-1) + #x2 = compute_diff_coef(0) + #print(f"{x0=}") + #print(f"{x1=}") + #print(f"{x2=}") + + + # 动态地生成一些一维数组并添加到列表中 + #arrays_list.append(x0) + #arrays_list.append(x1) + #arrays_list.append(x2) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +#matrix = create_matrix() +k=3 +matrix = create_matrix_new(k) + +print_matrix_fraction(matrix) + +# 计算逆矩阵 +inverse = inverse_matrix(matrix) + +print("\nInverse Matrix in Fraction Form:") +print_matrix_fraction(inverse) + +# 计算两个矩阵的乘积 +product = np.dot(matrix, inverse) + +print("\nProduct of Matrix and Inverse Matrix:") +print_matrix_fraction(product) + +m1 = compute_coef(0.5).reshape(1, -1) +print_matrix_fraction(m1) + +mc = np.dot(m1, inverse) + +print("\n Matrix C:") +print_matrix_fraction(mc) + + diff --git a/example/weno-coef/fractions/05d/testprj.py b/example/weno-coef/fractions/05d/testprj.py new file mode 100644 index 00000000..7700ace6 --- /dev/null +++ b/example/weno-coef/fractions/05d/testprj.py @@ -0,0 +1,120 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(k): + k1 = k-1 + print(f'{k1=}') + + for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def calc_eno_coef(k): + matrix = create_matrix(k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + print("\nInverse Matrix in Fraction Form:") + print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + print("\nProduct of Matrix and Inverse Matrix:") + print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + #print("\n Matrix C:") + #print_matrix_fraction(mc) + return mc + +k=3 +mc = calc_eno_coef(k) +print("\n Matrix C:") +print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05e/testprj.py b/example/weno-coef/fractions/05e/testprj.py new file mode 100644 index 00000000..e57f3cff --- /dev/null +++ b/example/weno-coef/fractions/05e/testprj.py @@ -0,0 +1,127 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(k): + #k1 = k-1 + #print(f'{k1=}') + # + #for s in range(k): + # r = k1 - s + # print(f'{r=},{s=},{k=}') + r = 2 + s = 0 + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + +def calc_eno_coef(k): + matrix = create_matrix(k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + print("\nInverse Matrix in Fraction Form:") + print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + print("\nProduct of Matrix and Inverse Matrix:") + print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + #print("\n Matrix C:") + #print_matrix_fraction(mc) + return mc + +k=3 +k1 = k-1 +print(f'{k1=}') + +for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + +mc = calc_eno_coef(k) +print("\n Matrix C:") +print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05f/testprj.py b/example/weno-coef/fractions/05f/testprj.py new file mode 100644 index 00000000..f75c0cbb --- /dev/null +++ b/example/weno-coef/fractions/05f/testprj.py @@ -0,0 +1,117 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +print(f'{k1=}') + +for s in range(k): + r = k1 - s + print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + print("\n Matrix C:") + print_matrix_fraction(mc) diff --git a/example/weno-coef/fractions/05g/testprj.py b/example/weno-coef/fractions/05g/testprj.py new file mode 100644 index 00000000..406849b7 --- /dev/null +++ b/example/weno-coef/fractions/05g/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +for s in range(k): + r = k1 - s + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + #print("\n Matrix C:") + #print_matrix_fraction(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/05h/testprj.py b/example/weno-coef/fractions/05h/testprj.py new file mode 100644 index 00000000..5f5be5b2 --- /dev/null +++ b/example/weno-coef/fractions/05h/testprj.py @@ -0,0 +1,122 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +for s in range(k+1): + r = k1 - s + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/05i/testprj.py b/example/weno-coef/fractions/05i/testprj.py new file mode 100644 index 00000000..cdbffb66 --- /dev/null +++ b/example/weno-coef/fractions/05i/testprj.py @@ -0,0 +1,127 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(3) + y[0] = ( np.power(x1, 1) - np.power(x0, 1) ) / float(1) + y[1] = ( np.power(x1, 2) - np.power(x0, 2) ) / float(2) + y[2] = ( np.power(x1, 3) - np.power(x0, 3) ) / float(3) + return y + +def compute_coef(x): + y = np.zeros(3) + y[0] = np.power(x, 0) + y[1] = np.power(x, 1) + y[2] = np.power(x, 2) + return y + +def create_matrix(r,s): + arrays_list = [] + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=}') + x = compute_diff_coef(ii) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s): + matrix = create_matrix(r,s) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +k=3 +k1 = k-1 +#print(f'{k1=}') +arrays_list = [] + +#for s in range(k+1): +# r = k1 - s +# #print(f'{r=},{s=},{k=}') +# mc = calc_eno_coef(r,s) +# arrays_list.append(mc) +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06/testprj.py b/example/weno-coef/fractions/06/testprj.py new file mode 100644 index 00000000..937dc257 --- /dev/null +++ b/example/weno-coef/fractions/06/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +#k=3 +k=1 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +for r in range(-1,k): + s = k1 - r + print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06a/testprj.py b/example/weno-coef/fractions/06a/testprj.py new file mode 100644 index 00000000..97d33fff --- /dev/null +++ b/example/weno-coef/fractions/06a/testprj.py @@ -0,0 +1,124 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + + +k=1 +k1 = k-1 +print(f'{k=}') +#print(f'{k1=}') +arrays_list = [] + +for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + +# 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 +matrix = np.vstack(arrays_list) + +print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06b/testprj.py b/example/weno-coef/fractions/06b/testprj.py new file mode 100644 index 00000000..c859854f --- /dev/null +++ b/example/weno-coef/fractions/06b/testprj.py @@ -0,0 +1,125 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}" + else: + s = f"{f.numerator}/{f.denominator}" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +kmax = 7 + +for k in range(1,kmax+1): + k1 = k-1 + print(f'{k=}') + #print(f'{k1=}') + arrays_list = [] + + for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + + # 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + + print_matrix_fraction(matrix) diff --git a/example/weno-coef/fractions/06c/testprj.py b/example/weno-coef/fractions/06c/testprj.py new file mode 100644 index 00000000..12c4ac56 --- /dev/null +++ b/example/weno-coef/fractions/06c/testprj.py @@ -0,0 +1,125 @@ +import numpy as np +from fractions import Fraction + +def inverse_matrix(matrix): + # 将矩阵元素转换为浮点数以计算逆矩阵 + matrix_float = matrix.astype(float) + inverse = np.linalg.inv(matrix_float) + # 将逆矩阵元素转换为分数 + inverse_fraction = [[Fraction(inverse[i, j]).limit_denominator() for j in range(len(inverse))] for i in range(len(inverse))] + return inverse_fraction + +def print_matrix_fraction(matrix): + # 将矩阵转换为Fraction数组 + fraction_matrix = np.array([[Fraction(x).limit_denominator() for x in row] for row in matrix]) + + # 转换为字符串矩阵并计算每列的最大宽度 + str_matrix = [] + rows = len(fraction_matrix) + cols = len(fraction_matrix[0]) + col_widths = [0] * cols # 每列的最大宽度 + + # 将数字转换为字符串,并记录每列最大宽度 + for row in fraction_matrix: + str_row = [] + for j, f in enumerate(row): + if f.denominator == 1: + s = f"{f.numerator}.0" + else: + s = f"{f.numerator}.0/{f.denominator}.0" + str_row.append(s) + current_length = len(s) + if current_length > col_widths[j]: + col_widths[j] = current_length + str_matrix.append(str_row) + + # 打印矩阵,每列等宽右对齐,添加逗号 + #print("Matrix in Fraction Form:") + for i in range(rows): + row_elements = [] + for j in range(cols): + element = str_matrix[i][j] + # 右对齐,使用该列的最大宽度 + formatted_element = f"{element:>{col_widths[j]}}" + # 除最后一列外添加逗号和空格 + if j < cols - 1: + formatted_element += ", " + else: + formatted_element += " " + row_elements.append(formatted_element) + # 拼接一行并打印 + formatted_row = "".join(row_elements) + print(f"[ {formatted_row}]") + +def compute_diff_coef(x,k): + x0 = x - 1/2 + x1 = x + 1/2 + y = np.zeros(k) + for j in range(k): + j1 = j + 1 + y[j] = ( np.power(x1, j1) - np.power(x0, j1) ) / float(j1) + return y + +def compute_coef(x,k): + y = np.zeros(k) + for j in range(k): + y[j] = np.power(x, j) + return y + +def create_matrix(r,s,k): + arrays_list = [] + #k = r + s + 1 + for ii in range(-r,s+1): + #print(f'{ii=},{r=},{s=},{r+s=}') + x = compute_diff_coef(ii,k) + #print(f"{x=}") + # 动态地生成一些一维数组并添加到列表中 + arrays_list.append(x) + + # 使用 vstack 函数将列表中的数组堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + return matrix + + +def calc_eno_coef(r,s,k): + matrix = create_matrix(r,s,k) + + #print_matrix_fraction(matrix) + + # 计算逆矩阵 + inverse = inverse_matrix(matrix) + + #print("\nInverse Matrix in Fraction Form:") + #print_matrix_fraction(inverse) + + # 计算两个矩阵的乘积 + product = np.dot(matrix, inverse) + + #print("\nProduct of Matrix and Inverse Matrix:") + #print_matrix_fraction(product) + + m1 = compute_coef(0.5,k).reshape(1, -1) + #print_matrix_fraction(m1) + + mc = np.dot(m1, inverse) + + return mc + +kmax = 7 + +for k in range(1,kmax+1): + k1 = k-1 + print(f'{k=}') + #print(f'{k1=}') + arrays_list = [] + + for r in range(-1,k): + s = k1 - r + #print(f'{r=},{s=},{k=}') + mc = calc_eno_coef(r,s,k) + arrays_list.append(mc) + + # 使用 vstack 函数将列表中的所有数组垂直堆叠成一个矩阵 + matrix = np.vstack(arrays_list) + + print_matrix_fraction(matrix)