From 3cb99e64ba218ae70ae3d0750cdd28965c676b18 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Sun, 5 Jan 2025 09:27:22 +0100 Subject: [PATCH 01/37] Create initial folders and files --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 0 elastic-tube-1d/fluid-fortran/clean.sh | 0 elastic-tube-1d/fluid-fortran/run.sh | 0 elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 | 0 elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 | 0 elastic-tube-1d/fluid-fortran/src/utilities.f90 | 0 elastic-tube-1d/solid-fortran/CMakeLists.txt | 0 elastic-tube-1d/solid-fortran/clean.sh | 0 elastic-tube-1d/solid-fortran/run.sh | 0 elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 | 0 elastic-tube-1d/solid-fortran/src/SolidSolver.f90 | 0 11 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 elastic-tube-1d/fluid-fortran/CMakeLists.txt create mode 100644 elastic-tube-1d/fluid-fortran/clean.sh create mode 100644 elastic-tube-1d/fluid-fortran/run.sh create mode 100644 elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 create mode 100644 elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 create mode 100644 elastic-tube-1d/fluid-fortran/src/utilities.f90 create mode 100644 elastic-tube-1d/solid-fortran/CMakeLists.txt create mode 100644 elastic-tube-1d/solid-fortran/clean.sh create mode 100644 elastic-tube-1d/solid-fortran/run.sh create mode 100644 elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 create mode 100644 elastic-tube-1d/solid-fortran/src/SolidSolver.f90 diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran/clean.sh b/elastic-tube-1d/fluid-fortran/clean.sh new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran/run.sh b/elastic-tube-1d/fluid-fortran/run.sh new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/solid-fortran/clean.sh b/elastic-tube-1d/solid-fortran/clean.sh new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/solid-fortran/run.sh b/elastic-tube-1d/solid-fortran/run.sh new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 new file mode 100644 index 000000000..e69de29bb From f44dbf86cfca3ff88a733009be8aa4bbff564cf4 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Sun, 5 Jan 2025 10:45:28 +0100 Subject: [PATCH 02/37] Add scripts, test with minimal solvers --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 31 ++++++++++++ elastic-tube-1d/fluid-fortran/clean.sh | 5 ++ elastic-tube-1d/fluid-fortran/run.sh | 12 +++++ .../fluid-fortran/src/FluidSolver.f90 | 48 +++++++++++++++++++ elastic-tube-1d/solid-fortran/CMakeLists.txt | 21 ++++++++ elastic-tube-1d/solid-fortran/clean.sh | 4 ++ elastic-tube-1d/solid-fortran/run.sh | 12 +++++ .../solid-fortran/src/SolidSolver.f90 | 42 ++++++++++++++++ 8 files changed, 175 insertions(+) mode change 100644 => 100755 elastic-tube-1d/fluid-fortran/clean.sh mode change 100644 => 100755 elastic-tube-1d/fluid-fortran/run.sh mode change 100644 => 100755 elastic-tube-1d/solid-fortran/clean.sh mode change 100644 => 100755 elastic-tube-1d/solid-fortran/run.sh diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index e69de29bb..a13db4621 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10) +project(ElasticTube_Fluid_Fortran LANGUAGES C Fortran DESCRIPTION "preCICE Fortran Fluid Solver") + +# If no build type is specified, default to Debug: +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}") + +# Find preCICE library with Fortran bindings +find_package(precice 3 REQUIRED CONFIG) + +# Find LAPACK for linear solves +# Uncomment if LAPACK is needed +# find_package(LAPACK REQUIRED) + +# Add the executable +add_executable(FluidSolver +# Uncomment these if additional source files are required +# src/FluidComputeSolution.f90 +# src/utilities.f90 + src/FluidSolver.f90 +) + +# Link preCICE library +target_link_libraries(FluidSolver PRIVATE precice::precice) + +# Additional linking for LAPACK if needed +# target_link_libraries(FluidSolver PRIVATE LAPACK::LAPACK) diff --git a/elastic-tube-1d/fluid-fortran/clean.sh b/elastic-tube-1d/fluid-fortran/clean.sh old mode 100644 new mode 100755 index e69de29bb..d29b40321 --- a/elastic-tube-1d/fluid-fortran/clean.sh +++ b/elastic-tube-1d/fluid-fortran/clean.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e -u + +rm -rf build || true +rm -rf output || true diff --git a/elastic-tube-1d/fluid-fortran/run.sh b/elastic-tube-1d/fluid-fortran/run.sh old mode 100644 new mode 100755 index e69de29bb..b0c7199f8 --- a/elastic-tube-1d/fluid-fortran/run.sh +++ b/elastic-tube-1d/fluid-fortran/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e -u + +if [ ! -d build ]; then + mkdir build + cd build + cmake .. + cmake --build . + cd .. +fi + +./build/FluidSolver ../precice-config.xml diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index e69de29bb..7983ddf69 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -0,0 +1,48 @@ +program FluidSolver + implicit none + + character(len=512) :: configFileName + character(len=*), parameter :: solverName = 'Fluid' + character(len=*), parameter :: meshName = 'Fluid-Nodes-Mesh' + + integer :: rank, commsize, ongoing, bool + double precision :: dt + + ! We “declare” the preCICE native Fortran routines as external: + external :: precicef_create + external :: precicef_initialize + external :: precicef_is_coupling_ongoing + external :: precicef_get_max_time_step_size + external :: precicef_advance + external :: precicef_finalize + + write(*,*) "Starting minimal Fluid Solver..." + + if (command_argument_count() /= 1) then + write(*,*) "Usage: FluidSolver " + stop + endif + call get_command_argument(1, configFileName) + + rank = 0 + commsize = 1 + + ! create participant + call precicef_create(solverName, configFileName, rank, commsize) + + ! initialize + call precicef_initialize() + + ! minimal coupling loop + call precicef_is_coupling_ongoing(ongoing) + do while(ongoing /= 0) + call precicef_get_max_time_step_size(dt) + call precicef_advance(dt) + call precicef_is_coupling_ongoing(ongoing) + end do + + ! finalize + call precicef_finalize() + + write(*,*) "Exit FluidSolver" +end program FluidSolver diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt index e69de29bb..ba56c7c3d 100644 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/solid-fortran/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.10) +project(ElasticTube_Solid_Fortran LANGUAGES C Fortran DESCRIPTION "preCICE Fortran Solid Solver") + + +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}") + + +find_package(precice REQUIRED CONFIG) + + +add_executable(SolidSolver + src/SolidSolver.f90 +) + + +target_link_libraries(SolidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/solid-fortran/clean.sh b/elastic-tube-1d/solid-fortran/clean.sh old mode 100644 new mode 100755 index e69de29bb..bec0a3f61 --- a/elastic-tube-1d/solid-fortran/clean.sh +++ b/elastic-tube-1d/solid-fortran/clean.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e -u + +rm -rf build || true diff --git a/elastic-tube-1d/solid-fortran/run.sh b/elastic-tube-1d/solid-fortran/run.sh old mode 100644 new mode 100755 index e69de29bb..e362cf904 --- a/elastic-tube-1d/solid-fortran/run.sh +++ b/elastic-tube-1d/solid-fortran/run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e -u + +if [ ! -d build ]; then + mkdir build + cd build + cmake .. + cmake --build . + cd .. +fi + +./build/SolidSolver ../precice-config.xml diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index e69de29bb..8f4d4f23f 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -0,0 +1,42 @@ +program SolidSolver + implicit none + + character(len=512) :: configFileName + character(len=*), parameter :: solverName = 'Solid' + + integer :: rank, commsize, ongoing + double precision :: dt + + external :: precicef_create + external :: precicef_initialize + external :: precicef_is_coupling_ongoing + external :: precicef_get_max_time_step_size + external :: precicef_advance + external :: precicef_finalize + + write(*,*) "Starting minimal Solid Solver..." + + if(command_argument_count() /= 1) then + write(*,*) "Usage: SolidSolver " + stop + end if + call get_command_argument(1, configFileName) + + rank = 0 + commsize = 1 + + call precicef_create(solverName, configFileName, rank, commsize) + + call precicef_initialize() + + call precicef_is_coupling_ongoing(ongoing) + do while(ongoing /= 0) + call precicef_get_max_time_step_size(dt) + call precicef_advance(dt) + call precicef_is_coupling_ongoing(ongoing) + end do + + call precicef_finalize() + + write(*,*) "Exit SolidSolver" +end program SolidSolver From b8bcdc5f3674effeac775b43153604ca8bb4b5c9 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 16:47:28 +0100 Subject: [PATCH 03/37] Implementation wip --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 94 +++++-- elastic-tube-1d/fluid-fortran/clean.sh | 9 +- elastic-tube-1d/fluid-fortran/run.sh | 11 +- .../src/FluidComputeSolution.f90 | 203 +++++++++++++++ .../fluid-fortran/src/FluidSolver.f90 | 231 +++++++++++++++--- elastic-tube-1d/solid-fortran/CMakeLists.txt | 8 +- elastic-tube-1d/solid-fortran/clean.sh | 5 +- elastic-tube-1d/solid-fortran/run.sh | 5 + .../src/SolidComputeSolution.f90 | 28 +++ .../solid-fortran/src/SolidSolver.f90 | 135 +++++++--- 10 files changed, 638 insertions(+), 91 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index a13db4621..e14fecfc4 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.10) -project(ElasticTube_Fluid_Fortran LANGUAGES C Fortran DESCRIPTION "preCICE Fortran Fluid Solver") +project(ElasticTube LANGUAGES Fortran C) -# If no build type is specified, default to Debug: +# Set default build type to Debug if not specified 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 @@ -9,23 +9,89 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}") -# Find preCICE library with Fortran bindings +# Find required packages find_package(precice 3 REQUIRED CONFIG) +find_package(LAPACK REQUIRED) -# Find LAPACK for linear solves -# Uncomment if LAPACK is needed -# find_package(LAPACK REQUIRED) - -# Add the executable +# Add executable add_executable(FluidSolver -# Uncomment these if additional source files are required -# src/FluidComputeSolution.f90 -# src/utilities.f90 + src/FluidComputeSolution.f90 + src/utilities.f90 src/FluidSolver.f90 ) -# Link preCICE library +# Link libraries target_link_libraries(FluidSolver PRIVATE precice::precice) +target_link_libraries(FluidSolver PRIVATE ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS}) + +# ============================ +# Add Compiler Flags for Debugging +# ============================ + +# Define a function to add compiler flags based on compiler ID +function(add_fortran_debug_flags target) + if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + # GNU Fortran (gfortran) specific flags + target_compile_options(${target} PRIVATE + $<$:-fbounds-check> + $<$:-fbacktrace> + $<$:-fcheck=all> + $<$:-g> + $<$:-Wall> + $<$:-Wextra> + ) + elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") + # Intel Fortran (ifort) specific flags + target_compile_options(${target} PRIVATE + $<$:-check bounds> + $<$:-g> + $<$:-warn all> + ) + elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI" OR + CMAKE_Fortran_COMPILER_ID MATCHES "NAG") + # PGI, NAG, and other Fortran compilers + target_compile_options(${target} PRIVATE + $<$:-C> + $<$:-g> + $<$:-Wall> + ) + else() + message(WARNING "Compiler ${CMAKE_Fortran_COMPILER_ID} not explicitly supported for debug flags.") + # Generic debug flags + target_compile_options(${target} PRIVATE + $<$:-g> + $<$:-Wall> + ) + endif() +endfunction() + +# Apply the debug flags to FluidSolver +add_fortran_debug_flags(FluidSolver) + +# ============================ +# Optionally, Add Linker Flags (if needed) +# ============================ + +# For example, to link LAPACK, you might need to specify additional flags +# However, typically, find_package(LAPACK) handles this +# If you have specific linker flags, you can add them as follows: +# target_link_libraries(FluidSolver PRIVATE ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS}) + +# ============================ +# Enable Fortran Module Generation (Optional) +# ============================ + +# If you have modules that need to be visible to other targets, set the appropriate properties +# For example: +# set_target_properties(FluidSolver PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) + +# ============================ +# Set CMake Policies (Optional) +# ============================ + +# To ensure compatibility with newer CMake versions +# cmake_policy(SET CMP0074 NEW) -# Additional linking for LAPACK if needed -# target_link_libraries(FluidSolver PRIVATE LAPACK::LAPACK) +# ============================ +# End of CMakeLists.txt +# ============================ diff --git a/elastic-tube-1d/fluid-fortran/clean.sh b/elastic-tube-1d/fluid-fortran/clean.sh index d29b40321..8d5d37784 100755 --- a/elastic-tube-1d/fluid-fortran/clean.sh +++ b/elastic-tube-1d/fluid-fortran/clean.sh @@ -1,5 +1,8 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -e -u -rm -rf build || true -rm -rf output || true +. ../../tools/cleaning-tools.sh + +rm -rvf ./output/*.vtk +clean_precice_logs . +clean_case_logs . diff --git a/elastic-tube-1d/fluid-fortran/run.sh b/elastic-tube-1d/fluid-fortran/run.sh index b0c7199f8..2a0de7786 100755 --- a/elastic-tube-1d/fluid-fortran/run.sh +++ b/elastic-tube-1d/fluid-fortran/run.sh @@ -1,12 +1,15 @@ #!/usr/bin/env bash set -e -u +. ../../tools/log.sh +exec > >(tee --append "$LOGFILE") 2>&1 + if [ ! -d build ]; then mkdir build - cd build - cmake .. - cmake --build . - cd .. + cmake -S . -B build + cmake --build build fi ./build/FluidSolver ../precice-config.xml + +close_log diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index e69de29bb..c2fd73996 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -0,0 +1,203 @@ +module FluidComputeSolution + use, intrinsic :: iso_c_binding, only: c_double, c_int + implicit none + private + public :: fluidComputeSolutionSerial + +contains + + subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & + crossSectionLength_old, crossSectionLength, t, N, kappa, tau, & + velocity, pressure, info) + implicit none + + ! Function arguments + real(8), intent(in) :: velocity_old(:), pressure_old(:) + real(8), intent(in) :: crossSectionLength_old(:), crossSectionLength(:) + real(8), intent(in) :: t + integer, intent(in) :: N + real(8), intent(in) :: kappa, tau + real(8), intent(inout) :: velocity(:), pressure(:) + integer, intent(out) :: info + + ! Local variables + integer :: i, k, j + real(8), parameter :: PI = 3.141592653589793 + real(8), parameter :: E = 10000.0 + real(8), parameter :: c_mk2 = E / 2.0 * sqrt(PI) + real(8), parameter :: u0 = 10.0, ampl = 3.0, frequency = 10.0, & + t_shift = 0.0 + real(8), parameter :: tolerance = 1.0e-15 + integer, parameter :: max_iterations = 50 + + real(8) :: alpha, L, dx, velocity_in, tmp2, norm_1, norm_2, norm + + ! LAPACK Variables + integer :: nlhs, nrhs + real(8), allocatable :: Res(:) + real(8), 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); + + ! Initialize result variable + info = 0 + print *, "CrossSectionLength:" + write(*, '(10F12.6)') crossSectionLength + print *, "Alpha:", alpha + + ! 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) + + + ! Solve Ax = b using LAPACK + ! print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" + ! do i = 1, size(LHS, 1) + ! write(*, '(10F12.6)') (LHS(i, j), j = 1, size(LHS, 2)) + ! end do + ! print *, "Diagonal elements of LHS:" + ! do i = 1, size(LHS, 1) + ! print *, "LHS(", i, ",", i, ") =", LHS(i, i) + ! end do + print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" + do i = 1, size(LHS, 1) + write(*, '(10F8.2)') (LHS(i, j), j = 1, size(LHS, 2)) + end do + + call dgesv(nlhs, nrhs, LHS, nlhs, ipiv, Res, nlhs, info) + if (info /= 0) then + return + 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 fluidComputeSolutionSerial +end module FluidComputeSolution \ No newline at end of file diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index 7983ddf69..e8c8c2768 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -1,48 +1,211 @@ -program FluidSolver - implicit none +PROGRAM FluidSolver + USE FluidComputeSolution, ONLY: fluidComputeSolutionSerial + USE Utilities_mod, ONLY: write_vtk + IMPLICIT NONE - character(len=512) :: configFileName - character(len=*), parameter :: solverName = 'Fluid' - character(len=*), parameter :: meshName = 'Fluid-Nodes-Mesh' + ! Variable Declarations + CHARACTER(LEN=512) :: configFileName + CHARACTER(LEN=50) :: solverName + CHARACTER(LEN=50) :: meshName, pressureName, crossSectionLengthName + CHARACTER(LEN=256) :: outputFilePrefix + INTEGER :: rank, commsize, ongoing, dimensions, bool + INTEGER :: domainSize, chunkLength + INTEGER :: i, j, info + DOUBLE PRECISION :: dt, t, cellwidth + DOUBLE PRECISION, ALLOCATABLE :: pressure(:), pressure_old(:) + DOUBLE PRECISION, ALLOCATABLE :: crossSectionLength(:), crossSectionLength_old(:) + DOUBLE PRECISION, ALLOCATABLE :: velocity(:), velocity_old(:) + INTEGER, ALLOCATABLE :: vertexIDs(:) + INTEGER :: out_counter + DOUBLE PRECISION, PARAMETER :: PI = 3.141592653589793d0 + DOUBLE PRECISION :: kappa, L + DOUBLE PRECISION :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 + DOUBLE PRECISION, ALLOCATABLE :: grid(:) - integer :: rank, commsize, ongoing, bool - double precision :: dt + ! Start of Program + WRITE (*,*) 'Fluid: Starting Fortran solver...' - ! We “declare” the preCICE native Fortran routines as external: - external :: precicef_create - external :: precicef_initialize - external :: precicef_is_coupling_ongoing - external :: precicef_get_max_time_step_size - external :: precicef_advance - external :: precicef_finalize + ! Command-Line Argument Parsing + IF (COMMAND_ARGUMENT_COUNT() /= 1) THEN + WRITE (*,*) "" + WRITE (*,*) "Fluid: Usage: FluidSolver " + STOP -1 + END IF - write(*,*) "Starting minimal Fluid Solver..." + CALL getarg(1, configFileName) - if (command_argument_count() /= 1) then - write(*,*) "Usage: FluidSolver " - stop - endif - call get_command_argument(1, configFileName) + solverName = 'Fluid' + outputFilePrefix = './output/out_fluid' + ! Initialize preCICE Interface rank = 0 commsize = 1 + CALL precicef_create(solverName, configFileName, rank, commsize) + WRITE (*,*) "preCICE configured..." - ! create participant - call precicef_create(solverName, configFileName, rank, commsize) + ! Define Mesh and Data Names + meshName = "Fluid-Nodes-Mesh" + pressureName = "Pressure" + crossSectionLengthName = "CrossSectionLength" - ! initialize - call precicef_initialize() + domainSize = 4 + chunkLength = domainSize + 1 + kappa = 100.0d0 + L = 10.0d0 - ! minimal coupling loop - call precicef_is_coupling_ongoing(ongoing) - do while(ongoing /= 0) - call precicef_get_max_time_step_size(dt) - call precicef_advance(dt) - call precicef_is_coupling_ongoing(ongoing) + ! Get Mesh Dimensions from preCICE + CALL precicef_get_mesh_dimensions(meshName, dimensions) + + ! Allocate Arrays + ALLOCATE(vertexIDs(chunkLength)) + ALLOCATE(pressure(chunkLength)) + ALLOCATE(pressure_old(chunkLength)) + ALLOCATE(crossSectionLength(chunkLength)) + ALLOCATE(crossSectionLength_old(chunkLength)) + ALLOCATE(velocity(chunkLength)) + ALLOCATE(velocity_old(chunkLength)) + ALLOCATE(grid(dimensions * chunkLength)) + + ! Initialize vertexIDs (0-based IDs) + DO i = 1, chunkLength + vertexIDs(i) = i - 1 + END DO + + ! Initialize Physical Parameters + r0 = 1.0d0 / SQRT(PI) + a0 = r0**2 * PI + u0 = 10.0d0 + ampl = 3.0d0 + frequency = 10.0d0 + t_shift = 0.0d0 + p0 = 0.0d0 + vel_in_0 = u0 + ampl * SIN(frequency * (t_shift) * PI) + + ! Initialize Data Arrays + pressure = p0 + pressure_old = pressure + crossSectionLength = a0 + crossSectionLength_old = crossSectionLength + velocity = vel_in_0 + velocity_old = velocity + + ! Initialize Grid Coordinates + cellwidth = L / REAL(domainSize, KIND=8) + DO i = 1, chunkLength + DO j = 1, dimensions + IF (j == 1) THEN + grid((i - 1) * dimensions + j) = REAL(i - 1, KIND=8) * cellwidth + ELSE + grid((i - 1) * dimensions + j) = 0.0d0 + END IF + END DO + END DO + + ! Print the grid + print *, "Grid values:" + do i = 1, chunkLength + do j = 1, dimensions + print "(A,I4,A,F6.2)", "grid(", (i - 1) * dimensions + j, ") = ", grid((i - 1) * dimensions + j) + end do end do - ! finalize - call precicef_finalize() - write(*,*) "Exit FluidSolver" -end program FluidSolver + CALL precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + + ! Check if Initial Data is Required and Write if Necessary + CALL precicef_requires_initial_data(bool) + IF (bool == 1) THEN + WRITE (*,*) 'Fluid: Writing initial data' + CALL precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) + END IF + + ! Initialize Simulation Time + t = 0.0d0 + WRITE (*,*) "Initialize preCICE..." + CALL precicef_initialize() + + ! Read Initial Cross-Section Length + CALL precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength) + + ! Copy Current Cross-Section Length to Old Array + crossSectionLength_old = crossSectionLength + + ! initialize such that mass conservation is fulfilled + DO i = 1, chunkLength + velocity_old(i) = vel_in_0 * crossSectionLength_old(1) / crossSectionLength_old(i) + END DO + + ! Initialize Output Counter + out_counter = 0 + + ! Print all arrays with 2 decimal places + print *, "Index | Pressure | Pressure_Old | CrossSection | CrossSection_Old | Velocity | Velocity_Old" + do i = 1, chunkLength + print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & + i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & + crossSectionLength_old(i), velocity(i), velocity_old(i) + end do + + ! Main Coupling Loop + CALL precicef_is_coupling_ongoing(ongoing) + DO WHILE (ongoing /= 0) + ! Check if Writing a Checkpoint is Required + CALL precicef_requires_writing_checkpoint(bool) + IF (bool == 1) THEN + WRITE (*,*) 'Fluid: Writing iteration checkpoint' + END IF + + ! Get Maximum Time Step Size from preCICE + CALL precicef_get_max_time_step_size(dt) + + ! Compute Fluid Solution + CALL fluidComputeSolutionSerial( & + velocity_old, pressure_old, crossSectionLength_old, & + crossSectionLength, & + t + dt, & ! used for inlet velocity + domainSize, & + kappa, & + dt, & ! tau + velocity, pressure, & ! resulting velocity pressure + info) + + + CALL precicef_advance(dt) + + CALL precicef_get_max_time_step_size(dt) + + CALL precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength) + + CALL precicef_requires_reading_checkpoint(bool) + IF (bool == 1) THEN + WRITE (*,*) 'Fluid: Reading iteration checkpoint' + ELSE + t = t + dt + + CALL write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) + crossSectionLength_old = crossSectionLength + pressure_old = pressure + velocity_old = velocity + + out_counter = out_counter + 1 + END IF + + ! Check if Coupling is Still Ongoing + CALL precicef_is_coupling_ongoing(ongoing) + END DO + + ! Finalize preCICE Interface + CALL precicef_finalize() + WRITE (*,*) 'Exiting FluidSolver' + + ! Deallocate Dynamically Allocated Arrays + DEALLOCATE(pressure) + DEALLOCATE(pressure_old) + DEALLOCATE(crossSectionLength) + DEALLOCATE(crossSectionLength_old) + DEALLOCATE(velocity) + DEALLOCATE(velocity_old) + DEALLOCATE(grid) + DEALLOCATE(vertexIDs) + +END PROGRAM FluidSolver diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt index ba56c7c3d..f063b730a 100644 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/solid-fortran/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(ElasticTube_Solid_Fortran LANGUAGES C Fortran DESCRIPTION "preCICE Fortran Solid Solver") +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) @@ -9,13 +9,11 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}") - -find_package(precice REQUIRED CONFIG) - +find_package(precice 3 REQUIRED CONFIG) add_executable(SolidSolver + src/SolidComputeSolution.f90 src/SolidSolver.f90 ) - target_link_libraries(SolidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/solid-fortran/clean.sh b/elastic-tube-1d/solid-fortran/clean.sh index bec0a3f61..ae7a54924 100755 --- a/elastic-tube-1d/solid-fortran/clean.sh +++ b/elastic-tube-1d/solid-fortran/clean.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash set -e -u -rm -rf build || true +. ../../tools/cleaning-tools.sh + +clean_precice_logs . +clean_case_logs . diff --git a/elastic-tube-1d/solid-fortran/run.sh b/elastic-tube-1d/solid-fortran/run.sh index e362cf904..5263549b9 100755 --- a/elastic-tube-1d/solid-fortran/run.sh +++ b/elastic-tube-1d/solid-fortran/run.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash set -e -u +. ../../tools/log.sh || true +exec > >(tee --append "$LOGFILE") 2>&1 || true + if [ ! -d build ]; then mkdir build cd build @@ -10,3 +13,5 @@ if [ ! -d build ]; then fi ./build/SolidSolver ../precice-config.xml + +close_log diff --git a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 index e69de29bb..a9540b6dc 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 @@ -0,0 +1,28 @@ +module SolidComputeSolution_mod + implicit none +contains + + subroutine SolidComputeSolution(chunkLength, pressure, crossSectionLength) + integer, intent(in) :: chunkLength + real(8), intent(in) :: pressure(1:chunkLength) + real(8), intent(inout) :: crossSectionLength(1:chunkLength) + + real(8) :: PI, E, r0, c_mk, c_mk2 + real(8) :: pressure0 + integer :: i + + PI = 3.14159265359d0 + E = 10000.d0 + r0 = 1.d0 / sqrt(PI) + c_mk = sqrt(E / (2.d0*r0)) + c_mk2 = c_mk * c_mk + pressure0 = 0.d0 + + do i=1, chunkLength + crossSectionLength(i) = ( (pressure0 - 2.d0 * c_mk2)**2 ) / & + ( (pressure(i) - 2.d0 * c_mk2)**2 ) + end do + + end subroutine SolidComputeSolution + +end module SolidComputeSolution_mod diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 8f4d4f23f..9db03ae13 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -1,42 +1,117 @@ -program SolidSolver - implicit none +PROGRAM SolidSolver + USE SolidComputeSolution_mod, ONLY: SolidComputeSolution + IMPLICIT NONE - character(len=512) :: configFileName - character(len=*), parameter :: solverName = 'Solid' + INTEGER, PARAMETER :: DP = KIND(1.0D0) - integer :: rank, commsize, ongoing - double precision :: dt + CHARACTER(LEN=512) :: configFileName + CHARACTER(LEN=256) :: solverName + CHARACTER(LEN=256) :: meshName, crossSectionLengthName, pressureName + INTEGER :: rank, commsize, ongoing, dimensions, bool + INTEGER :: domainSize, chunkLength + INTEGER :: i, j + INTEGER, ALLOCATABLE :: vertexIDs(:) + DOUBLE PRECISION, ALLOCATABLE :: pressure(:), crossSectionLength(:) + DOUBLE PRECISION, ALLOCATABLE :: grid(:) + DOUBLE PRECISION :: dt, tubeLength, dx - external :: precicef_create - external :: precicef_initialize - external :: precicef_is_coupling_ongoing - external :: precicef_get_max_time_step_size - external :: precicef_advance - external :: precicef_finalize + WRITE (*,*) 'Starting Solid Solver...' - write(*,*) "Starting minimal Solid Solver..." + IF (COMMAND_ARGUMENT_COUNT() /= 1) THEN + WRITE (*,*) 'Solid: Usage: SolidSolver ' + WRITE (*,*) '' + STOP -1 + END IF - if(command_argument_count() /= 1) then - write(*,*) "Usage: SolidSolver " - stop - end if - call get_command_argument(1, configFileName) + CALL get_command_argument(1, configFileName) - rank = 0 + domainSize = 4 + chunkLength = domainSize + 1 + tubeLength = 10.0D0 + + WRITE (*,*) 'N: ', domainSize + WRITE (*,*) 'inputs: ', COMMAND_ARGUMENT_COUNT() + + solverName = 'Solid' + meshName = 'Solid-Nodes-Mesh' + crossSectionLengthName = 'CrossSectionLength' + pressureName = 'Pressure' + + rank = 0 commsize = 1 + CALL precicef_create(solverName, configFileName, rank, commsize) + WRITE (*,*) 'preCICE configured...' + + CALL precicef_get_mesh_dimensions(meshName, dimensions) + + ! Allocate Arrays + ALLOCATE(pressure(chunkLength)) + ALLOCATE(crossSectionLength(chunkLength)) + ALLOCATE(grid(dimensions * chunkLength)) + ALLOCATE(vertexIDs(chunkLength)) - call precicef_create(solverName, configFileName, rank, commsize) - - call precicef_initialize() + pressure = 0.0D0 + crossSectionLength = 1.0D0 + dx = tubeLength / domainSize + DO i = 1, chunkLength + grid((i - 1) * dimensions + 1) = dx * REAL(i - 1, DP) ! x-coordinate + grid((i - 1) * dimensions + 2) = 0.0D0 ! y-coordinate + vertexIDs(i) = i - 1 ! 0-based indexing here + END DO - call precicef_is_coupling_ongoing(ongoing) - do while(ongoing /= 0) - call precicef_get_max_time_step_size(dt) - call precicef_advance(dt) - call precicef_is_coupling_ongoing(ongoing) + ! Print the grid + print *, "Grid values:" + do i = 1, chunkLength + do j = 1, dimensions + print "(A,I4,A,F6.2)", "grid(", (i - 1) * dimensions + j, ") = ", grid((i - 1) * dimensions + j) + end do end do - call precicef_finalize() + CALL precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + + ! Check if Initial Data is Required and Write if Necessary + CALL precicef_requires_initial_data(bool) + IF (bool == 1) THEN + CALL precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + END IF + + WRITE (*,*) 'Initialize preCICE...' + CALL precicef_initialize() + + ! Coupling Loop + CALL precicef_is_coupling_ongoing(ongoing) + DO WHILE (ongoing /= 0) + + CALL precicef_requires_writing_checkpoint(bool) + IF (bool == 1) THEN + WRITE (*,*) 'Solid: Writing iteration checkpoint (not implemented).' + END IF + + CALL precicef_get_max_time_step_size(dt) + + CALL precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure) + + CALL SolidComputeSolution(chunkLength, pressure, crossSectionLength) + + CALL precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + + CALL precicef_advance(dt) + + CALL precicef_requires_reading_checkpoint(bool) + IF (bool == 1) THEN + WRITE (*,*) 'Solid: Reading iteration checkpoint (not implemented).' + END IF + + CALL precicef_is_coupling_ongoing(ongoing) + END DO + + WRITE (*,*) 'Exiting SolidSolver' + + CALL precicef_finalize() + + DEALLOCATE(pressure) + DEALLOCATE(crossSectionLength) + DEALLOCATE(grid) + DEALLOCATE(vertexIDs) - write(*,*) "Exit SolidSolver" -end program SolidSolver +END PROGRAM SolidSolver From 4420eb52ceedced8622a10302fe4aac770759c90 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 17:04:01 +0100 Subject: [PATCH 04/37] Add output folder --- elastic-tube-1d/fluid-fortran/output/.keepme | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elastic-tube-1d/fluid-fortran/output/.keepme diff --git a/elastic-tube-1d/fluid-fortran/output/.keepme b/elastic-tube-1d/fluid-fortran/output/.keepme new file mode 100644 index 000000000..e69de29bb From 4ff7dab62561a952bc413ecdea1bc0dc0a2ec2cd Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 19:02:42 +0100 Subject: [PATCH 05/37] Implement vtk writing, Add missing write_data call in fluid solver --- .../src/FluidComputeSolution.f90 | 12 +-- .../fluid-fortran/src/FluidSolver.f90 | 16 +++- .../fluid-fortran/src/utilities.f90 | 88 +++++++++++++++++++ .../solid-fortran/src/SolidSolver.f90 | 4 +- 4 files changed, 109 insertions(+), 11 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index c2fd73996..f7aab2304 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -113,6 +113,7 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & if ((norm < tolerance .and. k > 1) .or. k > max_iterations) then exit + print *, "exiting" end if ! Initialize the LHS matrix @@ -180,14 +181,15 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & ! do i = 1, size(LHS, 1) ! print *, "LHS(", i, ",", i, ") =", LHS(i, i) ! end do - print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" - do i = 1, size(LHS, 1) - write(*, '(10F8.2)') (LHS(i, j), j = 1, size(LHS, 2)) - end do + ! print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" + ! do i = 1, size(LHS, 1) + ! write(*, '(10F8.2)') (LHS(i, j), j = 1, size(LHS, 2)) + ! end do call dgesv(nlhs, nrhs, LHS, nlhs, ipiv, Res, nlhs, info) if (info /= 0) then - return + ! return + print *, "Couldnt solve" end if ! Update velocity and pressure diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index e8c8c2768..633667bb4 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -1,6 +1,6 @@ PROGRAM FluidSolver USE FluidComputeSolution, ONLY: fluidComputeSolutionSerial - USE Utilities_mod, ONLY: write_vtk + USE utilities, ONLY: write_vtk IMPLICIT NONE ! Variable Declarations @@ -116,7 +116,6 @@ PROGRAM FluidSolver CALL precicef_requires_initial_data(bool) IF (bool == 1) THEN WRITE (*,*) 'Fluid: Writing initial data' - CALL precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) END IF ! Initialize Simulation Time @@ -151,7 +150,7 @@ PROGRAM FluidSolver DO WHILE (ongoing /= 0) ! Check if Writing a Checkpoint is Required CALL precicef_requires_writing_checkpoint(bool) - IF (bool == 1) THEN + IF (bool.EQ.1) THEN WRITE (*,*) 'Fluid: Writing iteration checkpoint' END IF @@ -169,7 +168,16 @@ PROGRAM FluidSolver velocity, pressure, & ! resulting velocity pressure info) + ! Print all arrays with 2 decimal places + print *, "Index | Pressure | Pressure_Old | CrossSection | CrossSection_Old | Velocity | Velocity_Old" + do i = 1, chunkLength + print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & + i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & + crossSectionLength_old(i), velocity(i), velocity_old(i) + end do + CALL precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) + CALL precicef_advance(dt) CALL precicef_get_max_time_step_size(dt) @@ -177,7 +185,7 @@ PROGRAM FluidSolver CALL precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength) CALL precicef_requires_reading_checkpoint(bool) - IF (bool == 1) THEN + IF (bool.EQ.1) THEN WRITE (*,*) 'Fluid: Reading iteration checkpoint' ELSE t = t + dt diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 index e69de29bb..01fc489d6 100644 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ b/elastic-tube-1d/fluid-fortran/src/utilities.f90 @@ -0,0 +1,88 @@ +module utilities + implicit none + integer, parameter :: dp = kind(1.0d0) +contains + + subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & + grid, velocity, pressure, diameter) + implicit none + + ! Input Parameters + real(dp), intent(in) :: t + integer, intent(in) :: iteration + character(len=*), intent(in) :: filenamePrefix + integer, intent(in) :: nSlices + real(dp), intent(in) :: grid(:) + real(dp), intent(in) :: velocity(:) + real(dp), intent(in) :: pressure(:) + real(dp), intent(in) :: diameter(:) + + ! Local Variables + integer :: ioUnit, i, ioStatus + character(len=256) :: filename + + ! Generate Filename + write(filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration + + ! Print Status Message + print *, 'Writing timestep at t=', t, ' to ', trim(filename) + + ! Open File + open(newunit=ioUnit, file=trim(filename), status="replace", & + action="write", form="formatted", iostat=ioStatus) + if (ioStatus /= 0) then + print *, 'Error: Unable to open file ', trim(filename) + return + end if + + ! Write VTK Header + write(ioUnit, '(A)') '# vtk DataFile Version 2.0' + write(ioUnit, '(A)') '' + write(ioUnit, '(A)') 'ASCII' + write(ioUnit, '(A)') '' + write(ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' + write(ioUnit, '(A)') '' + + ! Write POINTS Section + write(ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' + write(ioUnit, '(A)') '' + + ! Export Mesh Points + do i = 1, nSlices + write(ioUnit, '(F24.16,1X,F24.16,1X,F24.16)') grid(2*(i-1)+1), grid(2*(i-1)+2), 0.0_dp + end do + write(ioUnit, '(A)') '' + + ! Write POINT_DATA Section + write(ioUnit, '(A,I0)') 'POINT_DATA ', nSlices + write(ioUnit, '(A)') '' + + ! Export Velocity Vectors + write(ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' + do i = 1, nSlices + write(ioUnit, '(F24.16,1X,F24.16,1X,F24.16)') velocity(i), 0.0_dp, 0.0_dp + end do + write(ioUnit, '(A)') '' + + ! Export Pressure Scalars + write(ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' + write(ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write(ioUnit, '(F24.16)') pressure(i) + end do + write(ioUnit, '(A)') '' + + ! Export Diameter Scalars + write(ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' + write(ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write(ioUnit, '(F24.16)') diameter(i) + end do + write(ioUnit, '(A)') '' + + ! Close File + close(ioUnit) + + end subroutine write_vtk + +end module utilities diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 9db03ae13..30d118e23 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -83,7 +83,7 @@ PROGRAM SolidSolver DO WHILE (ongoing /= 0) CALL precicef_requires_writing_checkpoint(bool) - IF (bool == 1) THEN + IF (bool.EQ.1) THEN WRITE (*,*) 'Solid: Writing iteration checkpoint (not implemented).' END IF @@ -98,7 +98,7 @@ PROGRAM SolidSolver CALL precicef_advance(dt) CALL precicef_requires_reading_checkpoint(bool) - IF (bool == 1) THEN + IF (bool.EQ.1) THEN WRITE (*,*) 'Solid: Reading iteration checkpoint (not implemented).' END IF From 57bd144b9637522060e65b194222f22835876915 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 19:10:23 +0100 Subject: [PATCH 06/37] Set domainSize to 100 --- elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 | 2 +- elastic-tube-1d/solid-fortran/src/SolidSolver.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index 633667bb4..b7f519e71 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -48,7 +48,7 @@ PROGRAM FluidSolver pressureName = "Pressure" crossSectionLengthName = "CrossSectionLength" - domainSize = 4 + domainSize = 100 chunkLength = domainSize + 1 kappa = 100.0d0 L = 10.0d0 diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 30d118e23..2a81d40e6 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -25,7 +25,7 @@ PROGRAM SolidSolver CALL get_command_argument(1, configFileName) - domainSize = 4 + domainSize = 100 chunkLength = domainSize + 1 tubeLength = 10.0D0 From 9c8e7141829301b096298f5be59e7409301bd209 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 19:38:28 +0100 Subject: [PATCH 07/37] Use ES format to output in scientific notation --- .../fluid-fortran/src/utilities.f90 | 153 ++++++++---------- 1 file changed, 67 insertions(+), 86 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 index 01fc489d6..15ca1fe9f 100644 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ b/elastic-tube-1d/fluid-fortran/src/utilities.f90 @@ -1,88 +1,69 @@ -module utilities - implicit none - integer, parameter :: dp = kind(1.0d0) -contains +MODULE Utilities + IMPLICIT NONE + INTEGER, PARAMETER :: dp = KIND(1.0D0) +CONTAINS - subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & + SUBROUTINE write_vtk(t, iteration, filenamePrefix, nSlices, & grid, velocity, pressure, diameter) - implicit none - - ! Input Parameters - real(dp), intent(in) :: t - integer, intent(in) :: iteration - character(len=*), intent(in) :: filenamePrefix - integer, intent(in) :: nSlices - real(dp), intent(in) :: grid(:) - real(dp), intent(in) :: velocity(:) - real(dp), intent(in) :: pressure(:) - real(dp), intent(in) :: diameter(:) - - ! Local Variables - integer :: ioUnit, i, ioStatus - character(len=256) :: filename - - ! Generate Filename - write(filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration - - ! Print Status Message - print *, 'Writing timestep at t=', t, ' to ', trim(filename) - - ! Open File - open(newunit=ioUnit, file=trim(filename), status="replace", & - action="write", form="formatted", iostat=ioStatus) - if (ioStatus /= 0) then - print *, 'Error: Unable to open file ', trim(filename) - return - end if - - ! Write VTK Header - write(ioUnit, '(A)') '# vtk DataFile Version 2.0' - write(ioUnit, '(A)') '' - write(ioUnit, '(A)') 'ASCII' - write(ioUnit, '(A)') '' - write(ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' - write(ioUnit, '(A)') '' - - ! Write POINTS Section - write(ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' - write(ioUnit, '(A)') '' - - ! Export Mesh Points - do i = 1, nSlices - write(ioUnit, '(F24.16,1X,F24.16,1X,F24.16)') grid(2*(i-1)+1), grid(2*(i-1)+2), 0.0_dp - end do - write(ioUnit, '(A)') '' - - ! Write POINT_DATA Section - write(ioUnit, '(A,I0)') 'POINT_DATA ', nSlices - write(ioUnit, '(A)') '' - - ! Export Velocity Vectors - write(ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' - do i = 1, nSlices - write(ioUnit, '(F24.16,1X,F24.16,1X,F24.16)') velocity(i), 0.0_dp, 0.0_dp - end do - write(ioUnit, '(A)') '' - - ! Export Pressure Scalars - write(ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' - write(ioUnit, '(A)') 'LOOKUP_TABLE default' - do i = 1, nSlices - write(ioUnit, '(F24.16)') pressure(i) - end do - write(ioUnit, '(A)') '' - - ! Export Diameter Scalars - write(ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' - write(ioUnit, '(A)') 'LOOKUP_TABLE default' - do i = 1, nSlices - write(ioUnit, '(F24.16)') diameter(i) - end do - write(ioUnit, '(A)') '' - - ! Close File - close(ioUnit) - - end subroutine write_vtk - -end module utilities + IMPLICIT NONE + + DOUBLE PRECISION, INTENT(IN) :: t + INTEGER, INTENT(IN) :: iteration + CHARACTER(LEN=*), INTENT(IN) :: filenamePrefix + INTEGER, INTENT(IN) :: nSlices + DOUBLE PRECISION, INTENT(IN) :: grid(:), velocity(:), pressure(:), diameter(:) + + INTEGER :: ioUnit, i, ioStatus + CHARACTER(LEN=256) :: filename + + WRITE(filename, '(A,"_",I0,".vtk")') TRIM(filenamePrefix), iteration + PRINT *, 'Writing timestep at t=', t, ' to ', TRIM(filename) + + OPEN(newunit=ioUnit, file=TRIM(filename), status="replace", action="write", form="formatted", iostat=ioStatus) + IF (ioStatus /= 0) THEN + PRINT *, 'Error: Unable to open file ', TRIM(filename) + RETURN + END IF + + WRITE(ioUnit, '(A)') '# vtk DataFile Version 2.0' + WRITE(ioUnit, '(A)') '' + WRITE(ioUnit, '(A)') 'ASCII' + WRITE(ioUnit, '(A)') '' + WRITE(ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' + WRITE(ioUnit, '(A)') '' + + WRITE(ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' + WRITE(ioUnit, '(A)') '' + DO i = 1, nSlices + WRITE(ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') grid(2*(i-1)+1), grid(2*(i-1)+2), 0.0D0 + END DO + WRITE(ioUnit, '(A)') '' + + WRITE(ioUnit, '(A,I0)') 'POINT_DATA ', nSlices + WRITE(ioUnit, '(A)') '' + + WRITE(ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' + DO i = 1, nSlices + WRITE(ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 + END DO + WRITE(ioUnit, '(A)') '' + + WRITE(ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' + WRITE(ioUnit, '(A)') 'LOOKUP_TABLE default' + DO i = 1, nSlices + WRITE(ioUnit, '(ES24.16)') pressure(i) + END DO + WRITE(ioUnit, '(A)') '' + + WRITE(ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' + WRITE(ioUnit, '(A)') 'LOOKUP_TABLE default' + DO i = 1, nSlices + WRITE(ioUnit, '(ES24.16)') diameter(i) + END DO + WRITE(ioUnit, '(A)') '' + + CLOSE(ioUnit) + + END SUBROUTINE write_vtk + +END MODULE Utilities From 72fdc833dcff063bfc691ed703a6c0ccdd339bb2 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 21:58:31 +0100 Subject: [PATCH 08/37] Refactor: clean code, use snake_case for subroutines, apply dp for consistent precision --- .../src/FluidComputeSolution.f90 | 215 ++++++------- .../fluid-fortran/src/FluidSolver.f90 | 292 +++++++++--------- .../fluid-fortran/src/utilities.f90 | 108 +++---- .../src/SolidComputeSolution.f90 | 36 ++- .../solid-fortran/src/SolidSolver.f90 | 176 +++++------ 5 files changed, 403 insertions(+), 424 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index f7aab2304..709f00bac 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -1,49 +1,46 @@ module FluidComputeSolution - use, intrinsic :: iso_c_binding, only: c_double, c_int implicit none - private - public :: fluidComputeSolutionSerial - + integer, parameter :: dp = kind(1.0d0) + contains - subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & - crossSectionLength_old, crossSectionLength, t, N, kappa, tau, & + subroutine fluid_compute_solution(velocity_old, pressure_old, & + crossSectionLength_old, crossSectionLength, t, n, kappa, tau, & velocity, pressure, info) - implicit none - - ! Function arguments - real(8), intent(in) :: velocity_old(:), pressure_old(:) - real(8), intent(in) :: crossSectionLength_old(:), crossSectionLength(:) - real(8), intent(in) :: t - integer, intent(in) :: N - real(8), intent(in) :: kappa, tau - real(8), intent(inout) :: velocity(:), pressure(:) + + 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, j - real(8), parameter :: PI = 3.141592653589793 - real(8), parameter :: E = 10000.0 - real(8), parameter :: c_mk2 = E / 2.0 * sqrt(PI) - real(8), parameter :: u0 = 10.0, ampl = 3.0, frequency = 10.0, & - t_shift = 0.0 - real(8), parameter :: tolerance = 1.0e-15 + 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(8) :: alpha, L, dx, velocity_in, tmp2, norm_1, norm_2, norm - + real(dp) :: alpha, l, dx, velocity_in, tmp2, norm_1, norm_2, norm + ! LAPACK Variables integer :: nlhs, nrhs - real(8), allocatable :: Res(:) - real(8), allocatable :: LHS(:,:) + real(dp), allocatable :: res(:) + real(dp), allocatable :: lhs(:, :) integer, allocatable :: ipiv(:) - nlhs = 2 * N + 2 + nlhs = 2*N + 2 nrhs = 1 + ! Allocate arrays - allocate(Res(2 * N + 2)) - allocate(LHS(2 * N + 2, 2 * N + 2)) - allocate(ipiv(nlhs)) + allocate (Res(2*N + 2)) + allocate (LHS(2*N + 2, 2*N + 2)) + allocate (ipiv(nlhs)) velocity = velocity_old pressure = pressure_old @@ -51,13 +48,10 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & ! Stabilization intensity alpha = 0.0 !(N * kappa * tau) / (N * tau + 1); L = 10.0 - dx = L / kappa !1.0 / (N * kappa); + dx = L/kappa !1.0 / (N * kappa); - ! Initialize result variable + ! result variable info = 0 - print *, "CrossSectionLength:" - write(*, '(10F12.6)') crossSectionLength - print *, "Alpha:", alpha ! Nonlinear solver loop do k = 1, max_iterations @@ -67,49 +61,49 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & ! 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)) + 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)) + 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) + 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) + 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) + 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) + 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 + norm = norm_1/norm_2 if ((norm < tolerance .and. k > 1) .or. k > max_iterations) then exit @@ -122,69 +116,53 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & ! 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)) + 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) + 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) + 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 + 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 + 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 + 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) - - - ! Solve Ax = b using LAPACK - ! print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" - ! do i = 1, size(LHS, 1) - ! write(*, '(10F12.6)') (LHS(i, j), j = 1, size(LHS, 2)) - ! end do - ! print *, "Diagonal elements of LHS:" - ! do i = 1, size(LHS, 1) - ! print *, "LHS(", i, ",", i, ") =", LHS(i, i) - ! end do - ! print *, "LHS Matrix (size: ", size(LHS, 1), "x", size(LHS, 2), "):" - ! do i = 1, size(LHS, 1) - ! write(*, '(10F8.2)') (LHS(i, j), j = 1, size(LHS, 2)) - ! end do + 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 @@ -193,13 +171,14 @@ subroutine fluidComputeSolutionSerial(velocity_old, pressure_old, & end if ! Update velocity and pressure - do i = 1, N+1 + do i = 1, N + 1 velocity(i) = velocity(i) + Res(i) - pressure(i) = pressure(i) + Res(i+N+1) + pressure(i) = pressure(i) + Res(i + N + 1) end do end do ! Deallocate arrays deallocate(Res, LHS, ipiv) - end subroutine fluidComputeSolutionSerial -end module FluidComputeSolution \ No newline at end of file + + end subroutine fluid_compute_solution +end module FluidComputeSolution diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index b7f519e71..749311328 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -1,87 +1,82 @@ -PROGRAM FluidSolver - USE FluidComputeSolution, ONLY: fluidComputeSolutionSerial - USE utilities, ONLY: write_vtk - IMPLICIT NONE - - ! Variable Declarations - CHARACTER(LEN=512) :: configFileName - CHARACTER(LEN=50) :: solverName - CHARACTER(LEN=50) :: meshName, pressureName, crossSectionLengthName - CHARACTER(LEN=256) :: outputFilePrefix - INTEGER :: rank, commsize, ongoing, dimensions, bool - INTEGER :: domainSize, chunkLength - INTEGER :: i, j, info - DOUBLE PRECISION :: dt, t, cellwidth - DOUBLE PRECISION, ALLOCATABLE :: pressure(:), pressure_old(:) - DOUBLE PRECISION, ALLOCATABLE :: crossSectionLength(:), crossSectionLength_old(:) - DOUBLE PRECISION, ALLOCATABLE :: velocity(:), velocity_old(:) - INTEGER, ALLOCATABLE :: vertexIDs(:) - INTEGER :: out_counter - DOUBLE PRECISION, PARAMETER :: PI = 3.141592653589793d0 - DOUBLE PRECISION :: kappa, L - DOUBLE PRECISION :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 - DOUBLE PRECISION, ALLOCATABLE :: grid(:) - - ! Start of Program - WRITE (*,*) 'Fluid: Starting Fortran solver...' - - ! Command-Line Argument Parsing - IF (COMMAND_ARGUMENT_COUNT() /= 1) THEN - WRITE (*,*) "" - WRITE (*,*) "Fluid: Usage: FluidSolver " - STOP -1 - END IF - - CALL getarg(1, configFileName) +program FluidSolver + use FluidComputeSolution, only: fluid_compute_solution + use Utilities, only: write_vtk + implicit none + integer, parameter :: dp = kind(1.0d0) ! Double precision + + ! Variable declarations + character(LEN=512) :: configFileName + character(LEN=50) :: solverName + character(LEN=50) :: meshName, pressureName, crossSectionLengthName + character(LEN=256) :: outputFilePrefix + integer :: rank, commsize, ongoing, dimensions, bool + integer :: domainSize, chunkLength + integer :: i, j, info + real(dp) :: dt, t, cellwidth + real(dp), allocatable :: pressure(:), pressure_old(:) + real(dp), allocatable :: crossSectionLength(:), crossSectionLength_old(:) + real(dp), allocatable :: velocity(:), velocity_old(:) + integer, allocatable :: vertexIDs(:) + integer :: out_counter + real(dp), parameter :: pi = 3.141592653589793_dp + real(dp) :: kappa, l + real(dp) :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 + real(dp), allocatable :: grid(:) + + + write(*, *) 'Fluid: Starting Fortran solver...' + + if (command_argument_count() /= 1) then + write(*, *) "" + write(*, *) "Fluid: Usage: FluidSolver " + stop -1 + end if + + call getarg(1, configFileName) solverName = 'Fluid' outputFilePrefix = './output/out_fluid' - ! Initialize preCICE Interface + ! Configure precice rank = 0 commsize = 1 - CALL precicef_create(solverName, configFileName, rank, commsize) - WRITE (*,*) "preCICE configured..." + call precicef_create(solverName, configFileName, rank, commsize) + write(*, *) "preCICE configured..." - ! Define Mesh and Data Names + ! Define mesh and data names meshName = "Fluid-Nodes-Mesh" pressureName = "Pressure" crossSectionLengthName = "CrossSectionLength" domainSize = 100 chunkLength = domainSize + 1 - kappa = 100.0d0 - L = 10.0d0 - - ! Get Mesh Dimensions from preCICE - CALL precicef_get_mesh_dimensions(meshName, dimensions) - - ! Allocate Arrays - ALLOCATE(vertexIDs(chunkLength)) - ALLOCATE(pressure(chunkLength)) - ALLOCATE(pressure_old(chunkLength)) - ALLOCATE(crossSectionLength(chunkLength)) - ALLOCATE(crossSectionLength_old(chunkLength)) - ALLOCATE(velocity(chunkLength)) - ALLOCATE(velocity_old(chunkLength)) - ALLOCATE(grid(dimensions * chunkLength)) - - ! Initialize vertexIDs (0-based IDs) - DO i = 1, chunkLength - vertexIDs(i) = i - 1 - END DO - - ! Initialize Physical Parameters - r0 = 1.0d0 / SQRT(PI) - a0 = r0**2 * PI - u0 = 10.0d0 - ampl = 3.0d0 - frequency = 10.0d0 - t_shift = 0.0d0 - p0 = 0.0d0 - vel_in_0 = u0 + ampl * SIN(frequency * (t_shift) * PI) - - ! Initialize Data Arrays + kappa = 100.0_dp + l = 10.0_dp + + ! Get mesh dimensions + call precicef_get_mesh_dimensions(meshName, dimensions) + + ! Allocate arrays + allocate(vertexIDs(chunkLength)) + allocate(pressure(chunkLength)) + allocate(pressure_old(chunkLength)) + allocate(crossSectionLength(chunkLength)) + allocate(crossSectionLength_old(chunkLength)) + allocate(velocity(chunkLength)) + allocate(velocity_old(chunkLength)) + allocate(grid(dimensions*chunkLength)) + + ! Initialize physical parameters + r0 = 1.0_dp / sqrt(pi) + a0 = r0**2 * pi + u0 = 10.0_dp + ampl = 3.0_dp + frequency = 10.0_dp + t_shift = 0.0_dp + p0 = 0.0_dp + vel_in_0 = u0 + ampl * sin(frequency * (t_shift) * pi) + + ! Initialize data arrays pressure = p0 pressure_old = pressure crossSectionLength = a0 @@ -89,52 +84,55 @@ PROGRAM FluidSolver velocity = vel_in_0 velocity_old = velocity - ! Initialize Grid Coordinates - cellwidth = L / REAL(domainSize, KIND=8) - DO i = 1, chunkLength - DO j = 1, dimensions - IF (j == 1) THEN - grid((i - 1) * dimensions + j) = REAL(i - 1, KIND=8) * cellwidth - ELSE - grid((i - 1) * dimensions + j) = 0.0d0 - END IF - END DO - END DO + ! Initialize grid coordinates + cellwidth = l / real(domainSize, dp) + do i = 1, chunkLength + do j = 1, dimensions + if (j == 1) then + grid((i - 1)*dimensions + j) = real(i - 1, dp) * cellwidth + else + grid((i - 1)*dimensions + j) = 0.0_dp + end if + end do + end do + + ! Initialize vertexIDs (0-based IDs) + do i = 1, chunkLength + vertexIDs(i) = i - 1 + end do ! Print the grid print *, "Grid values:" do i = 1, chunkLength do j = 1, dimensions - print "(A,I4,A,F6.2)", "grid(", (i - 1) * dimensions + j, ") = ", grid((i - 1) * dimensions + j) + print "(A,I4,A,F6.2)", "grid(", (i - 1)*dimensions + j, ") = ", grid((i - 1)*dimensions + j) end do end do - - CALL precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) ! Check if Initial Data is Required and Write if Necessary - CALL precicef_requires_initial_data(bool) - IF (bool == 1) THEN - WRITE (*,*) 'Fluid: Writing initial data' - END IF + call precicef_requires_initial_data(bool) + if (bool == 1) then + write (*, *) 'Fluid: Writing initial data' + end if - ! Initialize Simulation Time - t = 0.0d0 - WRITE (*,*) "Initialize preCICE..." - CALL precicef_initialize() + + t = 0.0d0 + write (*, *) "Initialize preCICE..." + call precicef_initialize() - ! Read Initial Cross-Section Length - CALL precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength) + ! read initial cross-Section length + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength) - ! Copy Current Cross-Section Length to Old Array + ! Copy current cross-Section length to old array crossSectionLength_old = crossSectionLength ! initialize such that mass conservation is fulfilled - DO i = 1, chunkLength - velocity_old(i) = vel_in_0 * crossSectionLength_old(1) / crossSectionLength_old(i) - END DO + do i = 1, chunkLength + velocity_old(i) = vel_in_0*crossSectionLength_old(1)/crossSectionLength_old(i) + end do - ! Initialize Output Counter out_counter = 0 ! Print all arrays with 2 decimal places @@ -143,30 +141,29 @@ PROGRAM FluidSolver print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & crossSectionLength_old(i), velocity(i), velocity_old(i) - end do - - ! Main Coupling Loop - CALL precicef_is_coupling_ongoing(ongoing) - DO WHILE (ongoing /= 0) - ! Check if Writing a Checkpoint is Required - CALL precicef_requires_writing_checkpoint(bool) - IF (bool.EQ.1) THEN - WRITE (*,*) 'Fluid: Writing iteration checkpoint' - END IF - - ! Get Maximum Time Step Size from preCICE - CALL precicef_get_max_time_step_size(dt) - - ! Compute Fluid Solution - CALL fluidComputeSolutionSerial( & + end do + + ! Main coupling loop + call precicef_is_coupling_ongoing(ongoing) + do while (ongoing /= 0) + ! Check if writing a checkpoint is required + call precicef_requires_writing_checkpoint(bool) + if (bool .eq. 1) then + write (*, *) 'Fluid: Writing iteration checkpoint' + end if + + call precicef_get_max_time_step_size(dt) + + ! solve + call fluid_compute_solution( & velocity_old, pressure_old, crossSectionLength_old, & crossSectionLength, & t + dt, & ! used for inlet velocity - domainSize, & - kappa, & + domainSize, & + kappa, & dt, & ! tau velocity, pressure, & ! resulting velocity pressure - info) + info) ! Print all arrays with 2 decimal places print *, "Index | Pressure | Pressure_Old | CrossSection | CrossSection_Old | Velocity | Velocity_Old" @@ -174,46 +171,45 @@ PROGRAM FluidSolver print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & crossSectionLength_old(i), velocity(i), velocity_old(i) - end do + end do - CALL precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) + call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) - CALL precicef_advance(dt) + call precicef_advance(dt) - CALL precicef_get_max_time_step_size(dt) + call precicef_get_max_time_step_size(dt) - CALL precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength) + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength) - CALL precicef_requires_reading_checkpoint(bool) - IF (bool.EQ.1) THEN - WRITE (*,*) 'Fluid: Reading iteration checkpoint' - ELSE + call precicef_requires_reading_checkpoint(bool) + if (bool .eq. 1) then + write (*, *) 'Fluid: Reading iteration checkpoint' + else t = t + dt - CALL write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) + call write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) crossSectionLength_old = crossSectionLength pressure_old = pressure velocity_old = velocity out_counter = out_counter + 1 - END IF + end if ! Check if Coupling is Still Ongoing - CALL precicef_is_coupling_ongoing(ongoing) - END DO - - ! Finalize preCICE Interface - CALL precicef_finalize() - WRITE (*,*) 'Exiting FluidSolver' - - ! Deallocate Dynamically Allocated Arrays - DEALLOCATE(pressure) - DEALLOCATE(pressure_old) - DEALLOCATE(crossSectionLength) - DEALLOCATE(crossSectionLength_old) - DEALLOCATE(velocity) - DEALLOCATE(velocity_old) - DEALLOCATE(grid) - DEALLOCATE(vertexIDs) - -END PROGRAM FluidSolver + call precicef_is_coupling_ongoing(ongoing) + end do + + ! finalize precice and deallocate arrays + call precicef_finalize() + write (*, *) 'Exiting FluidSolver' + + deallocate(pressure) + deallocate(pressure_old) + deallocate(crossSectionLength) + deallocate(crossSectionLength_old) + deallocate(velocity) + deallocate(velocity_old) + deallocate(grid) + deallocate(vertexIDs) + +end program FluidSolver diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 index 15ca1fe9f..4cf04561b 100644 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ b/elastic-tube-1d/fluid-fortran/src/utilities.f90 @@ -1,69 +1,69 @@ -MODULE Utilities - IMPLICIT NONE - INTEGER, PARAMETER :: dp = KIND(1.0D0) -CONTAINS +module Utilities + implicit none + integer, parameter :: dp = kind(1.0D0) +contains - SUBROUTINE write_vtk(t, iteration, filenamePrefix, nSlices, & + subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & grid, velocity, pressure, diameter) - IMPLICIT NONE + implicit none - DOUBLE PRECISION, INTENT(IN) :: t - INTEGER, INTENT(IN) :: iteration - CHARACTER(LEN=*), INTENT(IN) :: filenamePrefix - INTEGER, INTENT(IN) :: nSlices - DOUBLE PRECISION, INTENT(IN) :: grid(:), velocity(:), pressure(:), diameter(:) + double precision, intent(IN) :: t + integer, intent(IN) :: iteration + character(LEN=*), intent(IN) :: filenamePrefix + integer, intent(IN) :: nSlices + double precision, intent(IN) :: grid(:), velocity(:), pressure(:), diameter(:) - INTEGER :: ioUnit, i, ioStatus - CHARACTER(LEN=256) :: filename + integer :: ioUnit, i, ioStatus + character(LEN=256) :: filename - WRITE(filename, '(A,"_",I0,".vtk")') TRIM(filenamePrefix), iteration - PRINT *, 'Writing timestep at t=', t, ' to ', TRIM(filename) + write (filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration + print *, 'Writing timestep at t=', t, ' to ', trim(filename) - OPEN(newunit=ioUnit, file=TRIM(filename), status="replace", action="write", form="formatted", iostat=ioStatus) - IF (ioStatus /= 0) THEN - PRINT *, 'Error: Unable to open file ', TRIM(filename) - RETURN - END IF + open (newunit=ioUnit, file=trim(filename), status="replace", action="write", form="formatted", iostat=ioStatus) + if (ioStatus /= 0) then + print *, 'Error: Unable to open file ', trim(filename) + return + end if - WRITE(ioUnit, '(A)') '# vtk DataFile Version 2.0' - WRITE(ioUnit, '(A)') '' - WRITE(ioUnit, '(A)') 'ASCII' - WRITE(ioUnit, '(A)') '' - WRITE(ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A)') '# vtk DataFile Version 2.0' + write (ioUnit, '(A)') '' + write (ioUnit, '(A)') 'ASCII' + write (ioUnit, '(A)') '' + write (ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' + write (ioUnit, '(A)') '' - WRITE(ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' - WRITE(ioUnit, '(A)') '' - DO i = 1, nSlices - WRITE(ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') grid(2*(i-1)+1), grid(2*(i-1)+2), 0.0D0 - END DO - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' + write (ioUnit, '(A)') '' + do i = 1, nSlices + write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') grid(2*(i - 1) + 1), grid(2*(i - 1) + 2), 0.0D0 + end do + write (ioUnit, '(A)') '' - WRITE(ioUnit, '(A,I0)') 'POINT_DATA ', nSlices - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A,I0)') 'POINT_DATA ', nSlices + write (ioUnit, '(A)') '' - WRITE(ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' - DO i = 1, nSlices - WRITE(ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 - END DO - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' + do i = 1, nSlices + write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 + end do + write (ioUnit, '(A)') '' - WRITE(ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' - WRITE(ioUnit, '(A)') 'LOOKUP_TABLE default' - DO i = 1, nSlices - WRITE(ioUnit, '(ES24.16)') pressure(i) - END DO - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' + write (ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write (ioUnit, '(ES24.16)') pressure(i) + end do + write (ioUnit, '(A)') '' - WRITE(ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' - WRITE(ioUnit, '(A)') 'LOOKUP_TABLE default' - DO i = 1, nSlices - WRITE(ioUnit, '(ES24.16)') diameter(i) - END DO - WRITE(ioUnit, '(A)') '' + write (ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' + write (ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write (ioUnit, '(ES24.16)') diameter(i) + end do + write (ioUnit, '(A)') '' - CLOSE(ioUnit) + close (ioUnit) - END SUBROUTINE write_vtk + end subroutine write_vtk -END MODULE Utilities +end module Utilities diff --git a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 index a9540b6dc..28aeb72b4 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 @@ -1,28 +1,32 @@ -module SolidComputeSolution_mod +module SolidComputeSolution implicit none + integer, parameter :: dp = kind(1.0d0) + contains - subroutine SolidComputeSolution(chunkLength, pressure, crossSectionLength) + subroutine solid_compute_solution(chunkLength, pressure, crossSectionLength) integer, intent(in) :: chunkLength - real(8), intent(in) :: pressure(1:chunkLength) - real(8), intent(inout) :: crossSectionLength(1:chunkLength) + real(dp), intent(in) :: pressure(1:chunkLength) + real(dp), intent(inout) :: crossSectionLength(1:chunkLength) - real(8) :: PI, E, r0, c_mk, c_mk2 - real(8) :: pressure0 + real(dp) :: pi, e, r0, c_mk, c_mk2 + real(dp) :: pressure0 integer :: i - PI = 3.14159265359d0 - E = 10000.d0 - r0 = 1.d0 / sqrt(PI) - c_mk = sqrt(E / (2.d0*r0)) + ! constants + pi = 3.141592653589793_dp + e = 10000.0_dp + r0 = 1.0_dp / sqrt(pi) + c_mk = sqrt(e / (2.0_dp * r0)) c_mk2 = c_mk * c_mk - pressure0 = 0.d0 + pressure0 = 0.0_dp - do i=1, chunkLength - crossSectionLength(i) = ( (pressure0 - 2.d0 * c_mk2)**2 ) / & - ( (pressure(i) - 2.d0 * c_mk2)**2 ) + ! Update crossSectionLength based on pressure + do i = 1, chunkLength + crossSectionLength(i) = ((pressure0 - 2.0_dp * c_mk2)**2) / & + ((pressure(i) - 2.0_dp * c_mk2)**2) end do - end subroutine SolidComputeSolution + end subroutine solid_compute_solution -end module SolidComputeSolution_mod +end module SolidComputeSolution diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 2a81d40e6..67746f532 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -1,117 +1,117 @@ -PROGRAM SolidSolver - USE SolidComputeSolution_mod, ONLY: SolidComputeSolution - IMPLICIT NONE - - INTEGER, PARAMETER :: DP = KIND(1.0D0) - - CHARACTER(LEN=512) :: configFileName - CHARACTER(LEN=256) :: solverName - CHARACTER(LEN=256) :: meshName, crossSectionLengthName, pressureName - INTEGER :: rank, commsize, ongoing, dimensions, bool - INTEGER :: domainSize, chunkLength - INTEGER :: i, j - INTEGER, ALLOCATABLE :: vertexIDs(:) - DOUBLE PRECISION, ALLOCATABLE :: pressure(:), crossSectionLength(:) - DOUBLE PRECISION, ALLOCATABLE :: grid(:) - DOUBLE PRECISION :: dt, tubeLength, dx - - WRITE (*,*) 'Starting Solid Solver...' - - IF (COMMAND_ARGUMENT_COUNT() /= 1) THEN - WRITE (*,*) 'Solid: Usage: SolidSolver ' - WRITE (*,*) '' - STOP -1 - END IF - - CALL get_command_argument(1, configFileName) - - domainSize = 100 +program SolidSolver + use SolidComputeSolution, only: solid_compute_solution + implicit none + + integer, parameter :: dp = kind(1.0d0) + + character(len=512) :: configFileName + character(len=256) :: solverName + character(len=256) :: meshName, crossSectionLengthName, pressureName + integer :: rank, commsize, ongoing, dimensions, bool + integer :: domainSize, chunkLength + integer :: i, j + integer, allocatable :: vertexIDs(:) + real(dp), allocatable :: pressure(:), crossSectionLength(:) + real(dp), allocatable :: grid(:) + real(dp) :: dt, tubeLength, dx + + write(*, *) 'Starting Solid Solver...' + + if (command_argument_count() /= 1) then + write(*, *) 'Solid: Usage: SolidSolver ' + write(*, *) '' + stop -1 + end if + + call get_command_argument(1, configFileName) + + domainSize = 100 chunkLength = domainSize + 1 - tubeLength = 10.0D0 + tubeLength = 10.0_dp - WRITE (*,*) 'N: ', domainSize - WRITE (*,*) 'inputs: ', COMMAND_ARGUMENT_COUNT() + write(*, *) 'N: ', domainSize + write(*, *) 'inputs: ', command_argument_count() - solverName = 'Solid' - meshName = 'Solid-Nodes-Mesh' - crossSectionLengthName = 'CrossSectionLength' - pressureName = 'Pressure' + solverName = 'Solid' + meshName = 'Solid-Nodes-Mesh' + crossSectionLengthName = 'CrossSectionLength' + pressureName = 'Pressure' - rank = 0 + rank = 0 commsize = 1 - CALL precicef_create(solverName, configFileName, rank, commsize) - WRITE (*,*) 'preCICE configured...' - - CALL precicef_get_mesh_dimensions(meshName, dimensions) - - ! Allocate Arrays - ALLOCATE(pressure(chunkLength)) - ALLOCATE(crossSectionLength(chunkLength)) - ALLOCATE(grid(dimensions * chunkLength)) - ALLOCATE(vertexIDs(chunkLength)) - - pressure = 0.0D0 - crossSectionLength = 1.0D0 - dx = tubeLength / domainSize - DO i = 1, chunkLength - grid((i - 1) * dimensions + 1) = dx * REAL(i - 1, DP) ! x-coordinate - grid((i - 1) * dimensions + 2) = 0.0D0 ! y-coordinate + call precicef_create(solverName, configFileName, rank, commsize) + write(*, *) 'preCICE configured...' + + call precicef_get_mesh_dimensions(meshName, dimensions) + + ! Allocate arrays + allocate(pressure(chunkLength)) + allocate(crossSectionLength(chunkLength)) + allocate(grid(dimensions*chunkLength)) + allocate(vertexIDs(chunkLength)) + + pressure = 0.0_dp + crossSectionLength = 1.0_dp + dx = tubeLength / real(domainSize, dp) + do i = 1, chunkLength + grid((i - 1)*dimensions + 1) = dx * real(i - 1, dp) ! x-coordinate + grid((i - 1)*dimensions + 2) = 0.0_dp ! y-coordinate vertexIDs(i) = i - 1 ! 0-based indexing here - END DO + end do ! Print the grid print *, "Grid values:" do i = 1, chunkLength do j = 1, dimensions - print "(A,I4,A,F6.2)", "grid(", (i - 1) * dimensions + j, ") = ", grid((i - 1) * dimensions + j) + print "(A,I4,A,F6.2)", "grid(", (i - 1)*dimensions + j, ") = ", grid((i - 1)*dimensions + j) end do end do - CALL precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) - ! Check if Initial Data is Required and Write if Necessary - CALL precicef_requires_initial_data(bool) - IF (bool == 1) THEN - CALL precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) - END IF + ! Check if initial data is required and write if necessary + call precicef_requires_initial_data(bool) + if (bool == 1) then + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + end if - WRITE (*,*) 'Initialize preCICE...' - CALL precicef_initialize() + write (*, *) 'Initialize preCICE...' + call precicef_initialize() - ! Coupling Loop - CALL precicef_is_coupling_ongoing(ongoing) - DO WHILE (ongoing /= 0) + ! Coupling loop + call precicef_is_coupling_ongoing(ongoing) + do while (ongoing /= 0) - CALL precicef_requires_writing_checkpoint(bool) - IF (bool.EQ.1) THEN - WRITE (*,*) 'Solid: Writing iteration checkpoint (not implemented).' - END IF + call precicef_requires_writing_checkpoint(bool) + if (bool .eq. 1) then + write (*, *) 'Solid: Writing iteration checkpoint (not implemented).' + end if - CALL precicef_get_max_time_step_size(dt) + call precicef_get_max_time_step_size(dt) - CALL precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure) + call precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure) - CALL SolidComputeSolution(chunkLength, pressure, crossSectionLength) + call solid_compute_solution(chunkLength, pressure, crossSectionLength) - CALL precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) - CALL precicef_advance(dt) + call precicef_advance(dt) - CALL precicef_requires_reading_checkpoint(bool) - IF (bool.EQ.1) THEN - WRITE (*,*) 'Solid: Reading iteration checkpoint (not implemented).' - END IF + call precicef_requires_reading_checkpoint(bool) + if (bool .eq. 1) then + write (*, *) 'Solid: Reading iteration checkpoint (not implemented).' + end if - CALL precicef_is_coupling_ongoing(ongoing) - END DO + call precicef_is_coupling_ongoing(ongoing) + end do - WRITE (*,*) 'Exiting SolidSolver' + write (*, *) 'Exiting SolidSolver' - CALL precicef_finalize() + call precicef_finalize() - DEALLOCATE(pressure) - DEALLOCATE(crossSectionLength) - DEALLOCATE(grid) - DEALLOCATE(vertexIDs) + deallocate(pressure) + deallocate(crossSectionLength) + deallocate(grid) + deallocate(vertexIDs) -END PROGRAM SolidSolver +end program SolidSolver From 5963731303ea19e857b04c6875a3316029cc2c35 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 22:29:22 +0100 Subject: [PATCH 09/37] Remove unused var --- elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index 709f00bac..7c0981270 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -1,7 +1,7 @@ module FluidComputeSolution implicit none integer, parameter :: dp = kind(1.0d0) - + contains subroutine fluid_compute_solution(velocity_old, pressure_old, & @@ -17,7 +17,7 @@ subroutine fluid_compute_solution(velocity_old, pressure_old, & integer, intent(out) :: info ! Local variables - integer :: i, k, j + 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) From 3ce8492673da66befb83b3a757ca0e4f0098ca04 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 22:30:03 +0100 Subject: [PATCH 10/37] apply dp for consistent precision --- elastic-tube-1d/fluid-fortran/src/utilities.f90 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 index 4cf04561b..e2587ae39 100644 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ b/elastic-tube-1d/fluid-fortran/src/utilities.f90 @@ -7,11 +7,11 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & grid, velocity, pressure, diameter) implicit none - double precision, intent(IN) :: t - integer, intent(IN) :: iteration - character(LEN=*), intent(IN) :: filenamePrefix - integer, intent(IN) :: nSlices - double precision, intent(IN) :: grid(:), velocity(:), pressure(:), diameter(:) + real(dp), intent(IN) :: t + integer, intent(IN) :: iteration + character(LEN=*), intent(IN) :: filenamePrefix + integer, intent(IN) :: nSlices + real(dp), intent(IN) :: grid(:), velocity(:), pressure(:), diameter(:) integer :: ioUnit, i, ioStatus character(LEN=256) :: filename @@ -25,6 +25,7 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & return end if + ! Write vtk headers write (ioUnit, '(A)') '# vtk DataFile Version 2.0' write (ioUnit, '(A)') '' write (ioUnit, '(A)') 'ASCII' @@ -32,6 +33,7 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & write (ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' write (ioUnit, '(A)') '' + ! Write points write (ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' write (ioUnit, '(A)') '' do i = 1, nSlices @@ -42,12 +44,14 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & write (ioUnit, '(A,I0)') 'POINT_DATA ', nSlices write (ioUnit, '(A)') '' + ! Write velocity vector field write (ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' do i = 1, nSlices write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 end do write (ioUnit, '(A)') '' + ! Write pressure write (ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' write (ioUnit, '(A)') 'LOOKUP_TABLE default' do i = 1, nSlices @@ -55,6 +59,7 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & end do write (ioUnit, '(A)') '' + ! Write diameter write (ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' write (ioUnit, '(A)') 'LOOKUP_TABLE default' do i = 1, nSlices From 9388e1a222d94ec3e253a3d2cb4ccc22c12468e9 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 22:50:08 +0100 Subject: [PATCH 11/37] Remove debug prints --- .../src/FluidComputeSolution.f90 | 4 +-- .../fluid-fortran/src/FluidSolver.f90 | 36 ++++--------------- .../solid-fortran/src/SolidSolver.f90 | 12 ++----- 3 files changed, 9 insertions(+), 43 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index 7c0981270..df9604816 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -107,7 +107,6 @@ subroutine fluid_compute_solution(velocity_old, pressure_old, & if ((norm < tolerance .and. k > 1) .or. k > max_iterations) then exit - print *, "exiting" end if ! Initialize the LHS matrix @@ -166,8 +165,7 @@ subroutine fluid_compute_solution(velocity_old, pressure_old, & call dgesv(nlhs, nrhs, LHS, nlhs, ipiv, Res, nlhs, info) if (info /= 0) then - ! return - print *, "Couldnt solve" + write(*, *) "Linear Solver not converged!, Info: ", info end if ! Update velocity and pressure diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index 749311328..7576a932e 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -101,14 +101,6 @@ program FluidSolver vertexIDs(i) = i - 1 end do - ! Print the grid - print *, "Grid values:" - do i = 1, chunkLength - do j = 1, dimensions - print "(A,I4,A,F6.2)", "grid(", (i - 1)*dimensions + j, ") = ", grid((i - 1)*dimensions + j) - end do - end do - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) ! Check if Initial Data is Required and Write if Necessary @@ -117,8 +109,6 @@ program FluidSolver write (*, *) 'Fluid: Writing initial data' end if - - t = 0.0d0 write (*, *) "Initialize preCICE..." call precicef_initialize() @@ -133,23 +123,16 @@ program FluidSolver velocity_old(i) = vel_in_0*crossSectionLength_old(1)/crossSectionLength_old(i) end do + t = 0.0d0 out_counter = 0 - ! Print all arrays with 2 decimal places - print *, "Index | Pressure | Pressure_Old | CrossSection | CrossSection_Old | Velocity | Velocity_Old" - do i = 1, chunkLength - print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & - i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & - crossSectionLength_old(i), velocity(i), velocity_old(i) - end do - ! Main coupling loop call precicef_is_coupling_ongoing(ongoing) do while (ongoing /= 0) - ! Check if writing a checkpoint is required + ! checkpointing is required in implicit coupling call precicef_requires_writing_checkpoint(bool) if (bool .eq. 1) then - write (*, *) 'Fluid: Writing iteration checkpoint' + ! nothing end if call precicef_get_max_time_step_size(dt) @@ -165,14 +148,6 @@ program FluidSolver velocity, pressure, & ! resulting velocity pressure info) - ! Print all arrays with 2 decimal places - print *, "Index | Pressure | Pressure_Old | CrossSection | CrossSection_Old | Velocity | Velocity_Old" - do i = 1, chunkLength - print "(I5, 3X, F8.2, 3X, F13.2, 3X, F13.2, 3X, F16.2, 3X, F8.2, 3X, F13.2)", & - i - 1, pressure(i), pressure_old(i), crossSectionLength(i), & - crossSectionLength_old(i), velocity(i), velocity_old(i) - end do - call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) call precicef_advance(dt) @@ -183,8 +158,9 @@ program FluidSolver call precicef_requires_reading_checkpoint(bool) if (bool .eq. 1) then - write (*, *) 'Fluid: Reading iteration checkpoint' + ! not yet converged else + ! converged, advance in time t = t + dt call write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) @@ -195,7 +171,7 @@ program FluidSolver out_counter = out_counter + 1 end if - ! Check if Coupling is Still Ongoing + ! Check if coupling is still ongoing call precicef_is_coupling_ongoing(ongoing) end do diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 67746f532..77854b5b5 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -59,14 +59,6 @@ program SolidSolver vertexIDs(i) = i - 1 ! 0-based indexing here end do - ! Print the grid - print *, "Grid values:" - do i = 1, chunkLength - do j = 1, dimensions - print "(A,I4,A,F6.2)", "grid(", (i - 1)*dimensions + j, ") = ", grid((i - 1)*dimensions + j) - end do - end do - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) ! Check if initial data is required and write if necessary @@ -84,7 +76,7 @@ program SolidSolver call precicef_requires_writing_checkpoint(bool) if (bool .eq. 1) then - write (*, *) 'Solid: Writing iteration checkpoint (not implemented).' + ! Do nothing here end if call precicef_get_max_time_step_size(dt) @@ -99,7 +91,7 @@ program SolidSolver call precicef_requires_reading_checkpoint(bool) if (bool .eq. 1) then - write (*, *) 'Solid: Reading iteration checkpoint (not implemented).' + ! nothing end if call precicef_is_coupling_ongoing(ongoing) From 6bb4cc2048e61ebf7286523e8c6f0731b65e7300 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 22:55:41 +0100 Subject: [PATCH 12/37] Remove comment --- elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index 7576a932e..a173580a6 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -4,7 +4,6 @@ program FluidSolver implicit none integer, parameter :: dp = kind(1.0d0) ! Double precision - ! Variable declarations character(LEN=512) :: configFileName character(LEN=50) :: solverName character(LEN=50) :: meshName, pressureName, crossSectionLengthName From c3c9be36cee82149d90550c8866748c8e5b01969 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 6 Jan 2025 23:51:00 +0100 Subject: [PATCH 13/37] Include Fortran watchpoint in plot-all script --- elastic-tube-1d/plot-all.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/elastic-tube-1d/plot-all.sh b/elastic-tube-1d/plot-all.sh index 8ba00ee03..26975482d 100755 --- a/elastic-tube-1d/plot-all.sh +++ b/elastic-tube-1d/plot-all.sh @@ -12,15 +12,16 @@ gnuplot -p << EOF plot \ "fluid-cpp/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "cpp", \ "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints lw 2 title "python", \ - "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "rust" + "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "rust", \ + "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran" set title 'Pressure of elastic-tube at x=5' set ylabel 'pressure' plot \ "fluid-cpp/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "cpp", \ "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "python", \ - "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "rust" - - set xlabel 'time [s]' + "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "rust", \ + "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran" + set xlabel 'time [s]' EOF From 679650658788a7ee173f4f766e9a9357811a43bc Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 00:00:49 +0100 Subject: [PATCH 14/37] Improve print statement formatting --- elastic-tube-1d/fluid-fortran/src/utilities.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 index e2587ae39..e844e0a64 100644 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ b/elastic-tube-1d/fluid-fortran/src/utilities.f90 @@ -17,7 +17,7 @@ subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & character(LEN=256) :: filename write (filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration - print *, 'Writing timestep at t=', t, ' to ', trim(filename) + print '(A, F7.6, A, A)', 'writing timestep at t=', t, ' to ', trim(filename) open (newunit=ioUnit, file=trim(filename), status="replace", action="write", form="formatted", iostat=ioStatus) if (ioStatus /= 0) then From 3ab04311891a8bdf80e4ee4cdd45d28ef6fcb619 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 13:15:11 +0100 Subject: [PATCH 15/37] Remove debug compiler flags and clean up --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 75 -------------------- 1 file changed, 75 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index e14fecfc4..248b02f77 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(ElasticTube LANGUAGES Fortran C) -# Set default build type to Debug if not specified 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 @@ -9,89 +8,15 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}") -# Find required packages find_package(precice 3 REQUIRED CONFIG) find_package(LAPACK REQUIRED) -# Add executable add_executable(FluidSolver src/FluidComputeSolution.f90 src/utilities.f90 src/FluidSolver.f90 ) -# Link libraries target_link_libraries(FluidSolver PRIVATE precice::precice) target_link_libraries(FluidSolver PRIVATE ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS}) -# ============================ -# Add Compiler Flags for Debugging -# ============================ - -# Define a function to add compiler flags based on compiler ID -function(add_fortran_debug_flags target) - if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") - # GNU Fortran (gfortran) specific flags - target_compile_options(${target} PRIVATE - $<$:-fbounds-check> - $<$:-fbacktrace> - $<$:-fcheck=all> - $<$:-g> - $<$:-Wall> - $<$:-Wextra> - ) - elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") - # Intel Fortran (ifort) specific flags - target_compile_options(${target} PRIVATE - $<$:-check bounds> - $<$:-g> - $<$:-warn all> - ) - elseif(CMAKE_Fortran_COMPILER_ID MATCHES "PGI" OR - CMAKE_Fortran_COMPILER_ID MATCHES "NAG") - # PGI, NAG, and other Fortran compilers - target_compile_options(${target} PRIVATE - $<$:-C> - $<$:-g> - $<$:-Wall> - ) - else() - message(WARNING "Compiler ${CMAKE_Fortran_COMPILER_ID} not explicitly supported for debug flags.") - # Generic debug flags - target_compile_options(${target} PRIVATE - $<$:-g> - $<$:-Wall> - ) - endif() -endfunction() - -# Apply the debug flags to FluidSolver -add_fortran_debug_flags(FluidSolver) - -# ============================ -# Optionally, Add Linker Flags (if needed) -# ============================ - -# For example, to link LAPACK, you might need to specify additional flags -# However, typically, find_package(LAPACK) handles this -# If you have specific linker flags, you can add them as follows: -# target_link_libraries(FluidSolver PRIVATE ${LAPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS}) - -# ============================ -# Enable Fortran Module Generation (Optional) -# ============================ - -# If you have modules that need to be visible to other targets, set the appropriate properties -# For example: -# set_target_properties(FluidSolver PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) - -# ============================ -# Set CMake Policies (Optional) -# ============================ - -# To ensure compatibility with newer CMake versions -# cmake_policy(SET CMP0074 NEW) - -# ============================ -# End of CMakeLists.txt -# ============================ From b675f664318494cf3b2f8171a275efb731b28b00 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 13:43:25 +0100 Subject: [PATCH 16/37] Set Fortran standard and enable warnings in debug builds --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 7 +++++++ elastic-tube-1d/solid-fortran/CMakeLists.txt | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index 248b02f77..1978e7d9a 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.10) project(ElasticTube LANGUAGES Fortran C) +set(CMAKE_Fortran_STANDARD 2003) + 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 @@ -8,6 +10,11 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 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) diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt index f063b730a..c33915351 100644 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/solid-fortran/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10) project(ElasticTube LANGUAGES Fortran C) +set(CMAKE_Fortran_STANDARD 2003) + 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 @@ -9,6 +11,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}") +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) add_executable(SolidSolver From fb964db6028cb60701f63a9b37aca184a94e399f Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 13:43:37 +0100 Subject: [PATCH 17/37] Remove unused variable --- elastic-tube-1d/solid-fortran/src/SolidSolver.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 77854b5b5..2a7b523e6 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -9,7 +9,7 @@ program SolidSolver character(len=256) :: meshName, crossSectionLengthName, pressureName integer :: rank, commsize, ongoing, dimensions, bool integer :: domainSize, chunkLength - integer :: i, j + integer :: i integer, allocatable :: vertexIDs(:) real(dp), allocatable :: pressure(:), crossSectionLength(:) real(dp), allocatable :: grid(:) From b16ba90d2113836aba46a8c27e3f69c1b736adbf Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 14:27:13 +0100 Subject: [PATCH 18/37] Set character lengths to 50 --- elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 | 2 +- elastic-tube-1d/solid-fortran/src/SolidSolver.f90 | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index a173580a6..f59b30df4 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -4,7 +4,7 @@ program FluidSolver implicit none integer, parameter :: dp = kind(1.0d0) ! Double precision - character(LEN=512) :: configFileName + character(LEN=50) :: configFileName character(LEN=50) :: solverName character(LEN=50) :: meshName, pressureName, crossSectionLengthName character(LEN=256) :: outputFilePrefix diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 2a7b523e6..9de1b1d63 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -4,9 +4,9 @@ program SolidSolver integer, parameter :: dp = kind(1.0d0) - character(len=512) :: configFileName - character(len=256) :: solverName - character(len=256) :: meshName, crossSectionLengthName, pressureName + character(len=50) :: configFileName + character(len=50) :: solverName + character(len=50) :: meshName, crossSectionLengthName, pressureName integer :: rank, commsize, ongoing, dimensions, bool integer :: domainSize, chunkLength integer :: i From 75fe3e3bf1dc211b37b724813ebb61cb7f54d8fb Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 14:34:19 +0100 Subject: [PATCH 19/37] Add preCICE Fortran module file (precice.f90) --- elastic-tube-1d/solid-fortran/src/precice.f90 | 315 ++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 elastic-tube-1d/solid-fortran/src/precice.f90 diff --git a/elastic-tube-1d/solid-fortran/src/precice.f90 b/elastic-tube-1d/solid-fortran/src/precice.f90 new file mode 100644 index 000000000..13f880e2b --- /dev/null +++ b/elastic-tube-1d/solid-fortran/src/precice.f90 @@ -0,0 +1,315 @@ +module precice + use, intrinsic :: iso_c_binding + implicit none + + interface + + subroutine precicef_create(participantName, configFileName, & + & solverProcessIndex, solverProcessSize, & + & participantNameLength, configFileNameLength) & + & bind(c, name='precicef_create_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: participantName + character(kind=c_char), dimension(*) :: configFileName + integer(kind=c_int) :: solverProcessIndex + integer(kind=c_int) :: solverProcessSize + integer(kind=c_int), value :: participantNameLength + integer(kind=c_int), value :: configFileNameLength + end subroutine precicef_create + + subroutine precicef_initialize() & + & bind(c, name='precicef_initialize_') + + use, intrinsic :: iso_c_binding + end subroutine precicef_initialize + + subroutine precicef_advance(timestepLengthLimit) & + & bind(c, name='precicef_advance_') + + use, intrinsic :: iso_c_binding + real(kind=c_double) :: timestepLengthLimit + end subroutine precicef_advance + + subroutine precicef_finalize() & + & bind(c, name='precicef_finalize_') + + use, intrinsic :: iso_c_binding + end subroutine precicef_finalize + + subroutine precicef_requires_reading_checkpoint(isRequired) & + & bind(c, name='precicef_requires_reading_checkpoint_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_reading_checkpoint + + subroutine precicef_requires_writing_checkpoint(isRequired) & + & bind(c, name='precicef_requires_writing_checkpoint_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_writing_checkpoint + + subroutine precicef_get_mesh_dimensions(meshName, dimensions, & + & meshNameLength) & + & bind(c, name='precicef_get_mesh_dimensions_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: dimensions + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_dimensions + + subroutine precicef_get_data_dimensions(meshName, dataName, & + & dimensions, meshNameLength, dataNameLength) & + & bind(c, name='precicef_get_data_dimensions_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: dimensions + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_get_data_dimensions + + subroutine precicef_is_coupling_ongoing(isOngoing) & + & bind(c, name='precicef_is_coupling_ongoing_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isOngoing + end subroutine precicef_is_coupling_ongoing + + subroutine precicef_is_time_window_complete(isComplete) & + & bind(c, name='precicef_is_time_window_complete_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isComplete + end subroutine precicef_is_time_window_complete + + subroutine precicef_get_max_time_step_size(maxTimeStepSize) & + & bind(c, name='precicef_get_max_time_step_size_') + + use, intrinsic :: iso_c_binding + real(kind=c_double) :: maxTimeStepSize + end subroutine precicef_get_max_time_step_size + + subroutine precicef_requires_mesh_connectivity_for(meshName, required, meshNameLength) & + & bind(c, name='precicef_requires_mesh_connectivity_for_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: required + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_requires_mesh_connectivity_for + + subroutine precicef_set_vertex(meshName, position, vertexID, meshNameLength) & + & bind(c, name='precicef_set_vertex_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + real(kind=c_double) :: coordinates(3) + integer(kind=c_int) :: id + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_vertex + + subroutine precicef_get_mesh_vertex_size(meshName, meshSize, meshNameLength) & + & bind(c, name='precicef_get_mesh_vertex_size_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: meshSize + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_vertex_size + + subroutine precicef_set_vertices(meshName, size, coordinates, ids, meshNameLength) & + & bind(c, name='precicef_set_vertices_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + real(kind=c_double) :: coordinates(*) + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_vertices + + subroutine precicef_set_edge(meshName, firstVertexID, secondVertexID, & + & meshNameLength) & + & bind(c, name='precicef_set_edge_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_edge + + subroutine precicef_set_mesh_edges(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_edges_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_edges + + subroutine precicef_set_triangle(meshName, firstEdgeID, secondEdgeID, & + & thirdEdgeID, meshNameLength) & + & bind(c, name='precicef_set_triangle_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstEdgeID + integer(kind=c_int) :: secondEdgeID + integer(kind=c_int) :: thirdEdgeID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_triangle + + subroutine precicef_set_quad(meshName, firstVertexID, secondVertexID, & + & thirdVertexID, fourthVertexID, & + & meshNameLength ) & + & bind(c, name='precicef_set_quad_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int) :: thirdVertexID + integer(kind=c_int) :: fourthVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_quad + + subroutine precicef_set_mesh_quads(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_quads_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_quads + + subroutine precicef_set_tetrahedron(meshName, firstVertexID, secondVertexID, & + & thirdVertexID, fourthVertexID, & + & meshNameLength) & + & bind(c, name='precicef_set_tetrahedron_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int) :: thirdVertexID + integer(kind=c_int) :: fourthVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_tetrahedron + + subroutine precicef_set_mesh_tetrahedra(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_tetrahedra_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_tetrahedra + + subroutine precicef_requires_initial_data(isRequired) & + & bind(c, name='precicef_requires_initial_data_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_initial_data + + subroutine precicef_write_data(meshName, dataName, size, ids, & + & values, meshNameLength, dataNameLength) & + & bind(c, name='precicef_write_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: values(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_write_data + + subroutine precicef_read_data(meshName, dataName, size, ids, & + & relativeReadTime, values, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_read_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: relativeReadTime + real(kind=c_double) :: values(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_read_data + + subroutine precicef_set_mesh_access_region(meshName, boundingBox, & + & meshNameLength) & + & bind(c, name='precicef_set_mesh_access_region_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + real(kind=c_double) :: boundingBox(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_access_region + + subroutine precicef_get_mesh_vertex_ids_and_coordinates(meshName, size, & + & ids, coordinates, & + & meshNameLength) & + & bind(c, name='precicef_get_mesh_vertex_ids_and_coordinates_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: coordinates(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_vertex_ids_and_coordinates + + subroutine precicef_requires_gradient_data_for(meshName, dataName, & + & required, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_requires_gradient_data_for_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: required + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_requires_gradient_data_for + + subroutine precicef_write_gradient_data(meshName, dataName, size, ids, & + & gradients, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_write_gradient_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: gradients(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_write_gradient_data + + subroutine precicef_get_version_information(versionInfo, lengthVersionInfo) & + & bind(c, name="precicef_get_version_information_") + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: versionInfo + integer(kind=c_int), value :: lengthVersionInfo + end subroutine precicef_get_version_information + + end interface + +end module precice From 2cde8cbf89bba17c2d3bd40170f821c8d6fe08df Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 14:36:34 +0100 Subject: [PATCH 20/37] Add preCICE Fortran module file (precice.f90) --- elastic-tube-1d/fluid-fortran/src/precice.f90 | 315 ++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 elastic-tube-1d/fluid-fortran/src/precice.f90 diff --git a/elastic-tube-1d/fluid-fortran/src/precice.f90 b/elastic-tube-1d/fluid-fortran/src/precice.f90 new file mode 100644 index 000000000..13f880e2b --- /dev/null +++ b/elastic-tube-1d/fluid-fortran/src/precice.f90 @@ -0,0 +1,315 @@ +module precice + use, intrinsic :: iso_c_binding + implicit none + + interface + + subroutine precicef_create(participantName, configFileName, & + & solverProcessIndex, solverProcessSize, & + & participantNameLength, configFileNameLength) & + & bind(c, name='precicef_create_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: participantName + character(kind=c_char), dimension(*) :: configFileName + integer(kind=c_int) :: solverProcessIndex + integer(kind=c_int) :: solverProcessSize + integer(kind=c_int), value :: participantNameLength + integer(kind=c_int), value :: configFileNameLength + end subroutine precicef_create + + subroutine precicef_initialize() & + & bind(c, name='precicef_initialize_') + + use, intrinsic :: iso_c_binding + end subroutine precicef_initialize + + subroutine precicef_advance(timestepLengthLimit) & + & bind(c, name='precicef_advance_') + + use, intrinsic :: iso_c_binding + real(kind=c_double) :: timestepLengthLimit + end subroutine precicef_advance + + subroutine precicef_finalize() & + & bind(c, name='precicef_finalize_') + + use, intrinsic :: iso_c_binding + end subroutine precicef_finalize + + subroutine precicef_requires_reading_checkpoint(isRequired) & + & bind(c, name='precicef_requires_reading_checkpoint_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_reading_checkpoint + + subroutine precicef_requires_writing_checkpoint(isRequired) & + & bind(c, name='precicef_requires_writing_checkpoint_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_writing_checkpoint + + subroutine precicef_get_mesh_dimensions(meshName, dimensions, & + & meshNameLength) & + & bind(c, name='precicef_get_mesh_dimensions_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: dimensions + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_dimensions + + subroutine precicef_get_data_dimensions(meshName, dataName, & + & dimensions, meshNameLength, dataNameLength) & + & bind(c, name='precicef_get_data_dimensions_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: dimensions + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_get_data_dimensions + + subroutine precicef_is_coupling_ongoing(isOngoing) & + & bind(c, name='precicef_is_coupling_ongoing_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isOngoing + end subroutine precicef_is_coupling_ongoing + + subroutine precicef_is_time_window_complete(isComplete) & + & bind(c, name='precicef_is_time_window_complete_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isComplete + end subroutine precicef_is_time_window_complete + + subroutine precicef_get_max_time_step_size(maxTimeStepSize) & + & bind(c, name='precicef_get_max_time_step_size_') + + use, intrinsic :: iso_c_binding + real(kind=c_double) :: maxTimeStepSize + end subroutine precicef_get_max_time_step_size + + subroutine precicef_requires_mesh_connectivity_for(meshName, required, meshNameLength) & + & bind(c, name='precicef_requires_mesh_connectivity_for_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: required + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_requires_mesh_connectivity_for + + subroutine precicef_set_vertex(meshName, position, vertexID, meshNameLength) & + & bind(c, name='precicef_set_vertex_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + real(kind=c_double) :: coordinates(3) + integer(kind=c_int) :: id + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_vertex + + subroutine precicef_get_mesh_vertex_size(meshName, meshSize, meshNameLength) & + & bind(c, name='precicef_get_mesh_vertex_size_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: meshSize + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_vertex_size + + subroutine precicef_set_vertices(meshName, size, coordinates, ids, meshNameLength) & + & bind(c, name='precicef_set_vertices_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + real(kind=c_double) :: coordinates(*) + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_vertices + + subroutine precicef_set_edge(meshName, firstVertexID, secondVertexID, & + & meshNameLength) & + & bind(c, name='precicef_set_edge_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_edge + + subroutine precicef_set_mesh_edges(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_edges_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_edges + + subroutine precicef_set_triangle(meshName, firstEdgeID, secondEdgeID, & + & thirdEdgeID, meshNameLength) & + & bind(c, name='precicef_set_triangle_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstEdgeID + integer(kind=c_int) :: secondEdgeID + integer(kind=c_int) :: thirdEdgeID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_triangle + + subroutine precicef_set_quad(meshName, firstVertexID, secondVertexID, & + & thirdVertexID, fourthVertexID, & + & meshNameLength ) & + & bind(c, name='precicef_set_quad_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int) :: thirdVertexID + integer(kind=c_int) :: fourthVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_quad + + subroutine precicef_set_mesh_quads(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_quads_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_quads + + subroutine precicef_set_tetrahedron(meshName, firstVertexID, secondVertexID, & + & thirdVertexID, fourthVertexID, & + & meshNameLength) & + & bind(c, name='precicef_set_tetrahedron_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: firstVertexID + integer(kind=c_int) :: secondVertexID + integer(kind=c_int) :: thirdVertexID + integer(kind=c_int) :: fourthVertexID + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_tetrahedron + + subroutine precicef_set_mesh_tetrahedra(meshName, size, ids, meshNameLength) & + & bind(c, name='precicef_set_mesh_tetrahedra_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_tetrahedra + + subroutine precicef_requires_initial_data(isRequired) & + & bind(c, name='precicef_requires_initial_data_') + + use, intrinsic :: iso_c_binding + integer(kind=c_int) :: isRequired + end subroutine precicef_requires_initial_data + + subroutine precicef_write_data(meshName, dataName, size, ids, & + & values, meshNameLength, dataNameLength) & + & bind(c, name='precicef_write_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: values(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_write_data + + subroutine precicef_read_data(meshName, dataName, size, ids, & + & relativeReadTime, values, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_read_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: relativeReadTime + real(kind=c_double) :: values(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_read_data + + subroutine precicef_set_mesh_access_region(meshName, boundingBox, & + & meshNameLength) & + & bind(c, name='precicef_set_mesh_access_region_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + real(kind=c_double) :: boundingBox(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_set_mesh_access_region + + subroutine precicef_get_mesh_vertex_ids_and_coordinates(meshName, size, & + & ids, coordinates, & + & meshNameLength) & + & bind(c, name='precicef_get_mesh_vertex_ids_and_coordinates_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: coordinates(*) + integer(kind=c_int), value :: meshNameLength + end subroutine precicef_get_mesh_vertex_ids_and_coordinates + + subroutine precicef_requires_gradient_data_for(meshName, dataName, & + & required, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_requires_gradient_data_for_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: required + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_requires_gradient_data_for + + subroutine precicef_write_gradient_data(meshName, dataName, size, ids, & + & gradients, meshNameLength, & + & dataNameLength) & + & bind(c, name='precicef_write_gradient_data_') + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: meshName + character(kind=c_char), dimension(*) :: dataName + integer(kind=c_int) :: size + integer(kind=c_int) :: ids(*) + real(kind=c_double) :: gradients(*) + integer(kind=c_int), value :: meshNameLength + integer(kind=c_int), value :: dataNameLength + end subroutine precicef_write_gradient_data + + subroutine precicef_get_version_information(versionInfo, lengthVersionInfo) & + & bind(c, name="precicef_get_version_information_") + + use, intrinsic :: iso_c_binding + character(kind=c_char), dimension(*) :: versionInfo + integer(kind=c_int), value :: lengthVersionInfo + end subroutine precicef_get_version_information + + end interface + +end module precice From 9dd624ac2a0d1e51a82d894df000c0a3c4292cf6 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Tue, 7 Jan 2025 16:54:06 +0100 Subject: [PATCH 21/37] Add Fortran module and update precicef_ calls with length args --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 1 + .../fluid-fortran/src/FluidSolver.f90 | 18 ++++++++++------- elastic-tube-1d/solid-fortran/CMakeLists.txt | 1 + .../solid-fortran/src/SolidSolver.f90 | 20 +++++++++++++------ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index 1978e7d9a..bdb070435 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable(FluidSolver src/FluidComputeSolution.f90 src/utilities.f90 src/FluidSolver.f90 + src/precice.f90 ) target_link_libraries(FluidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index f59b30df4..8aa4833cb 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -1,4 +1,5 @@ program FluidSolver + use precice use FluidComputeSolution, only: fluid_compute_solution use Utilities, only: write_vtk implicit none @@ -39,7 +40,7 @@ program FluidSolver ! Configure precice rank = 0 commsize = 1 - call precicef_create(solverName, configFileName, rank, commsize) + call precicef_create(solverName, configFileName, rank, commsize, len_trim(solverName), len_trim(configFileName)) write(*, *) "preCICE configured..." ! Define mesh and data names @@ -53,7 +54,7 @@ program FluidSolver l = 10.0_dp ! Get mesh dimensions - call precicef_get_mesh_dimensions(meshName, dimensions) + call precicef_get_mesh_dimensions(meshName, dimensions, len_trim(meshName)) ! Allocate arrays allocate(vertexIDs(chunkLength)) @@ -100,7 +101,7 @@ program FluidSolver vertexIDs(i) = i - 1 end do - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, len_trim(meshName)) ! Check if Initial Data is Required and Write if Necessary call precicef_requires_initial_data(bool) @@ -112,7 +113,8 @@ program FluidSolver call precicef_initialize() ! read initial cross-Section length - call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength) + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength, & + len_trim(meshName), len_trim(crossSectionLengthName)) ! Copy current cross-Section length to old array crossSectionLength_old = crossSectionLength @@ -147,13 +149,15 @@ program FluidSolver velocity, pressure, & ! resulting velocity pressure info) - call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure) - + call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure, & + len_trim(meshName), len_trim(pressureName)) + call precicef_advance(dt) call precicef_get_max_time_step_size(dt) - call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength) + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength, & + len_trim(meshName), len_trim(crossSectionLengthName)) call precicef_requires_reading_checkpoint(bool) if (bool .eq. 1) then diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt index c33915351..7f57ccca4 100644 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/solid-fortran/CMakeLists.txt @@ -20,6 +20,7 @@ find_package(precice 3 REQUIRED CONFIG) add_executable(SolidSolver src/SolidComputeSolution.f90 src/SolidSolver.f90 + src/precice.f90 ) target_link_libraries(SolidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 index 9de1b1d63..86be2925f 100644 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 @@ -1,4 +1,5 @@ program SolidSolver + use precice use SolidComputeSolution, only: solid_compute_solution implicit none @@ -39,10 +40,12 @@ program SolidSolver rank = 0 commsize = 1 - call precicef_create(solverName, configFileName, rank, commsize) + call precicef_create(solverName, configFileName, rank, commsize, & + len_trim(solverName), len_trim(configFileName)) write(*, *) 'preCICE configured...' - call precicef_get_mesh_dimensions(meshName, dimensions) + call precicef_get_mesh_dimensions(meshName, dimensions, & + len_trim(meshName)) ! Allocate arrays allocate(pressure(chunkLength)) @@ -53,18 +56,21 @@ program SolidSolver pressure = 0.0_dp crossSectionLength = 1.0_dp dx = tubeLength / real(domainSize, dp) + do i = 1, chunkLength grid((i - 1)*dimensions + 1) = dx * real(i - 1, dp) ! x-coordinate grid((i - 1)*dimensions + 2) = 0.0_dp ! y-coordinate vertexIDs(i) = i - 1 ! 0-based indexing here end do - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs) + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, & + len_trim(meshName)) ! Check if initial data is required and write if necessary call precicef_requires_initial_data(bool) if (bool == 1) then - call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & + crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) end if write (*, *) 'Initialize preCICE...' @@ -81,11 +87,13 @@ program SolidSolver call precicef_get_max_time_step_size(dt) - call precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure) + call precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure, & + len_trim(meshName), len_trim(pressureName)) call solid_compute_solution(chunkLength, pressure, crossSectionLength) - call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, crossSectionLength) + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & + crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) call precicef_advance(dt) From 67d1a8dbc7660299e58cb0a0a29825705b3136fd Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 8 Jan 2025 11:16:41 +0100 Subject: [PATCH 22/37] Add plotting for fluid fortran diameter --- elastic-tube-1d/plot-diameter.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/elastic-tube-1d/plot-diameter.sh b/elastic-tube-1d/plot-diameter.sh index ae5f84d97..059eba585 100755 --- a/elastic-tube-1d/plot-diameter.sh +++ b/elastic-tube-1d/plot-diameter.sh @@ -23,3 +23,10 @@ if [ -n "$(ls -A ./fluid-rust/output/*.vtk 2>/dev/null)" ]; then else echo "No results to plot from fluid-python." fi + +# Plot diameter from fluid-fortran +if [ -n "$(ls -A ./fluid-fortran/output/*.vtk 2>/dev/null)" ]; then + python3 plot-vtk.py diameter fluid-fortran/output/out_fluid_ & +else + echo "No results to plot from fluid-fortran." +fi \ No newline at end of file From 827a7c5dd45273b60d422df482eb64235c70a1f9 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 8 Jan 2025 11:54:28 +0100 Subject: [PATCH 23/37] Delete file (now fetched dynamically) --- elastic-tube-1d/fluid-fortran/src/precice.f90 | 315 ------------------ elastic-tube-1d/solid-fortran/src/precice.f90 | 315 ------------------ 2 files changed, 630 deletions(-) delete mode 100644 elastic-tube-1d/fluid-fortran/src/precice.f90 delete mode 100644 elastic-tube-1d/solid-fortran/src/precice.f90 diff --git a/elastic-tube-1d/fluid-fortran/src/precice.f90 b/elastic-tube-1d/fluid-fortran/src/precice.f90 deleted file mode 100644 index 13f880e2b..000000000 --- a/elastic-tube-1d/fluid-fortran/src/precice.f90 +++ /dev/null @@ -1,315 +0,0 @@ -module precice - use, intrinsic :: iso_c_binding - implicit none - - interface - - subroutine precicef_create(participantName, configFileName, & - & solverProcessIndex, solverProcessSize, & - & participantNameLength, configFileNameLength) & - & bind(c, name='precicef_create_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: participantName - character(kind=c_char), dimension(*) :: configFileName - integer(kind=c_int) :: solverProcessIndex - integer(kind=c_int) :: solverProcessSize - integer(kind=c_int), value :: participantNameLength - integer(kind=c_int), value :: configFileNameLength - end subroutine precicef_create - - subroutine precicef_initialize() & - & bind(c, name='precicef_initialize_') - - use, intrinsic :: iso_c_binding - end subroutine precicef_initialize - - subroutine precicef_advance(timestepLengthLimit) & - & bind(c, name='precicef_advance_') - - use, intrinsic :: iso_c_binding - real(kind=c_double) :: timestepLengthLimit - end subroutine precicef_advance - - subroutine precicef_finalize() & - & bind(c, name='precicef_finalize_') - - use, intrinsic :: iso_c_binding - end subroutine precicef_finalize - - subroutine precicef_requires_reading_checkpoint(isRequired) & - & bind(c, name='precicef_requires_reading_checkpoint_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_reading_checkpoint - - subroutine precicef_requires_writing_checkpoint(isRequired) & - & bind(c, name='precicef_requires_writing_checkpoint_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_writing_checkpoint - - subroutine precicef_get_mesh_dimensions(meshName, dimensions, & - & meshNameLength) & - & bind(c, name='precicef_get_mesh_dimensions_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: dimensions - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_dimensions - - subroutine precicef_get_data_dimensions(meshName, dataName, & - & dimensions, meshNameLength, dataNameLength) & - & bind(c, name='precicef_get_data_dimensions_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: dimensions - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_get_data_dimensions - - subroutine precicef_is_coupling_ongoing(isOngoing) & - & bind(c, name='precicef_is_coupling_ongoing_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isOngoing - end subroutine precicef_is_coupling_ongoing - - subroutine precicef_is_time_window_complete(isComplete) & - & bind(c, name='precicef_is_time_window_complete_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isComplete - end subroutine precicef_is_time_window_complete - - subroutine precicef_get_max_time_step_size(maxTimeStepSize) & - & bind(c, name='precicef_get_max_time_step_size_') - - use, intrinsic :: iso_c_binding - real(kind=c_double) :: maxTimeStepSize - end subroutine precicef_get_max_time_step_size - - subroutine precicef_requires_mesh_connectivity_for(meshName, required, meshNameLength) & - & bind(c, name='precicef_requires_mesh_connectivity_for_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: required - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_requires_mesh_connectivity_for - - subroutine precicef_set_vertex(meshName, position, vertexID, meshNameLength) & - & bind(c, name='precicef_set_vertex_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - real(kind=c_double) :: coordinates(3) - integer(kind=c_int) :: id - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_vertex - - subroutine precicef_get_mesh_vertex_size(meshName, meshSize, meshNameLength) & - & bind(c, name='precicef_get_mesh_vertex_size_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: meshSize - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_vertex_size - - subroutine precicef_set_vertices(meshName, size, coordinates, ids, meshNameLength) & - & bind(c, name='precicef_set_vertices_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - real(kind=c_double) :: coordinates(*) - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_vertices - - subroutine precicef_set_edge(meshName, firstVertexID, secondVertexID, & - & meshNameLength) & - & bind(c, name='precicef_set_edge_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_edge - - subroutine precicef_set_mesh_edges(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_edges_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_edges - - subroutine precicef_set_triangle(meshName, firstEdgeID, secondEdgeID, & - & thirdEdgeID, meshNameLength) & - & bind(c, name='precicef_set_triangle_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstEdgeID - integer(kind=c_int) :: secondEdgeID - integer(kind=c_int) :: thirdEdgeID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_triangle - - subroutine precicef_set_quad(meshName, firstVertexID, secondVertexID, & - & thirdVertexID, fourthVertexID, & - & meshNameLength ) & - & bind(c, name='precicef_set_quad_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int) :: thirdVertexID - integer(kind=c_int) :: fourthVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_quad - - subroutine precicef_set_mesh_quads(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_quads_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_quads - - subroutine precicef_set_tetrahedron(meshName, firstVertexID, secondVertexID, & - & thirdVertexID, fourthVertexID, & - & meshNameLength) & - & bind(c, name='precicef_set_tetrahedron_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int) :: thirdVertexID - integer(kind=c_int) :: fourthVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_tetrahedron - - subroutine precicef_set_mesh_tetrahedra(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_tetrahedra_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_tetrahedra - - subroutine precicef_requires_initial_data(isRequired) & - & bind(c, name='precicef_requires_initial_data_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_initial_data - - subroutine precicef_write_data(meshName, dataName, size, ids, & - & values, meshNameLength, dataNameLength) & - & bind(c, name='precicef_write_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: values(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_write_data - - subroutine precicef_read_data(meshName, dataName, size, ids, & - & relativeReadTime, values, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_read_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: relativeReadTime - real(kind=c_double) :: values(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_read_data - - subroutine precicef_set_mesh_access_region(meshName, boundingBox, & - & meshNameLength) & - & bind(c, name='precicef_set_mesh_access_region_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - real(kind=c_double) :: boundingBox(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_access_region - - subroutine precicef_get_mesh_vertex_ids_and_coordinates(meshName, size, & - & ids, coordinates, & - & meshNameLength) & - & bind(c, name='precicef_get_mesh_vertex_ids_and_coordinates_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: coordinates(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_vertex_ids_and_coordinates - - subroutine precicef_requires_gradient_data_for(meshName, dataName, & - & required, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_requires_gradient_data_for_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: required - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_requires_gradient_data_for - - subroutine precicef_write_gradient_data(meshName, dataName, size, ids, & - & gradients, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_write_gradient_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: gradients(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_write_gradient_data - - subroutine precicef_get_version_information(versionInfo, lengthVersionInfo) & - & bind(c, name="precicef_get_version_information_") - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: versionInfo - integer(kind=c_int), value :: lengthVersionInfo - end subroutine precicef_get_version_information - - end interface - -end module precice diff --git a/elastic-tube-1d/solid-fortran/src/precice.f90 b/elastic-tube-1d/solid-fortran/src/precice.f90 deleted file mode 100644 index 13f880e2b..000000000 --- a/elastic-tube-1d/solid-fortran/src/precice.f90 +++ /dev/null @@ -1,315 +0,0 @@ -module precice - use, intrinsic :: iso_c_binding - implicit none - - interface - - subroutine precicef_create(participantName, configFileName, & - & solverProcessIndex, solverProcessSize, & - & participantNameLength, configFileNameLength) & - & bind(c, name='precicef_create_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: participantName - character(kind=c_char), dimension(*) :: configFileName - integer(kind=c_int) :: solverProcessIndex - integer(kind=c_int) :: solverProcessSize - integer(kind=c_int), value :: participantNameLength - integer(kind=c_int), value :: configFileNameLength - end subroutine precicef_create - - subroutine precicef_initialize() & - & bind(c, name='precicef_initialize_') - - use, intrinsic :: iso_c_binding - end subroutine precicef_initialize - - subroutine precicef_advance(timestepLengthLimit) & - & bind(c, name='precicef_advance_') - - use, intrinsic :: iso_c_binding - real(kind=c_double) :: timestepLengthLimit - end subroutine precicef_advance - - subroutine precicef_finalize() & - & bind(c, name='precicef_finalize_') - - use, intrinsic :: iso_c_binding - end subroutine precicef_finalize - - subroutine precicef_requires_reading_checkpoint(isRequired) & - & bind(c, name='precicef_requires_reading_checkpoint_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_reading_checkpoint - - subroutine precicef_requires_writing_checkpoint(isRequired) & - & bind(c, name='precicef_requires_writing_checkpoint_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_writing_checkpoint - - subroutine precicef_get_mesh_dimensions(meshName, dimensions, & - & meshNameLength) & - & bind(c, name='precicef_get_mesh_dimensions_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: dimensions - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_dimensions - - subroutine precicef_get_data_dimensions(meshName, dataName, & - & dimensions, meshNameLength, dataNameLength) & - & bind(c, name='precicef_get_data_dimensions_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: dimensions - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_get_data_dimensions - - subroutine precicef_is_coupling_ongoing(isOngoing) & - & bind(c, name='precicef_is_coupling_ongoing_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isOngoing - end subroutine precicef_is_coupling_ongoing - - subroutine precicef_is_time_window_complete(isComplete) & - & bind(c, name='precicef_is_time_window_complete_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isComplete - end subroutine precicef_is_time_window_complete - - subroutine precicef_get_max_time_step_size(maxTimeStepSize) & - & bind(c, name='precicef_get_max_time_step_size_') - - use, intrinsic :: iso_c_binding - real(kind=c_double) :: maxTimeStepSize - end subroutine precicef_get_max_time_step_size - - subroutine precicef_requires_mesh_connectivity_for(meshName, required, meshNameLength) & - & bind(c, name='precicef_requires_mesh_connectivity_for_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: required - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_requires_mesh_connectivity_for - - subroutine precicef_set_vertex(meshName, position, vertexID, meshNameLength) & - & bind(c, name='precicef_set_vertex_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - real(kind=c_double) :: coordinates(3) - integer(kind=c_int) :: id - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_vertex - - subroutine precicef_get_mesh_vertex_size(meshName, meshSize, meshNameLength) & - & bind(c, name='precicef_get_mesh_vertex_size_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: meshSize - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_vertex_size - - subroutine precicef_set_vertices(meshName, size, coordinates, ids, meshNameLength) & - & bind(c, name='precicef_set_vertices_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - real(kind=c_double) :: coordinates(*) - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_vertices - - subroutine precicef_set_edge(meshName, firstVertexID, secondVertexID, & - & meshNameLength) & - & bind(c, name='precicef_set_edge_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_edge - - subroutine precicef_set_mesh_edges(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_edges_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_edges - - subroutine precicef_set_triangle(meshName, firstEdgeID, secondEdgeID, & - & thirdEdgeID, meshNameLength) & - & bind(c, name='precicef_set_triangle_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstEdgeID - integer(kind=c_int) :: secondEdgeID - integer(kind=c_int) :: thirdEdgeID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_triangle - - subroutine precicef_set_quad(meshName, firstVertexID, secondVertexID, & - & thirdVertexID, fourthVertexID, & - & meshNameLength ) & - & bind(c, name='precicef_set_quad_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int) :: thirdVertexID - integer(kind=c_int) :: fourthVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_quad - - subroutine precicef_set_mesh_quads(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_quads_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_quads - - subroutine precicef_set_tetrahedron(meshName, firstVertexID, secondVertexID, & - & thirdVertexID, fourthVertexID, & - & meshNameLength) & - & bind(c, name='precicef_set_tetrahedron_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: firstVertexID - integer(kind=c_int) :: secondVertexID - integer(kind=c_int) :: thirdVertexID - integer(kind=c_int) :: fourthVertexID - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_tetrahedron - - subroutine precicef_set_mesh_tetrahedra(meshName, size, ids, meshNameLength) & - & bind(c, name='precicef_set_mesh_tetrahedra_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_tetrahedra - - subroutine precicef_requires_initial_data(isRequired) & - & bind(c, name='precicef_requires_initial_data_') - - use, intrinsic :: iso_c_binding - integer(kind=c_int) :: isRequired - end subroutine precicef_requires_initial_data - - subroutine precicef_write_data(meshName, dataName, size, ids, & - & values, meshNameLength, dataNameLength) & - & bind(c, name='precicef_write_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: values(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_write_data - - subroutine precicef_read_data(meshName, dataName, size, ids, & - & relativeReadTime, values, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_read_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: relativeReadTime - real(kind=c_double) :: values(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_read_data - - subroutine precicef_set_mesh_access_region(meshName, boundingBox, & - & meshNameLength) & - & bind(c, name='precicef_set_mesh_access_region_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - real(kind=c_double) :: boundingBox(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_set_mesh_access_region - - subroutine precicef_get_mesh_vertex_ids_and_coordinates(meshName, size, & - & ids, coordinates, & - & meshNameLength) & - & bind(c, name='precicef_get_mesh_vertex_ids_and_coordinates_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: coordinates(*) - integer(kind=c_int), value :: meshNameLength - end subroutine precicef_get_mesh_vertex_ids_and_coordinates - - subroutine precicef_requires_gradient_data_for(meshName, dataName, & - & required, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_requires_gradient_data_for_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: required - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_requires_gradient_data_for - - subroutine precicef_write_gradient_data(meshName, dataName, size, ids, & - & gradients, meshNameLength, & - & dataNameLength) & - & bind(c, name='precicef_write_gradient_data_') - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: meshName - character(kind=c_char), dimension(*) :: dataName - integer(kind=c_int) :: size - integer(kind=c_int) :: ids(*) - real(kind=c_double) :: gradients(*) - integer(kind=c_int), value :: meshNameLength - integer(kind=c_int), value :: dataNameLength - end subroutine precicef_write_gradient_data - - subroutine precicef_get_version_information(versionInfo, lengthVersionInfo) & - & bind(c, name="precicef_get_version_information_") - - use, intrinsic :: iso_c_binding - character(kind=c_char), dimension(*) :: versionInfo - integer(kind=c_int), value :: lengthVersionInfo - end subroutine precicef_get_version_information - - end interface - -end module precice From aa9247ebf49135ea1e4a959a96c9fae0fbc8e8a0 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 8 Jan 2025 12:00:05 +0100 Subject: [PATCH 24/37] Get precice.f90 from the fortran module repo in run script --- elastic-tube-1d/fluid-fortran/run.sh | 5 +++++ elastic-tube-1d/solid-fortran/run.sh | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/elastic-tube-1d/fluid-fortran/run.sh b/elastic-tube-1d/fluid-fortran/run.sh index 2a0de7786..1f307ae6f 100755 --- a/elastic-tube-1d/fluid-fortran/run.sh +++ b/elastic-tube-1d/fluid-fortran/run.sh @@ -4,6 +4,11 @@ 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 diff --git a/elastic-tube-1d/solid-fortran/run.sh b/elastic-tube-1d/solid-fortran/run.sh index 5263549b9..337bd8c1f 100755 --- a/elastic-tube-1d/solid-fortran/run.sh +++ b/elastic-tube-1d/solid-fortran/run.sh @@ -4,6 +4,11 @@ set -e -u . ../../tools/log.sh || true exec > >(tee --append "$LOGFILE") 2>&1 || true +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 cd build From 0cddeb710056abf96cc39dac3aedbe42e53e4063 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 05:11:12 +0100 Subject: [PATCH 25/37] Add descriptive comment for info, fix variable capitalizations --- .../fluid-fortran/src/FluidComputeSolution.f90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 index df9604816..650fc79f6 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 @@ -5,33 +5,33 @@ module FluidComputeSolution contains subroutine fluid_compute_solution(velocity_old, pressure_old, & - crossSectionLength_old, crossSectionLength, t, n, kappa, tau, & + 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 + 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 :: 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 :: 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 + 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(:, :) + real(dp), allocatable :: Res(:) + real(dp), allocatable :: LHS(:, :) integer, allocatable :: ipiv(:) nlhs = 2*N + 2 @@ -50,7 +50,7 @@ subroutine fluid_compute_solution(velocity_old, pressure_old, & L = 10.0 dx = L/kappa !1.0 / (N * kappa); - ! result variable + ! Output status from dgesv (0 = success, < 0 = invalid argument, > 0 = singular matrix) info = 0 ! Nonlinear solver loop From af13235e3b1cf978d189045e8dd2d5fe5c5ea5ca Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 05:20:19 +0100 Subject: [PATCH 26/37] Use 50 chars for outputFilePrefix --- elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index 8aa4833cb..a2149a753 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -8,7 +8,7 @@ program FluidSolver character(LEN=50) :: configFileName character(LEN=50) :: solverName character(LEN=50) :: meshName, pressureName, crossSectionLengthName - character(LEN=256) :: outputFilePrefix + character(LEN=50) :: outputFilePrefix integer :: rank, commsize, ongoing, dimensions, bool integer :: domainSize, chunkLength integer :: i, j, info From f14181a4ca84a650fdc5843d4548e8b453585779 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 05:28:27 +0100 Subject: [PATCH 27/37] Add comments from cpp, capitalize pi --- .../fluid-fortran/src/FluidSolver.f90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 index a2149a753..f2b4485f5 100644 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 @@ -18,7 +18,7 @@ program FluidSolver real(dp), allocatable :: velocity(:), velocity_old(:) integer, allocatable :: vertexIDs(:) integer :: out_counter - real(dp), parameter :: pi = 3.141592653589793_dp + real(dp), parameter :: PI = 3.141592653589793_dp real(dp) :: kappa, l real(dp) :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 real(dp), allocatable :: grid(:) @@ -67,14 +67,14 @@ program FluidSolver allocate(grid(dimensions*chunkLength)) ! Initialize physical parameters - r0 = 1.0_dp / sqrt(pi) - a0 = r0**2 * pi - u0 = 10.0_dp - ampl = 3.0_dp - frequency = 10.0_dp - t_shift = 0.0_dp - p0 = 0.0_dp - vel_in_0 = u0 + ampl * sin(frequency * (t_shift) * pi) + r0 = 1.0_dp / sqrt(PI) ! radius of the tube + a0 = r0**2 * PI ! cross-sectional area + u0 = 10.0_dp ! mean velocity + ampl = 3.0_dp ! amplitude of varying velocity + frequency = 10.0_dp ! frequency of variation + t_shift = 0.0_dp ! temporal shift of variation + p0 = 0.0_dp ! pressure at outlet + vel_in_0 = u0 + ampl * sin(frequency * (t_shift) * PI) ! Initialize data arrays pressure = p0 From f153c56fe2789e56a15f720351dce5c73f6de216 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 05:32:09 +0100 Subject: [PATCH 28/37] Remove Fortran standard --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 2 -- elastic-tube-1d/solid-fortran/CMakeLists.txt | 2 -- 2 files changed, 4 deletions(-) diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt index bdb070435..706fd822f 100644 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/fluid-fortran/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(ElasticTube LANGUAGES Fortran C) -set(CMAKE_Fortran_STANDARD 2003) - 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 diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt index 7f57ccca4..a1be8258f 100644 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ b/elastic-tube-1d/solid-fortran/CMakeLists.txt @@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.10) project(ElasticTube LANGUAGES Fortran C) -set(CMAKE_Fortran_STANDARD 2003) - 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 From 1e6f130e0d52711442aae5545034d5b765edfc4e Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 06:01:13 +0100 Subject: [PATCH 29/37] Added -module suffix to solver folders --- .../fluid-fortran-module/CMakeLists.txt | 28 +++ elastic-tube-1d/fluid-fortran-module/clean.sh | 8 + .../fluid-fortran-module/output/.keepme | 0 elastic-tube-1d/fluid-fortran-module/run.sh | 20 ++ .../src/FluidComputeSolution.f90 | 182 ++++++++++++++++ .../fluid-fortran-module/src/FluidSolver.f90 | 194 ++++++++++++++++++ .../fluid-fortran-module/src/utilities.f90 | 74 +++++++ .../solid-fortran-module/CMakeLists.txt | 24 +++ elastic-tube-1d/solid-fortran-module/clean.sh | 7 + elastic-tube-1d/solid-fortran-module/run.sh | 22 ++ .../src/SolidComputeSolution.f90 | 32 +++ .../solid-fortran-module/src/SolidSolver.f90 | 117 +++++++++++ 12 files changed, 708 insertions(+) create mode 100644 elastic-tube-1d/fluid-fortran-module/CMakeLists.txt create mode 100755 elastic-tube-1d/fluid-fortran-module/clean.sh create mode 100644 elastic-tube-1d/fluid-fortran-module/output/.keepme create mode 100755 elastic-tube-1d/fluid-fortran-module/run.sh create mode 100644 elastic-tube-1d/fluid-fortran-module/src/FluidComputeSolution.f90 create mode 100644 elastic-tube-1d/fluid-fortran-module/src/FluidSolver.f90 create mode 100644 elastic-tube-1d/fluid-fortran-module/src/utilities.f90 create mode 100644 elastic-tube-1d/solid-fortran-module/CMakeLists.txt create mode 100755 elastic-tube-1d/solid-fortran-module/clean.sh create mode 100755 elastic-tube-1d/solid-fortran-module/run.sh create mode 100644 elastic-tube-1d/solid-fortran-module/src/SolidComputeSolution.f90 create mode 100644 elastic-tube-1d/solid-fortran-module/src/SolidSolver.f90 diff --git a/elastic-tube-1d/fluid-fortran-module/CMakeLists.txt b/elastic-tube-1d/fluid-fortran-module/CMakeLists.txt new file mode 100644 index 000000000..706fd822f --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/CMakeLists.txt @@ -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}) + diff --git a/elastic-tube-1d/fluid-fortran-module/clean.sh b/elastic-tube-1d/fluid-fortran-module/clean.sh new file mode 100755 index 000000000..8d5d37784 --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/clean.sh @@ -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 . diff --git a/elastic-tube-1d/fluid-fortran-module/output/.keepme b/elastic-tube-1d/fluid-fortran-module/output/.keepme new file mode 100644 index 000000000..e69de29bb diff --git a/elastic-tube-1d/fluid-fortran-module/run.sh b/elastic-tube-1d/fluid-fortran-module/run.sh new file mode 100755 index 000000000..1f307ae6f --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/run.sh @@ -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 diff --git a/elastic-tube-1d/fluid-fortran-module/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran-module/src/FluidComputeSolution.f90 new file mode 100644 index 000000000..650fc79f6 --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/src/FluidComputeSolution.f90 @@ -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 diff --git a/elastic-tube-1d/fluid-fortran-module/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran-module/src/FluidSolver.f90 new file mode 100644 index 000000000..f2b4485f5 --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/src/FluidSolver.f90 @@ -0,0 +1,194 @@ +program FluidSolver + use precice + use FluidComputeSolution, only: fluid_compute_solution + use Utilities, only: write_vtk + implicit none + integer, parameter :: dp = kind(1.0d0) ! Double precision + + character(LEN=50) :: configFileName + character(LEN=50) :: solverName + character(LEN=50) :: meshName, pressureName, crossSectionLengthName + character(LEN=50) :: outputFilePrefix + integer :: rank, commsize, ongoing, dimensions, bool + integer :: domainSize, chunkLength + integer :: i, j, info + real(dp) :: dt, t, cellwidth + real(dp), allocatable :: pressure(:), pressure_old(:) + real(dp), allocatable :: crossSectionLength(:), crossSectionLength_old(:) + real(dp), allocatable :: velocity(:), velocity_old(:) + integer, allocatable :: vertexIDs(:) + integer :: out_counter + real(dp), parameter :: PI = 3.141592653589793_dp + real(dp) :: kappa, l + real(dp) :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 + real(dp), allocatable :: grid(:) + + + write(*, *) 'Fluid: Starting Fortran solver...' + + if (command_argument_count() /= 1) then + write(*, *) "" + write(*, *) "Fluid: Usage: FluidSolver " + stop -1 + end if + + call getarg(1, configFileName) + + solverName = 'Fluid' + outputFilePrefix = './output/out_fluid' + + ! Configure precice + rank = 0 + commsize = 1 + call precicef_create(solverName, configFileName, rank, commsize, len_trim(solverName), len_trim(configFileName)) + write(*, *) "preCICE configured..." + + ! Define mesh and data names + meshName = "Fluid-Nodes-Mesh" + pressureName = "Pressure" + crossSectionLengthName = "CrossSectionLength" + + domainSize = 100 + chunkLength = domainSize + 1 + kappa = 100.0_dp + l = 10.0_dp + + ! Get mesh dimensions + call precicef_get_mesh_dimensions(meshName, dimensions, len_trim(meshName)) + + ! Allocate arrays + allocate(vertexIDs(chunkLength)) + allocate(pressure(chunkLength)) + allocate(pressure_old(chunkLength)) + allocate(crossSectionLength(chunkLength)) + allocate(crossSectionLength_old(chunkLength)) + allocate(velocity(chunkLength)) + allocate(velocity_old(chunkLength)) + allocate(grid(dimensions*chunkLength)) + + ! Initialize physical parameters + r0 = 1.0_dp / sqrt(PI) ! radius of the tube + a0 = r0**2 * PI ! cross-sectional area + u0 = 10.0_dp ! mean velocity + ampl = 3.0_dp ! amplitude of varying velocity + frequency = 10.0_dp ! frequency of variation + t_shift = 0.0_dp ! temporal shift of variation + p0 = 0.0_dp ! pressure at outlet + vel_in_0 = u0 + ampl * sin(frequency * (t_shift) * PI) + + ! Initialize data arrays + pressure = p0 + pressure_old = pressure + crossSectionLength = a0 + crossSectionLength_old = crossSectionLength + velocity = vel_in_0 + velocity_old = velocity + + ! Initialize grid coordinates + cellwidth = l / real(domainSize, dp) + do i = 1, chunkLength + do j = 1, dimensions + if (j == 1) then + grid((i - 1)*dimensions + j) = real(i - 1, dp) * cellwidth + else + grid((i - 1)*dimensions + j) = 0.0_dp + end if + end do + end do + + ! Initialize vertexIDs (0-based IDs) + do i = 1, chunkLength + vertexIDs(i) = i - 1 + end do + + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, len_trim(meshName)) + + ! Check if Initial Data is Required and Write if Necessary + call precicef_requires_initial_data(bool) + if (bool == 1) then + write (*, *) 'Fluid: Writing initial data' + end if + + write (*, *) "Initialize preCICE..." + call precicef_initialize() + + ! read initial cross-Section length + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength, & + len_trim(meshName), len_trim(crossSectionLengthName)) + + ! Copy current cross-Section length to old array + crossSectionLength_old = crossSectionLength + + ! initialize such that mass conservation is fulfilled + do i = 1, chunkLength + velocity_old(i) = vel_in_0*crossSectionLength_old(1)/crossSectionLength_old(i) + end do + + t = 0.0d0 + out_counter = 0 + + ! Main coupling loop + call precicef_is_coupling_ongoing(ongoing) + do while (ongoing /= 0) + ! checkpointing is required in implicit coupling + call precicef_requires_writing_checkpoint(bool) + if (bool .eq. 1) then + ! nothing + end if + + call precicef_get_max_time_step_size(dt) + + ! solve + call fluid_compute_solution( & + velocity_old, pressure_old, crossSectionLength_old, & + crossSectionLength, & + t + dt, & ! used for inlet velocity + domainSize, & + kappa, & + dt, & ! tau + velocity, pressure, & ! resulting velocity pressure + info) + + call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure, & + len_trim(meshName), len_trim(pressureName)) + + call precicef_advance(dt) + + call precicef_get_max_time_step_size(dt) + + call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength, & + len_trim(meshName), len_trim(crossSectionLengthName)) + + call precicef_requires_reading_checkpoint(bool) + if (bool .eq. 1) then + ! not yet converged + else + ! converged, advance in time + t = t + dt + + call write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) + crossSectionLength_old = crossSectionLength + pressure_old = pressure + velocity_old = velocity + + out_counter = out_counter + 1 + end if + + ! Check if coupling is still ongoing + call precicef_is_coupling_ongoing(ongoing) + end do + + ! finalize precice and deallocate arrays + call precicef_finalize() + write (*, *) 'Exiting FluidSolver' + + deallocate(pressure) + deallocate(pressure_old) + deallocate(crossSectionLength) + deallocate(crossSectionLength_old) + deallocate(velocity) + deallocate(velocity_old) + deallocate(grid) + deallocate(vertexIDs) + +end program FluidSolver diff --git a/elastic-tube-1d/fluid-fortran-module/src/utilities.f90 b/elastic-tube-1d/fluid-fortran-module/src/utilities.f90 new file mode 100644 index 000000000..e844e0a64 --- /dev/null +++ b/elastic-tube-1d/fluid-fortran-module/src/utilities.f90 @@ -0,0 +1,74 @@ +module Utilities + implicit none + integer, parameter :: dp = kind(1.0D0) +contains + + subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & + grid, velocity, pressure, diameter) + implicit none + + real(dp), intent(IN) :: t + integer, intent(IN) :: iteration + character(LEN=*), intent(IN) :: filenamePrefix + integer, intent(IN) :: nSlices + real(dp), intent(IN) :: grid(:), velocity(:), pressure(:), diameter(:) + + integer :: ioUnit, i, ioStatus + character(LEN=256) :: filename + + write (filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration + print '(A, F7.6, A, A)', 'writing timestep at t=', t, ' to ', trim(filename) + + open (newunit=ioUnit, file=trim(filename), status="replace", action="write", form="formatted", iostat=ioStatus) + if (ioStatus /= 0) then + print *, 'Error: Unable to open file ', trim(filename) + return + end if + + ! Write vtk headers + write (ioUnit, '(A)') '# vtk DataFile Version 2.0' + write (ioUnit, '(A)') '' + write (ioUnit, '(A)') 'ASCII' + write (ioUnit, '(A)') '' + write (ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' + write (ioUnit, '(A)') '' + + ! Write points + write (ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' + write (ioUnit, '(A)') '' + do i = 1, nSlices + write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') grid(2*(i - 1) + 1), grid(2*(i - 1) + 2), 0.0D0 + end do + write (ioUnit, '(A)') '' + + write (ioUnit, '(A,I0)') 'POINT_DATA ', nSlices + write (ioUnit, '(A)') '' + + ! Write velocity vector field + write (ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' + do i = 1, nSlices + write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 + end do + write (ioUnit, '(A)') '' + + ! Write pressure + write (ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' + write (ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write (ioUnit, '(ES24.16)') pressure(i) + end do + write (ioUnit, '(A)') '' + + ! Write diameter + write (ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' + write (ioUnit, '(A)') 'LOOKUP_TABLE default' + do i = 1, nSlices + write (ioUnit, '(ES24.16)') diameter(i) + end do + write (ioUnit, '(A)') '' + + close (ioUnit) + + end subroutine write_vtk + +end module Utilities diff --git a/elastic-tube-1d/solid-fortran-module/CMakeLists.txt b/elastic-tube-1d/solid-fortran-module/CMakeLists.txt new file mode 100644 index 000000000..a1be8258f --- /dev/null +++ b/elastic-tube-1d/solid-fortran-module/CMakeLists.txt @@ -0,0 +1,24 @@ +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}") + +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) + +add_executable(SolidSolver + src/SolidComputeSolution.f90 + src/SolidSolver.f90 + src/precice.f90 +) + +target_link_libraries(SolidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/solid-fortran-module/clean.sh b/elastic-tube-1d/solid-fortran-module/clean.sh new file mode 100755 index 000000000..ae7a54924 --- /dev/null +++ b/elastic-tube-1d/solid-fortran-module/clean.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e -u + +. ../../tools/cleaning-tools.sh + +clean_precice_logs . +clean_case_logs . diff --git a/elastic-tube-1d/solid-fortran-module/run.sh b/elastic-tube-1d/solid-fortran-module/run.sh new file mode 100755 index 000000000..337bd8c1f --- /dev/null +++ b/elastic-tube-1d/solid-fortran-module/run.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e -u + +. ../../tools/log.sh || true +exec > >(tee --append "$LOGFILE") 2>&1 || true + +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 + cd build + cmake .. + cmake --build . + cd .. +fi + +./build/SolidSolver ../precice-config.xml + +close_log diff --git a/elastic-tube-1d/solid-fortran-module/src/SolidComputeSolution.f90 b/elastic-tube-1d/solid-fortran-module/src/SolidComputeSolution.f90 new file mode 100644 index 000000000..28aeb72b4 --- /dev/null +++ b/elastic-tube-1d/solid-fortran-module/src/SolidComputeSolution.f90 @@ -0,0 +1,32 @@ +module SolidComputeSolution + implicit none + integer, parameter :: dp = kind(1.0d0) + +contains + + subroutine solid_compute_solution(chunkLength, pressure, crossSectionLength) + integer, intent(in) :: chunkLength + real(dp), intent(in) :: pressure(1:chunkLength) + real(dp), intent(inout) :: crossSectionLength(1:chunkLength) + + real(dp) :: pi, e, r0, c_mk, c_mk2 + real(dp) :: pressure0 + integer :: i + + ! constants + pi = 3.141592653589793_dp + e = 10000.0_dp + r0 = 1.0_dp / sqrt(pi) + c_mk = sqrt(e / (2.0_dp * r0)) + c_mk2 = c_mk * c_mk + pressure0 = 0.0_dp + + ! Update crossSectionLength based on pressure + do i = 1, chunkLength + crossSectionLength(i) = ((pressure0 - 2.0_dp * c_mk2)**2) / & + ((pressure(i) - 2.0_dp * c_mk2)**2) + end do + + end subroutine solid_compute_solution + +end module SolidComputeSolution diff --git a/elastic-tube-1d/solid-fortran-module/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran-module/src/SolidSolver.f90 new file mode 100644 index 000000000..86be2925f --- /dev/null +++ b/elastic-tube-1d/solid-fortran-module/src/SolidSolver.f90 @@ -0,0 +1,117 @@ +program SolidSolver + use precice + use SolidComputeSolution, only: solid_compute_solution + implicit none + + integer, parameter :: dp = kind(1.0d0) + + character(len=50) :: configFileName + character(len=50) :: solverName + character(len=50) :: meshName, crossSectionLengthName, pressureName + integer :: rank, commsize, ongoing, dimensions, bool + integer :: domainSize, chunkLength + integer :: i + integer, allocatable :: vertexIDs(:) + real(dp), allocatable :: pressure(:), crossSectionLength(:) + real(dp), allocatable :: grid(:) + real(dp) :: dt, tubeLength, dx + + write(*, *) 'Starting Solid Solver...' + + if (command_argument_count() /= 1) then + write(*, *) 'Solid: Usage: SolidSolver ' + write(*, *) '' + stop -1 + end if + + call get_command_argument(1, configFileName) + + domainSize = 100 + chunkLength = domainSize + 1 + tubeLength = 10.0_dp + + write(*, *) 'N: ', domainSize + write(*, *) 'inputs: ', command_argument_count() + + solverName = 'Solid' + meshName = 'Solid-Nodes-Mesh' + crossSectionLengthName = 'CrossSectionLength' + pressureName = 'Pressure' + + rank = 0 + commsize = 1 + call precicef_create(solverName, configFileName, rank, commsize, & + len_trim(solverName), len_trim(configFileName)) + write(*, *) 'preCICE configured...' + + call precicef_get_mesh_dimensions(meshName, dimensions, & + len_trim(meshName)) + + ! Allocate arrays + allocate(pressure(chunkLength)) + allocate(crossSectionLength(chunkLength)) + allocate(grid(dimensions*chunkLength)) + allocate(vertexIDs(chunkLength)) + + pressure = 0.0_dp + crossSectionLength = 1.0_dp + dx = tubeLength / real(domainSize, dp) + + do i = 1, chunkLength + grid((i - 1)*dimensions + 1) = dx * real(i - 1, dp) ! x-coordinate + grid((i - 1)*dimensions + 2) = 0.0_dp ! y-coordinate + vertexIDs(i) = i - 1 ! 0-based indexing here + end do + + call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, & + len_trim(meshName)) + + ! Check if initial data is required and write if necessary + call precicef_requires_initial_data(bool) + if (bool == 1) then + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & + crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) + end if + + write (*, *) 'Initialize preCICE...' + call precicef_initialize() + + ! Coupling loop + call precicef_is_coupling_ongoing(ongoing) + do while (ongoing /= 0) + + call precicef_requires_writing_checkpoint(bool) + if (bool .eq. 1) then + ! Do nothing here + end if + + call precicef_get_max_time_step_size(dt) + + call precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure, & + len_trim(meshName), len_trim(pressureName)) + + call solid_compute_solution(chunkLength, pressure, crossSectionLength) + + call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & + crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) + + call precicef_advance(dt) + + call precicef_requires_reading_checkpoint(bool) + if (bool .eq. 1) then + ! nothing + end if + + call precicef_is_coupling_ongoing(ongoing) + end do + + write (*, *) 'Exiting SolidSolver' + + call precicef_finalize() + + deallocate(pressure) + deallocate(crossSectionLength) + deallocate(grid) + deallocate(vertexIDs) + +end program SolidSolver From b0d45930883792e13d7568561616510d8b5ff684 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 06:27:54 +0100 Subject: [PATCH 30/37] Include fortran result in plot-all image --- .../images/tutorials-elastic-tube-1d-all.png | Bin 93881 -> 92186 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/elastic-tube-1d/images/tutorials-elastic-tube-1d-all.png b/elastic-tube-1d/images/tutorials-elastic-tube-1d-all.png index 166b27d4e7a215f519f4fd39c66a50b4e172936f..021ee2dfef8e1019b69477f8b8e5b6af8a8a7d90 100644 GIT binary patch literal 92186 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

