Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Fortran elastic-tube-1d solvers (precice Fortran module) #607

Merged
merged 37 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3cb99e6
Create initial folders and files
YonatanGM Jan 5, 2025
f44dbf8
Add scripts, test with minimal solvers
YonatanGM Jan 5, 2025
b8bcdc5
Implementation wip
YonatanGM Jan 6, 2025
4420eb5
Add output folder
YonatanGM Jan 6, 2025
4ff7dab
Implement vtk writing, Add missing write_data call in fluid solver
YonatanGM Jan 6, 2025
57bd144
Set domainSize to 100
YonatanGM Jan 6, 2025
9c8e714
Use ES format to output in scientific notation
YonatanGM Jan 6, 2025
72fdc83
Refactor: clean code, use snake_case for subroutines, apply dp for co…
YonatanGM Jan 6, 2025
5963731
Remove unused var
YonatanGM Jan 6, 2025
3ce8492
apply dp for consistent precision
YonatanGM Jan 6, 2025
9388e1a
Remove debug prints
YonatanGM Jan 6, 2025
6bb4cc2
Remove comment
YonatanGM Jan 6, 2025
c3c9be3
Include Fortran watchpoint in plot-all script
YonatanGM Jan 6, 2025
6796506
Improve print statement formatting
YonatanGM Jan 6, 2025
3ab0431
Remove debug compiler flags and clean up
YonatanGM Jan 7, 2025
b675f66
Set Fortran standard and enable warnings in debug builds
YonatanGM Jan 7, 2025
fb964db
Remove unused variable
YonatanGM Jan 7, 2025
b16ba90
Set character lengths to 50
YonatanGM Jan 7, 2025
75fe3e3
Add preCICE Fortran module file (precice.f90)
YonatanGM Jan 7, 2025
2cde8cb
Add preCICE Fortran module file (precice.f90)
YonatanGM Jan 7, 2025
9dd624a
Add Fortran module and update precicef_ calls with length args
YonatanGM Jan 7, 2025
67d1a8d
Add plotting for fluid fortran diameter
YonatanGM Jan 8, 2025
827a7c5
Delete file (now fetched dynamically)
YonatanGM Jan 8, 2025
aa9247e
Get precice.f90 from the fortran module repo in run script
YonatanGM Jan 8, 2025
0cddeb7
Add descriptive comment for info, fix variable capitalizations
YonatanGM Jan 27, 2025
af13235
Use 50 chars for outputFilePrefix
YonatanGM Jan 27, 2025
f14181a
Add comments from cpp, capitalize pi
YonatanGM Jan 27, 2025
f153c56
Remove Fortran standard
YonatanGM Jan 27, 2025
1e6f130
Added -module suffix to solver folders
YonatanGM Jan 27, 2025
b0d4593
Include fortran result in plot-all image
YonatanGM Jan 27, 2025
7d09f7f
Deleted folders
YonatanGM Jan 27, 2025
9be34a6
Include fluid-fortran-module results in plots
YonatanGM Jan 29, 2025
3f5b6c6
Update plot-all image
YonatanGM Jan 29, 2025
9e68835
Fix backslash
YonatanGM Jan 29, 2025
e5cb17d
Deleted file
YonatanGM Jan 29, 2025
ee37f0f
Add changelog entry
YonatanGM Jan 29, 2025
af9a497
Create output directory in run script
YonatanGM Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions elastic-tube-1d/fluid-fortran-module/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.10)
project(ElasticTube LANGUAGES Fortran C)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}")

# Add bounds check and warnings in debug build
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall -Wextra -fbounds-check")
endif()

find_package(precice 3 REQUIRED CONFIG)
find_package(LAPACK REQUIRED)

add_executable(FluidSolver
src/FluidComputeSolution.f90
src/utilities.f90
src/FluidSolver.f90
src/precice.f90
)

target_link_libraries(FluidSolver PRIVATE precice::precice)
target_link_libraries(FluidSolver PRIVATE ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS})

8 changes: 8 additions & 0 deletions elastic-tube-1d/fluid-fortran-module/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env sh
set -e -u

. ../../tools/cleaning-tools.sh