pSIQb$LNXa|lV#-2-9mHN zXs*e@&(2vQ3yxI72~Y46#*DzA+w*qnw;ERdq*v~>?aXlOwU@V^W!6U5 zOm-cCtrtQo9jg)=yg+(fTUGS|?8BhOmc%&N7=PR1eVdg1yx3*}`~uKN0OJNUKmUfj z<#u-C2UAU!BFd7TSmV|z=YvSu)&>rg@o;R3DjMy~4db6e8fNyefyb+1Au<0_^9@%Eo|Brkl+)q*25j*%DW7jWBf4uKqv)@(cBew>v$*iQa)>xd)NdN7K*~q#u zFZiiRd0GcFD!2)e#Lu4;&k$jhTJ1($mg-jCZ%~h;`C5AF(lhW%Q^+NrwzH^RiKIJz zM^(qj+fqYAgxZ>3N6U_iQ;cL`L*~w#gmY{$g~WlvpZrf-Ml}7J z{o*5WGu&3x^u7DK{;7_XUqD&fS?za`|M$50@R25`ie`R|gKSh(divgt z;6hiIenanigELZ=IL7soQ^`mY*053|jK%p^lQVkK>k%z(_CSW-e z0kILcfq zwJ77(PzIY6!r8|UUW_okEGyqp`ocL!XD3$pKd=I{K#!=mJ@%Vv?*F|S7yMV1U9^9d zLh%d(Z=_`VjJY#!BO$%&k8Po*iK)Qv4>CEG6BcHVk|qSWG^|L$Wp}9cNi)B22wUr& z4qBKV&8HH=Ln#b-0(%dSwk}CYn!huyw&F97t}u>X{yq_MSNLGR{Wke67Gh_@su=Wb z&-9^VuYd)1_gX>;H$Mm(fC5=tN9S6t4)qm;p2FZATo9JF{d`X{qbe8gHy8RQ)%D+2 z?_2$MUR;;PA8`@K{_QsrLS%EZb3u=c1okANjUAwn0<;QlC<=0NHxTDrPK{7LE&CHP zw3&g?3LG1t+V}XEFgpc;LR#812%a1p)BX@GmzAB9BO@gRD>*kUZ8PYwz>~0*C7-z{ z+deKs6MgdGE#f5XmOz|n1gfV6?|xd$D35|P(jjvx`=ND! zo%D!{f-&CBI2)LyOWz({Ikumu?~r-=UZ5fpbp6A%#9S{J+p!j ~#fJo~C%L5`=X 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 G`2PZ&_h%9S From 9e68835910af916759664079cc043f8d3f949760 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 12:21:02 +0100 Subject: [PATCH 34/37] Fix backslash --- elastic-tube-1d/plot-all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elastic-tube-1d/plot-all.sh b/elastic-tube-1d/plot-all.sh index e0df51d2f..bb1396070 100755 --- a/elastic-tube-1d/plot-all.sh +++ b/elastic-tube-1d/plot-all.sh @@ -13,7 +13,7 @@ gnuplot -p << EOF "fluid-cpp/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "cpp", \ "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints lw 2 title "python", \ "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "rust", \ - "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran" + "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran", \ "fluid-fortran-module/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran-module" set title 'Pressure of elastic-tube at x=5' @@ -22,7 +22,7 @@ gnuplot -p << EOF "fluid-cpp/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "cpp", \ "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "python", \ "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "rust", \ - "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran" + "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran", \ "fluid-fortran-module/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran-module" set xlabel 'time [s]' From e5cb17d167d123d625cdfa741f41ebdddbf03283 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 13:08:47 +0100 Subject: [PATCH 35/37] Deleted file --- elastic-tube-1d/fluid-fortran-module/output/.keepme | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 elastic-tube-1d/fluid-fortran-module/output/.keepme diff --git a/elastic-tube-1d/fluid-fortran-module/output/.keepme b/elastic-tube-1d/fluid-fortran-module/output/.keepme deleted file mode 100644 index e69de29bb..000000000 From ee37f0fcc8c961766ab897193be7eb0fab3df158 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 13:25:47 +0100 Subject: [PATCH 36/37] Add changelog entry --- changelog-entries/607.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog-entries/607.md diff --git a/changelog-entries/607.md b/changelog-entries/607.md new file mode 100644 index 000000000..5f234dc48 --- /dev/null +++ b/changelog-entries/607.md @@ -0,0 +1 @@ +- Added Fortran solvers for the elastic-tube-1d tutorial using the [Fortran module](https://github.com/precice/fortran-module). \ No newline at end of file From af9a497e174d9d12512d57005fad748fb41a32d8 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 17:10:11 +0100 Subject: [PATCH 37/37] Create output directory in run script --- elastic-tube-1d/fluid-fortran-module/run.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/elastic-tube-1d/fluid-fortran-module/run.sh b/elastic-tube-1d/fluid-fortran-module/run.sh index 1f307ae6f..0b6d315c7 100755 --- a/elastic-tube-1d/fluid-fortran-module/run.sh +++ b/elastic-tube-1d/fluid-fortran-module/run.sh @@ -15,6 +15,8 @@ if [ ! -d build ]; then cmake --build build fi +mkdir -p output + ./build/FluidSolver ../precice-config.xml close_log

pSIQb$LNXa|lV#-2-9mHN zXs*e@&(2vQ3yxI72~Y46#*DzA+w*qnw;ERdq*v~>?aXlOwU@V^W!6U5 zOm-cCtrtQo9jg)=yg+(fTUGS|?8BhOmc%&N7=PR1eVdg1yx3*}`~uKN0OJNUKmUfj z<#u-C2UAU!BFd7TSmV|z=YvSu)&>rg@o;R3DjMy~4db6e8fNyefyb+1Au<0_^9@%Eo|Brkl+)q*25j*%DW7jWBf4uKqv)@(cBew>v$*iQa)>xd)NdN7K*~q#u zFZiiRd0GcFD!2)e#Lu4;&k$jhTJ1($mg-jCZ%~h;`C5AF(lhW%Q^+NrwzH^RiKIJz zM^(qj+fqYAgxZ>3N6U_iQ;cL`L*~w#gmY{$g~WlvpZrf-Ml}7J z{o*5WGu&3x^u7DK{;7_XUqD&fS?za`|M$50@R25`ie`R|gKSh(divgt z;6hiIenanigELZ=IL7soQ^`mY*053|jK%p^lQVkK>k%z(_CSW-e z0kILcfq zwJ77(PzIY6!r8|UUW_okEGyqp`ocL!XD3$pKd=I{K#!=mJ@%Vv?*F|S7yMV1U9^9d zLh%d(Z=_`VjJY#!BO$%&k8Po*iK)Qv4>CEG6BcHVk|qSWG^|L$Wp}9cNi)B22wUr& z4qBKV&8HH=Ln#b-0(%dSwk}CYn!huyw&F97t}u>X{yq_MSNLGR{Wke67Gh_@su=Wb z&-9^VuYd)1_gX>;H$Mm(fC5=tN9S6t4)qm;p2FZATo9JF{d`X{qbe8gHy8RQ)%D+2 z?_2$MUR;;PA8`@K{_QsrLS%EZb3u=c1okANjUAwn0<;QlC<=0NHxTDrPK{7LE&CHP zw3&g?3LG1t+V}XEFgpc;LR#812%a1p)BX@GmzAB9BO@gRD>*kUZ8PYwz>~0*C7-z{ z+deKs6MgdGE#f5XmOz|n1gfV6?|xd$D35|P(jjvx`=ND! zo%D!{f-&CBI2)LyOWz({Ikumu?~r-=UZ5fpbp6A%#9S{J+p!j ~#fJo~C%L5`=X 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 G`2PZ&_h%9S literal 93881 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 From 7d09f7f605e586f456f8d07bf2367eab8bc1037a Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Mon, 27 Jan 2025 07:49:18 +0100 Subject: [PATCH 31/37] Deleted folders --- elastic-tube-1d/fluid-fortran/CMakeLists.txt | 28 --- elastic-tube-1d/fluid-fortran/clean.sh | 8 - elastic-tube-1d/fluid-fortran/output/.keepme | 0 elastic-tube-1d/fluid-fortran/run.sh | 20 -- .../src/FluidComputeSolution.f90 | 182 ---------------- .../fluid-fortran/src/FluidSolver.f90 | 194 ------------------ .../fluid-fortran/src/utilities.f90 | 74 ------- elastic-tube-1d/solid-fortran/CMakeLists.txt | 24 --- elastic-tube-1d/solid-fortran/clean.sh | 7 - elastic-tube-1d/solid-fortran/run.sh | 22 -- .../src/SolidComputeSolution.f90 | 32 --- .../solid-fortran/src/SolidSolver.f90 | 117 ----------- 12 files changed, 708 deletions(-) delete mode 100644 elastic-tube-1d/fluid-fortran/CMakeLists.txt delete mode 100755 elastic-tube-1d/fluid-fortran/clean.sh delete mode 100644 elastic-tube-1d/fluid-fortran/output/.keepme delete mode 100755 elastic-tube-1d/fluid-fortran/run.sh delete mode 100644 elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 delete mode 100644 elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 delete mode 100644 elastic-tube-1d/fluid-fortran/src/utilities.f90 delete mode 100644 elastic-tube-1d/solid-fortran/CMakeLists.txt delete mode 100755 elastic-tube-1d/solid-fortran/clean.sh delete mode 100755 elastic-tube-1d/solid-fortran/run.sh delete mode 100644 elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 delete mode 100644 elastic-tube-1d/solid-fortran/src/SolidSolver.f90 diff --git a/elastic-tube-1d/fluid-fortran/CMakeLists.txt b/elastic-tube-1d/fluid-fortran/CMakeLists.txt deleted file mode 100644 index 706fd822f..000000000 --- a/elastic-tube-1d/fluid-fortran/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -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}) - diff --git a/elastic-tube-1d/fluid-fortran/clean.sh b/elastic-tube-1d/fluid-fortran/clean.sh deleted file mode 100755 index 8d5d37784..000000000 --- a/elastic-tube-1d/fluid-fortran/clean.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e -u - -. ../../tools/cleaning-tools.sh - -rm -rvf ./output/*.vtk -clean_precice_logs . -clean_case_logs . diff --git a/elastic-tube-1d/fluid-fortran/output/.keepme b/elastic-tube-1d/fluid-fortran/output/.keepme deleted file mode 100644 index e69de29bb..000000000 diff --git a/elastic-tube-1d/fluid-fortran/run.sh b/elastic-tube-1d/fluid-fortran/run.sh deleted file mode 100755 index 1f307ae6f..000000000 --- a/elastic-tube-1d/fluid-fortran/run.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 diff --git a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 b/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 deleted file mode 100644 index 650fc79f6..000000000 --- a/elastic-tube-1d/fluid-fortran/src/FluidComputeSolution.f90 +++ /dev/null @@ -1,182 +0,0 @@ -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 diff --git a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 b/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 deleted file mode 100644 index f2b4485f5..000000000 --- a/elastic-tube-1d/fluid-fortran/src/FluidSolver.f90 +++ /dev/null @@ -1,194 +0,0 @@ -program FluidSolver - use precice - use FluidComputeSolution, only: fluid_compute_solution - use Utilities, only: write_vtk - implicit none - integer, parameter :: dp = kind(1.0d0) ! Double precision - - character(LEN=50) :: configFileName - character(LEN=50) :: solverName - character(LEN=50) :: meshName, pressureName, crossSectionLengthName - character(LEN=50) :: outputFilePrefix - integer :: rank, commsize, ongoing, dimensions, bool - integer :: domainSize, chunkLength - integer :: i, j, info - real(dp) :: dt, t, cellwidth - real(dp), allocatable :: pressure(:), pressure_old(:) - real(dp), allocatable :: crossSectionLength(:), crossSectionLength_old(:) - real(dp), allocatable :: velocity(:), velocity_old(:) - integer, allocatable :: vertexIDs(:) - integer :: out_counter - real(dp), parameter :: PI = 3.141592653589793_dp - real(dp) :: kappa, l - real(dp) :: r0, a0, u0, ampl, frequency, t_shift, p0, vel_in_0 - real(dp), allocatable :: grid(:) - - - write(*, *) 'Fluid: Starting Fortran solver...' - - if (command_argument_count() /= 1) then - write(*, *) "" - write(*, *) "Fluid: Usage: FluidSolver " - stop -1 - end if - - call getarg(1, configFileName) - - solverName = 'Fluid' - outputFilePrefix = './output/out_fluid' - - ! Configure precice - rank = 0 - commsize = 1 - call precicef_create(solverName, configFileName, rank, commsize, len_trim(solverName), len_trim(configFileName)) - write(*, *) "preCICE configured..." - - ! Define mesh and data names - meshName = "Fluid-Nodes-Mesh" - pressureName = "Pressure" - crossSectionLengthName = "CrossSectionLength" - - domainSize = 100 - chunkLength = domainSize + 1 - kappa = 100.0_dp - l = 10.0_dp - - ! Get mesh dimensions - call precicef_get_mesh_dimensions(meshName, dimensions, len_trim(meshName)) - - ! Allocate arrays - allocate(vertexIDs(chunkLength)) - allocate(pressure(chunkLength)) - allocate(pressure_old(chunkLength)) - allocate(crossSectionLength(chunkLength)) - allocate(crossSectionLength_old(chunkLength)) - allocate(velocity(chunkLength)) - allocate(velocity_old(chunkLength)) - allocate(grid(dimensions*chunkLength)) - - ! Initialize physical parameters - r0 = 1.0_dp / sqrt(PI) ! radius of the tube - a0 = r0**2 * PI ! cross-sectional area - u0 = 10.0_dp ! mean velocity - ampl = 3.0_dp ! amplitude of varying velocity - frequency = 10.0_dp ! frequency of variation - t_shift = 0.0_dp ! temporal shift of variation - p0 = 0.0_dp ! pressure at outlet - vel_in_0 = u0 + ampl * sin(frequency * (t_shift) * PI) - - ! Initialize data arrays - pressure = p0 - pressure_old = pressure - crossSectionLength = a0 - crossSectionLength_old = crossSectionLength - velocity = vel_in_0 - velocity_old = velocity - - ! Initialize grid coordinates - cellwidth = l / real(domainSize, dp) - do i = 1, chunkLength - do j = 1, dimensions - if (j == 1) then - grid((i - 1)*dimensions + j) = real(i - 1, dp) * cellwidth - else - grid((i - 1)*dimensions + j) = 0.0_dp - end if - end do - end do - - ! Initialize vertexIDs (0-based IDs) - do i = 1, chunkLength - vertexIDs(i) = i - 1 - end do - - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, len_trim(meshName)) - - ! Check if Initial Data is Required and Write if Necessary - call precicef_requires_initial_data(bool) - if (bool == 1) then - write (*, *) 'Fluid: Writing initial data' - end if - - write (*, *) "Initialize preCICE..." - call precicef_initialize() - - ! read initial cross-Section length - call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, 0.0d0, crossSectionLength, & - len_trim(meshName), len_trim(crossSectionLengthName)) - - ! Copy current cross-Section length to old array - crossSectionLength_old = crossSectionLength - - ! initialize such that mass conservation is fulfilled - do i = 1, chunkLength - velocity_old(i) = vel_in_0*crossSectionLength_old(1)/crossSectionLength_old(i) - end do - - t = 0.0d0 - out_counter = 0 - - ! Main coupling loop - call precicef_is_coupling_ongoing(ongoing) - do while (ongoing /= 0) - ! checkpointing is required in implicit coupling - call precicef_requires_writing_checkpoint(bool) - if (bool .eq. 1) then - ! nothing - end if - - call precicef_get_max_time_step_size(dt) - - ! solve - call fluid_compute_solution( & - velocity_old, pressure_old, crossSectionLength_old, & - crossSectionLength, & - t + dt, & ! used for inlet velocity - domainSize, & - kappa, & - dt, & ! tau - velocity, pressure, & ! resulting velocity pressure - info) - - call precicef_write_data(meshName, pressureName, chunkLength, vertexIDs, pressure, & - len_trim(meshName), len_trim(pressureName)) - - call precicef_advance(dt) - - call precicef_get_max_time_step_size(dt) - - call precicef_read_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, dt, crossSectionLength, & - len_trim(meshName), len_trim(crossSectionLengthName)) - - call precicef_requires_reading_checkpoint(bool) - if (bool .eq. 1) then - ! not yet converged - else - ! converged, advance in time - t = t + dt - - call write_vtk(t, out_counter, outputFilePrefix, chunkLength, grid, velocity, pressure, crossSectionLength) - crossSectionLength_old = crossSectionLength - pressure_old = pressure - velocity_old = velocity - - out_counter = out_counter + 1 - end if - - ! Check if coupling is still ongoing - call precicef_is_coupling_ongoing(ongoing) - end do - - ! finalize precice and deallocate arrays - call precicef_finalize() - write (*, *) 'Exiting FluidSolver' - - deallocate(pressure) - deallocate(pressure_old) - deallocate(crossSectionLength) - deallocate(crossSectionLength_old) - deallocate(velocity) - deallocate(velocity_old) - deallocate(grid) - deallocate(vertexIDs) - -end program FluidSolver diff --git a/elastic-tube-1d/fluid-fortran/src/utilities.f90 b/elastic-tube-1d/fluid-fortran/src/utilities.f90 deleted file mode 100644 index e844e0a64..000000000 --- a/elastic-tube-1d/fluid-fortran/src/utilities.f90 +++ /dev/null @@ -1,74 +0,0 @@ -module Utilities - implicit none - integer, parameter :: dp = kind(1.0D0) -contains - - subroutine write_vtk(t, iteration, filenamePrefix, nSlices, & - grid, velocity, pressure, diameter) - implicit none - - real(dp), intent(IN) :: t - integer, intent(IN) :: iteration - character(LEN=*), intent(IN) :: filenamePrefix - integer, intent(IN) :: nSlices - real(dp), intent(IN) :: grid(:), velocity(:), pressure(:), diameter(:) - - integer :: ioUnit, i, ioStatus - character(LEN=256) :: filename - - write (filename, '(A,"_",I0,".vtk")') trim(filenamePrefix), iteration - print '(A, F7.6, A, A)', 'writing timestep at t=', t, ' to ', trim(filename) - - open (newunit=ioUnit, file=trim(filename), status="replace", action="write", form="formatted", iostat=ioStatus) - if (ioStatus /= 0) then - print *, 'Error: Unable to open file ', trim(filename) - return - end if - - ! Write vtk headers - write (ioUnit, '(A)') '# vtk DataFile Version 2.0' - write (ioUnit, '(A)') '' - write (ioUnit, '(A)') 'ASCII' - write (ioUnit, '(A)') '' - write (ioUnit, '(A)') 'DATASET UNSTRUCTURED_GRID' - write (ioUnit, '(A)') '' - - ! Write points - write (ioUnit, '(A,I0,A)') 'POINTS ', nSlices, ' float' - write (ioUnit, '(A)') '' - do i = 1, nSlices - write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') grid(2*(i - 1) + 1), grid(2*(i - 1) + 2), 0.0D0 - end do - write (ioUnit, '(A)') '' - - write (ioUnit, '(A,I0)') 'POINT_DATA ', nSlices - write (ioUnit, '(A)') '' - - ! Write velocity vector field - write (ioUnit, '(A,A,A)') 'VECTORS ', 'velocity', ' float' - do i = 1, nSlices - write (ioUnit, '(ES24.16,1X,ES24.16,1X,ES24.16)') velocity(i), 0.0D0, 0.0D0 - end do - write (ioUnit, '(A)') '' - - ! Write pressure - write (ioUnit, '(A,A,A)') 'SCALARS ', 'pressure', ' float' - write (ioUnit, '(A)') 'LOOKUP_TABLE default' - do i = 1, nSlices - write (ioUnit, '(ES24.16)') pressure(i) - end do - write (ioUnit, '(A)') '' - - ! Write diameter - write (ioUnit, '(A,A,A)') 'SCALARS ', 'diameter', ' float' - write (ioUnit, '(A)') 'LOOKUP_TABLE default' - do i = 1, nSlices - write (ioUnit, '(ES24.16)') diameter(i) - end do - write (ioUnit, '(A)') '' - - close (ioUnit) - - end subroutine write_vtk - -end module Utilities diff --git a/elastic-tube-1d/solid-fortran/CMakeLists.txt b/elastic-tube-1d/solid-fortran/CMakeLists.txt deleted file mode 100644 index a1be8258f..000000000 --- a/elastic-tube-1d/solid-fortran/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -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}") - -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) - -add_executable(SolidSolver - src/SolidComputeSolution.f90 - src/SolidSolver.f90 - src/precice.f90 -) - -target_link_libraries(SolidSolver PRIVATE precice::precice) diff --git a/elastic-tube-1d/solid-fortran/clean.sh b/elastic-tube-1d/solid-fortran/clean.sh deleted file mode 100755 index ae7a54924..000000000 --- a/elastic-tube-1d/solid-fortran/clean.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -set -e -u - -. ../../tools/cleaning-tools.sh - -clean_precice_logs . -clean_case_logs . diff --git a/elastic-tube-1d/solid-fortran/run.sh b/elastic-tube-1d/solid-fortran/run.sh deleted file mode 100755 index 337bd8c1f..000000000 --- a/elastic-tube-1d/solid-fortran/run.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -e -u - -. ../../tools/log.sh || true -exec > >(tee --append "$LOGFILE") 2>&1 || true - -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 - cd build - cmake .. - cmake --build . - cd .. -fi - -./build/SolidSolver ../precice-config.xml - -close_log diff --git a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 b/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 deleted file mode 100644 index 28aeb72b4..000000000 --- a/elastic-tube-1d/solid-fortran/src/SolidComputeSolution.f90 +++ /dev/null @@ -1,32 +0,0 @@ -module SolidComputeSolution - implicit none - integer, parameter :: dp = kind(1.0d0) - -contains - - subroutine solid_compute_solution(chunkLength, pressure, crossSectionLength) - integer, intent(in) :: chunkLength - real(dp), intent(in) :: pressure(1:chunkLength) - real(dp), intent(inout) :: crossSectionLength(1:chunkLength) - - real(dp) :: pi, e, r0, c_mk, c_mk2 - real(dp) :: pressure0 - integer :: i - - ! constants - pi = 3.141592653589793_dp - e = 10000.0_dp - r0 = 1.0_dp / sqrt(pi) - c_mk = sqrt(e / (2.0_dp * r0)) - c_mk2 = c_mk * c_mk - pressure0 = 0.0_dp - - ! Update crossSectionLength based on pressure - do i = 1, chunkLength - crossSectionLength(i) = ((pressure0 - 2.0_dp * c_mk2)**2) / & - ((pressure(i) - 2.0_dp * c_mk2)**2) - end do - - end subroutine solid_compute_solution - -end module SolidComputeSolution diff --git a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 b/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 deleted file mode 100644 index 86be2925f..000000000 --- a/elastic-tube-1d/solid-fortran/src/SolidSolver.f90 +++ /dev/null @@ -1,117 +0,0 @@ -program SolidSolver - use precice - use SolidComputeSolution, only: solid_compute_solution - implicit none - - integer, parameter :: dp = kind(1.0d0) - - character(len=50) :: configFileName - character(len=50) :: solverName - character(len=50) :: meshName, crossSectionLengthName, pressureName - integer :: rank, commsize, ongoing, dimensions, bool - integer :: domainSize, chunkLength - integer :: i - integer, allocatable :: vertexIDs(:) - real(dp), allocatable :: pressure(:), crossSectionLength(:) - real(dp), allocatable :: grid(:) - real(dp) :: dt, tubeLength, dx - - write(*, *) 'Starting Solid Solver...' - - if (command_argument_count() /= 1) then - write(*, *) 'Solid: Usage: SolidSolver ' - write(*, *) '' - stop -1 - end if - - call get_command_argument(1, configFileName) - - domainSize = 100 - chunkLength = domainSize + 1 - tubeLength = 10.0_dp - - write(*, *) 'N: ', domainSize - write(*, *) 'inputs: ', command_argument_count() - - solverName = 'Solid' - meshName = 'Solid-Nodes-Mesh' - crossSectionLengthName = 'CrossSectionLength' - pressureName = 'Pressure' - - rank = 0 - commsize = 1 - call precicef_create(solverName, configFileName, rank, commsize, & - len_trim(solverName), len_trim(configFileName)) - write(*, *) 'preCICE configured...' - - call precicef_get_mesh_dimensions(meshName, dimensions, & - len_trim(meshName)) - - ! Allocate arrays - allocate(pressure(chunkLength)) - allocate(crossSectionLength(chunkLength)) - allocate(grid(dimensions*chunkLength)) - allocate(vertexIDs(chunkLength)) - - pressure = 0.0_dp - crossSectionLength = 1.0_dp - dx = tubeLength / real(domainSize, dp) - - do i = 1, chunkLength - grid((i - 1)*dimensions + 1) = dx * real(i - 1, dp) ! x-coordinate - grid((i - 1)*dimensions + 2) = 0.0_dp ! y-coordinate - vertexIDs(i) = i - 1 ! 0-based indexing here - end do - - call precicef_set_vertices(meshName, chunkLength, grid, vertexIDs, & - len_trim(meshName)) - - ! Check if initial data is required and write if necessary - call precicef_requires_initial_data(bool) - if (bool == 1) then - call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & - crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) - end if - - write (*, *) 'Initialize preCICE...' - call precicef_initialize() - - ! Coupling loop - call precicef_is_coupling_ongoing(ongoing) - do while (ongoing /= 0) - - call precicef_requires_writing_checkpoint(bool) - if (bool .eq. 1) then - ! Do nothing here - end if - - call precicef_get_max_time_step_size(dt) - - call precicef_read_data(meshName, pressureName, chunkLength, vertexIDs, dt, pressure, & - len_trim(meshName), len_trim(pressureName)) - - call solid_compute_solution(chunkLength, pressure, crossSectionLength) - - call precicef_write_data(meshName, crossSectionLengthName, chunkLength, vertexIDs, & - crossSectionLength, len_trim(meshName), len_trim(crossSectionLengthName)) - - call precicef_advance(dt) - - call precicef_requires_reading_checkpoint(bool) - if (bool .eq. 1) then - ! nothing - end if - - call precicef_is_coupling_ongoing(ongoing) - end do - - write (*, *) 'Exiting SolidSolver' - - call precicef_finalize() - - deallocate(pressure) - deallocate(crossSectionLength) - deallocate(grid) - deallocate(vertexIDs) - -end program SolidSolver From 9be34a65da3ae54a9a5c3fa195be6f10f278ab3e Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 12:08:29 +0100 Subject: [PATCH 32/37] Include fluid-fortran-module results in plots --- elastic-tube-1d/plot-all.sh | 4 +++- elastic-tube-1d/plot-diameter.sh | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/elastic-tube-1d/plot-all.sh b/elastic-tube-1d/plot-all.sh index 26975482d..e0df51d2f 100755 --- a/elastic-tube-1d/plot-all.sh +++ b/elastic-tube-1d/plot-all.sh @@ -14,6 +14,7 @@ gnuplot -p << EOF "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints lw 2 title "python", \ "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "rust", \ "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran" + "fluid-fortran-module/precice-Fluid-watchpoint-Middle.log" using 1:4 with linespoints title "fortran-module" set title 'Pressure of elastic-tube at x=5' set ylabel 'pressure' @@ -22,6 +23,7 @@ gnuplot -p << EOF "fluid-python/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "python", \ "fluid-rust/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "rust", \ "fluid-fortran/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran" - + "fluid-fortran-module/precice-Fluid-watchpoint-Middle.log" using 1:5 with linespoints title "fortran-module" + set xlabel 'time [s]' EOF diff --git a/elastic-tube-1d/plot-diameter.sh b/elastic-tube-1d/plot-diameter.sh index 059eba585..4f7c30d4e 100755 --- a/elastic-tube-1d/plot-diameter.sh +++ b/elastic-tube-1d/plot-diameter.sh @@ -29,4 +29,11 @@ if [ -n "$(ls -A ./fluid-fortran/output/*.vtk 2>/dev/null)" ]; then python3 plot-vtk.py diameter fluid-fortran/output/out_fluid_ & else echo "No results to plot from fluid-fortran." +fi + +# Plot diameter from fluid-fortran-module +if [ -n "$(ls -A ./fluid-fortran-module/output/*.vtk 2>/dev/null)" ]; then + python3 plot-vtk.py diameter fluid-fortran-module/output/out_fluid_ & +else + echo "No results to plot from fluid-fortran-module." fi \ No newline at end of file From 3f5b6c6e08b328ba676d287613ffcd62d20ee2b2 Mon Sep 17 00:00:00 2001 From: YonatanGM Date: Wed, 29 Jan 2025 12:20:52 +0100 Subject: [PATCH 33/37] Update plot-all image --- .../images/tutorials-elastic-tube-1d-all.png | Bin 92186 -> 81114 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/elastic-tube-1d/images/tutorials-elastic-tube-1d-all.png b/elastic-tube-1d/images/tutorials-elastic-tube-1d-all.png index 021ee2dfef8e1019b69477f8b8e5b6af8a8a7d90..0aaf61182f4b79dfe0980cb68beaa93e3b1580e8 100644 GIT binary patch literal 81114 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