rm -rvf ./output/*.vtk
clean_precice_logs .
clean_case_logs .
MakisH marked this conversation as resolved.
Show resolved Hide resolved
Empty file.
20 changes: 20 additions & 0 deletions elastic-tube-1d/fluid-fortran-module/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e -u

. ../../tools/log.sh
exec > >(tee --append "$LOGFILE") 2>&1

if [ ! -f src/precice.f90 ]; then
echo "Fetching precice.f90 (Module for Fortran bindings of preCICE)..."
curl -o src/precice.f90 https://raw.githubusercontent.com/precice/fortran-module/master/precice.f90
fi

if [ ! -d build ]; then
mkdir build
cmake -S . -B build
cmake --build build
fi

./build/FluidSolver ../precice-config.xml

close_log
182 changes: 182 additions & 0 deletions elastic-tube-1d/fluid-fortran-module/src/FluidComputeSolution.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
module FluidComputeSolution
implicit none
integer, parameter :: dp = kind(1.0d0)

contains

subroutine fluid_compute_solution(velocity_old, pressure_old, &
crossSectionLength_old, crossSectionLength, t, N, kappa, tau, &
velocity, pressure, info)

real(dp), intent(in) :: velocity_old(:), pressure_old(:)
real(dp), intent(in) :: crossSectionLength_old(:), crossSectionLength(:)
real(dp), intent(in) :: t
integer, intent(in) :: N
real(dp), intent(in) :: kappa, tau
real(dp), intent(inout) :: velocity(:), pressure(:)
integer, intent(out) :: info

! Local variables
integer :: i, k
real(dp), parameter :: PI = 3.141592653589793_dp
real(dp), parameter :: e = 10000.0_dp
real(dp), parameter :: c_mk2 = e / 2.0_dp * sqrt(PI)
real(dp), parameter :: u0 = 10.0_dp, ampl = 3.0_dp, frequency = 10.0_dp, &
t_shift = 0.0_dp
real(dp), parameter :: tolerance = 1.0e-15_dp
integer, parameter :: max_iterations = 50

real(dp) :: alpha, L, dx, velocity_in, tmp2, norm_1, norm_2, norm

! LAPACK Variables
integer :: nlhs, nrhs
real(dp), allocatable :: Res(:)
real(dp), allocatable :: LHS(:, :)
integer, allocatable :: ipiv(:)

nlhs = 2*N + 2
nrhs = 1

! Allocate arrays
allocate (Res(2*N + 2))
allocate (LHS(2*N + 2, 2*N + 2))
allocate (ipiv(nlhs))

velocity = velocity_old
pressure = pressure_old

! Stabilization intensity
alpha = 0.0 !(N * kappa * tau) / (N * tau + 1);
L = 10.0
dx = L/kappa !1.0 / (N * kappa);

! Output status from dgesv (0 = success, < 0 = invalid argument, > 0 = singular matrix)
info = 0

! Nonlinear solver loop
do k = 1, max_iterations
! Initialize residual vector
Res = 0.0

! Compute residuals
do i = 2, N ! Adjusted for 1-based indexing
! Momentum
Res(i) = (velocity_old(i)*crossSectionLength_old(i) - velocity(i)*crossSectionLength(i))*dx/tau
Res(i) = Res(i) + 0.25*(-crossSectionLength(i + 1)*velocity(i)*velocity(i + 1) - &
crossSectionLength(i)*velocity(i)*velocity(i + 1))
Res(i) = Res(i) + 0.25*(-crossSectionLength(i + 1)*velocity(i)**2 - &
crossSectionLength(i)*velocity(i)**2 + &
crossSectionLength(i)*velocity(i - 1)*velocity(i) + &
crossSectionLength(i - 1)*velocity(i - 1)*velocity(i))
Res(i) = Res(i) + 0.25*(crossSectionLength(i - 1)*velocity(i - 1)**2 + &
crossSectionLength(i)*velocity(i - 1)**2)
Res(i) = Res(i) + 0.25*(crossSectionLength(i - 1)*pressure(i - 1) + &
crossSectionLength(i)*pressure(i - 1) - &
crossSectionLength(i - 1)*pressure(i) + &
crossSectionLength(i + 1)*pressure(i) - &
crossSectionLength(i)*pressure(i + 1) - &
crossSectionLength(i + 1)*pressure(i + 1))

! Continuity
Res(i + N + 1) = (crossSectionLength_old(i) - crossSectionLength(i))*dx/tau
Res(i + N + 1) = Res(i + N + 1) + 0.25*(crossSectionLength(i - 1)*velocity(i - 1) + &
crossSectionLength(i)*velocity(i - 1) + &
crossSectionLength(i - 1)*velocity(i) - &
crossSectionLength(i + 1)*velocity(i) - &
crossSectionLength(i)*velocity(i + 1) - &
crossSectionLength(i + 1)*velocity(i + 1))
Res(i + N + 1) = Res(i + N + 1) + alpha*(pressure(i - 1) - 2.0*pressure(i) + pressure(i + 1))
end do

! Boundary conditions
velocity_in = u0 + ampl*sin(frequency*(t + t_shift)*PI)
Res(1) = velocity_in - velocity(1)
! Pressure Inlet is linearly interpolated
Res(N + 2) = -pressure(1) + 2.0*pressure(2) - pressure(3)
! Velocity Outlet is linearly interpolated
Res(N + 1) = -velocity(N + 1) + 2.0*velocity(N) - velocity(N - 1)
! Pressure Outlet is "non-reflecting"
tmp2 = sqrt(c_mk2 - pressure_old(N + 1)/2.0) - &
(velocity(N + 1) - velocity_old(N + 1))/4.0
Res(2*N + 2) = -pressure(N + 1) + 2.0*(c_mk2 - tmp2**2)

! Compute residual norm
norm_1 = sqrt(sum(Res**2))
norm_2 = sqrt(sum(pressure**2) + sum(velocity**2))
norm = norm_1/norm_2

if ((norm < tolerance .and. k > 1) .or. k > max_iterations) then
exit
end if

! Initialize the LHS matrix
LHS = 0.0

! Populate LHS matrix
do i = 2, N
! Momentum, Velocity
LHS(i, i - 1) = LHS(i, i - 1) + 0.25*(-2.0*crossSectionLength(i - 1)*velocity(i - 1) - &
2.0*crossSectionLength(i)*velocity(i - 1) - &
crossSectionLength(i)*velocity(i) - crossSectionLength(i - 1)*velocity(i))
LHS(i, i) = LHS(i, i) + crossSectionLength(i)*dx/tau + &
0.25*(crossSectionLength(i + 1)*velocity(i + 1) + &
crossSectionLength(i)*velocity(i + 1) + &
2.0*crossSectionLength(i + 1)*velocity(i) + &
2.0*crossSectionLength(i)*velocity(i) - &
crossSectionLength(i)*velocity(i - 1) - crossSectionLength(i - 1)*velocity(i - 1))
LHS(i, i + 1) = LHS(i, i + 1) + 0.25*(crossSectionLength(i + 1)*velocity(i) + &
crossSectionLength(i)*velocity(i))

! Momentum, Pressure
LHS(i, N + 1 + i - 1) = LHS(i, N + 1 + i - 1) - 0.25*crossSectionLength(i - 1) - &
0.25*crossSectionLength(i)
LHS(i, N + 1 + i) = LHS(i, N + 1 + i) + 0.25*crossSectionLength(i - 1) - &
0.25*crossSectionLength(i + 1)
LHS(i, N + 1 + i + 1) = LHS(i, N + 1 + i + 1) + 0.25*crossSectionLength(i) + &
0.25*crossSectionLength(i + 1)
! Continuity, Velocity
LHS(i + N + 1, i - 1) = LHS(i + N + 1, i - 1) - 0.25*crossSectionLength(i - 1) - &
0.25*crossSectionLength(i)
LHS(i + N + 1, i) = LHS(i + N + 1, i) - 0.25*crossSectionLength(i - 1) + &
0.25*crossSectionLength(i + 1)
LHS(i + N + 1, i + 1) = LHS(i + N + 1, i + 1) + 0.25*crossSectionLength(i) + &
0.25*crossSectionLength(i + 1)

! Continuity, Pressure
LHS(i + N + 1, N + 1 + i - 1) = LHS(i + N + 1, N + 1 + i - 1) - alpha
LHS(i + N + 1, N + 1 + i) = LHS(i + N + 1, N + 1 + i) + 2.0*alpha
LHS(i + N + 1, N + 1 + i + 1) = LHS(i + N + 1, N + 1 + i + 1) - alpha
end do

! Boundary conditions in LHS
! Velocity Inlet is prescribed
LHS(1, 1) = 1.0
! Pressure Inlet is linearly interpolated
LHS(N + 2, N + 2) = 1.0
LHS(N + 2, N + 3) = -2.0
LHS(N + 2, N + 4) = 1.0
! Velocity Outlet is linearly interpolated
LHS(N + 1, N + 1) = 1.0
LHS(N + 1, N) = -2.0
LHS(N + 1, N - 1) = 1.0
! Pressure Outlet is Non-Reflecting
LHS(2*N + 2, 2*N + 2) = 1.0
LHS(2*N + 2, N + 1) = -(sqrt(c_mk2 - pressure_old(N + 1)/2.0) - (velocity(N + 1) - velocity_old(N + 1))/4.0)

call dgesv(nlhs, nrhs, LHS, nlhs, ipiv, Res, nlhs, info)
if (info /= 0) then
write(*, *) "Linear Solver not converged!, Info: ", info
end if

! Update velocity and pressure
do i = 1, N + 1
velocity(i) = velocity(i) + Res(i)
pressure(i) = pressure(i) + Res(i + N + 1)
end do
end do

! Deallocate arrays
deallocate(Res, LHS, ipiv)

end subroutine fluid_compute_solution
end module FluidComputeSolution
Loading
Loading