From ee7bcdc02d68e04d5436e5e87f4acf5417633409 Mon Sep 17 00:00:00 2001 From: dreamer2368 Date: Thu, 15 Dec 2022 13:10:18 -0600 Subject: [PATCH] LevelsetFactory: abstract interface for various levelsets. --- CMakeLists.txt | 3 + include/ImmersedBoundaryPatch.f90 | 8 -- include/LevelsetFactory.f90 | 64 ++++++++++++++ include/Region.f90 | 16 ++++ include/SinusoidalWallLevelset.f90 | 73 ++++++++++++++++ include/State.f90 | 23 +---- src/ImmersedBoundaryImpl.f90 | 112 ++---------------------- src/RegionImpl.f90 | 40 +++++++++ src/SinusoidalWallLevelsetImpl.f90 | 133 +++++++++++++++++++++++++++++ src/SolverImpl.f90 | 6 +- src/StateImpl.f90 | 6 +- utils/rhs.f90 | 7 +- 12 files changed, 344 insertions(+), 147 deletions(-) create mode 100644 include/LevelsetFactory.f90 create mode 100644 include/SinusoidalWallLevelset.f90 create mode 100644 src/SinusoidalWallLevelsetImpl.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index d58ba959..37b29068 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,6 +161,7 @@ set(magudiObj_SOURCES ${PROJECT_SOURCE_DIR}/include/ReverseMigrator.f90 ${PROJECT_SOURCE_DIR}/src/ReverseMigratorImpl.f90 ${PROJECT_SOURCE_DIR}/include/MappingFunction.f90 + ${PROJECT_SOURCE_DIR}/include/LevelsetFactory.f90 # Extended types. ${PROJECT_SOURCE_DIR}/include/RK4Integrator.f90 @@ -213,6 +214,8 @@ set(magudiObj_SOURCES ${PROJECT_SOURCE_DIR}/src/KolmogorovForcingPatchImpl.f90 ${PROJECT_SOURCE_DIR}/include/ImmersedBoundaryPatch.f90 ${PROJECT_SOURCE_DIR}/src/ImmersedBoundaryImpl.f90 + ${PROJECT_SOURCE_DIR}/include/SinusoidalWallLevelset.f90 + ${PROJECT_SOURCE_DIR}/src/SinusoidalWallLevelsetImpl.f90 # C source files. ${PROJECT_SOURCE_DIR}/src/PLOT3DFormat.c diff --git a/include/ImmersedBoundaryPatch.f90 b/include/ImmersedBoundaryPatch.f90 index 9cfa3153..38cd0c31 100644 --- a/include/ImmersedBoundaryPatch.f90 +++ b/include/ImmersedBoundaryPatch.f90 @@ -16,7 +16,6 @@ module ImmersedBoundaryPatch_mod procedure, pass :: cleanup => cleanupImmersedBoundaryPatch procedure, pass :: verifyUsage => verifyImmersedBoundaryPatchUsage procedure, pass :: updateRhs => addImmersedBoundaryPenalty - procedure, pass :: updateLevelset => addImmersedBoundaryLevelset end type t_ImmersedBoundaryPatch interface @@ -77,11 +76,4 @@ subroutine addImmersedBoundaryPenalty(this, mode, simulationFlags, solverOptions end subroutine addImmersedBoundaryPenalty end interface - interface - subroutine addImmersedBoundaryLevelset(this) - import :: t_ImmersedBoundaryPatch - class(t_ImmersedBoundaryPatch) :: this - end subroutine addImmersedBoundaryLevelset - end interface - end module ImmersedBoundaryPatch_mod diff --git a/include/LevelsetFactory.f90 b/include/LevelsetFactory.f90 new file mode 100644 index 00000000..4365f79c --- /dev/null +++ b/include/LevelsetFactory.f90 @@ -0,0 +1,64 @@ +#include "config.h" + +module LevelsetFactory_mod + + implicit none + + type, abstract, public :: t_LevelsetFactory + + contains + + procedure(setup), pass, deferred :: setup + procedure(cleanup), pass, deferred :: cleanup + procedure(updateLevelset), pass, deferred :: updateLevelset + + end type t_LevelsetFactory + + abstract interface + + subroutine setup(this, grids, states) + + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + import :: t_LevelsetFactory + + class(t_LevelsetFactory) :: this + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + end subroutine setup + + end interface + + abstract interface + + subroutine cleanup(this) + + import :: t_LevelsetFactory + + class(t_LevelsetFactory) :: this + + end subroutine cleanup + + end interface + + abstract interface + + subroutine updateLevelset(this, mode, grids, states) + + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + import :: t_LevelsetFactory + + class(t_LevelsetFactory) :: this + integer, intent(in) :: mode + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + end subroutine updateLevelset + + end interface + +end module LevelsetFactory_mod diff --git a/include/Region.f90 b/include/Region.f90 index 0093dfc2..7010b3cb 100644 --- a/include/Region.f90 +++ b/include/Region.f90 @@ -22,6 +22,7 @@ module Region_mod use SolverOptions_mod, only : t_SolverOptions use PatchDescriptor_mod, only : t_PatchDescriptor use SimulationFlags_mod, only : t_SimulationFlags + use LevelsetFactory_mod, only : t_LevelsetFactory implicit none @@ -33,6 +34,7 @@ module Region_mod type(t_SolverOptions) :: solverOptions type(t_SimulationFlags) :: simulationFlags type(t_PatchDescriptor), allocatable :: patchData(:) + class(t_LevelsetFactory), pointer :: levelsetFactory => null() integer :: comm = MPI_COMM_NULL, commGridMasters = MPI_COMM_NULL, timestep = 0 integer, allocatable :: globalGridSizes(:,:), processDistributions(:,:), & gridCommunicators(:), patchCommunicators(:), patchInterfaces(:), & @@ -40,6 +42,7 @@ module Region_mod logical :: outputOn = .true. SCALAR_TYPE :: initialXmomentum, oneOverVolume, momentumLossPerVolume, & adjointMomentumLossPerVolume + character(len=STRING_LENGTH) :: levelsetType contains @@ -55,6 +58,7 @@ module Region_mod procedure, pass :: saveSpongeStrength procedure, pass :: resetProbes procedure, pass :: saveProbeData + procedure, pass :: connectLevelsetFactory end type t_Region @@ -227,4 +231,16 @@ end subroutine saveProbeData end interface + interface + + subroutine connectLevelsetFactory(this) + + import :: t_Region + + class(t_Region) :: this + + end subroutine connectLevelsetFactory + + end interface + end module Region_mod diff --git a/include/SinusoidalWallLevelset.f90 b/include/SinusoidalWallLevelset.f90 new file mode 100644 index 00000000..9002810b --- /dev/null +++ b/include/SinusoidalWallLevelset.f90 @@ -0,0 +1,73 @@ +#include "config.h" + +module SinusoidalWallLevelset_mod + + use LevelsetFactory_mod, only : t_LevelsetFactory + + implicit none + + type, private :: t_SWInternal + SCALAR_TYPE, allocatable :: buffer(:) + end type t_SWInternal + + type, extends(t_LevelsetFactory), public :: t_SinusoidalWallLevelset + + type(t_SWInternal), dimension(:), allocatable :: wallShapes + real(SCALAR_KIND) :: levelsetLoc, levelsetWidth, levelsetAmp, levelsetPeriod + + contains + + procedure, pass :: setup => setupSinusoidalWallLevelset + procedure, pass :: cleanup => cleanupSinusoidalWallLevelset + procedure, pass :: updateLevelset => updateSinusoidalWallLevelset + + end type t_SinusoidalWallLevelset + + interface + + subroutine setupSinusoidalWallLevelset(this, grids, states) + + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + import :: t_SinusoidalWallLevelset + + class(t_SinusoidalWallLevelset) :: this + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + end subroutine setupSinusoidalWallLevelset + + end interface + + interface + + subroutine cleanupSinusoidalWallLevelset(this) + + import :: t_SinusoidalWallLevelset + + class(t_SinusoidalWallLevelset) :: this + + end subroutine cleanupSinusoidalWallLevelset + + end interface + + interface + + subroutine updateSinusoidalWallLevelset(this, mode, grids, states) + + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + import :: t_SinusoidalWallLevelset + + class(t_SinusoidalWallLevelset) :: this + integer, intent(in) :: mode + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + end subroutine updateSinusoidalWallLevelset + + end interface + +end module SinusoidalWallLevelset_mod diff --git a/include/State.f90 b/include/State.f90 index be766936..db0873e5 100644 --- a/include/State.f90 +++ b/include/State.f90 @@ -64,7 +64,7 @@ end function getNumberOfScalars ! Variables for immersed boundary method. real(SCALAR_KIND), dimension(:,:), allocatable :: levelset, levelsetNormal!, indicatorFunction, & !primitiveGridNorm, levelsetCurvature - real(SCALAR_KIND), dimension(:), allocatable :: wallShape, objectSpeed + real(SCALAR_KIND), dimension(:,:), allocatable :: objectVelocity real(SCALAR_KIND) :: levelsetLoc, levelsetWidth, levelsetAmp, levelsetPeriod real(SCALAR_KIND), dimension(:,:), allocatable :: ibmDissipation, nDotGradRho, uDotGradRho @@ -82,8 +82,6 @@ end function getNumberOfScalars procedure, pass :: computeTimeStepSize => computeStateTimeStepSize procedure, pass :: addSources procedure, pass :: updateIBMVariables - procedure, pass :: setupLevelset - procedure, pass :: updateLevelset end type t_State @@ -275,23 +273,4 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) end subroutine updateIBMVariables end interface - interface - subroutine setupLevelset(this, grid) - use Grid_mod, only : t_Grid - import :: t_State - class(t_State) :: this - class(t_Grid), intent(in) :: grid - end subroutine setupLevelset - end interface - - interface - subroutine updateLevelset(this, mode, grid) - use Grid_mod, only : t_Grid - import :: t_State - class(t_State) :: this - integer, intent(in) :: mode - class(t_Grid), intent(in) :: grid - end subroutine updateLevelset - end interface - end module State_mod diff --git a/src/ImmersedBoundaryImpl.f90 b/src/ImmersedBoundaryImpl.f90 index 181c83dc..dd15d4af 100644 --- a/src/ImmersedBoundaryImpl.f90 +++ b/src/ImmersedBoundaryImpl.f90 @@ -216,8 +216,7 @@ subroutine addImmersedBoundaryPenalty(this, mode, simulationFlags, solverOptions localLevelsetNormal = state%levelsetNormal(gridIndex, :) ! Get velocity of associated object - !TODO: include tangential component of the object velocity. - objectVelocity = state%objectSpeed(gridIndex) * localLevelsetNormal + objectVelocity = state%objectVelocity(gridIndex, :) ! if (ibm_move) then ! n = objectIndex(i) ! objectVelocity = object(n)%velocity(1:nDimensions) @@ -266,11 +265,6 @@ subroutine addImmersedBoundaryPenalty(this, mode, simulationFlags, solverOptions end do !... k = this%offset(3) + 1, this%offset(3) + this%localSize(3) end subroutine addImmersedBoundaryPenalty -subroutine addImmersedBoundaryLevelset(this) - use ImmersedBoundaryPatch_mod, only : t_ImmersedBoundaryPatch - class(t_ImmersedBoundaryPatch) :: this -end subroutine addImmersedBoundaryLevelset - ! t_State method subroutine updateIBMVariables(this, mode, grid, simulationFlags) @@ -297,7 +291,7 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) integer, parameter :: wp = SCALAR_KIND real(wp), parameter :: pi = 4.0_wp * atan(1.0_wp) integer :: i, j, n, nUnknowns - real(wp) :: buf, timeDerivativeFactor, objectVelocity(grid%nDimensions) + real(wp) :: buf real(wp), dimension(:, :), allocatable :: densityGradient, dissipationTerm call startTiming("updateIBMVariables") @@ -314,24 +308,8 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) allocate(densityGradient(grid%nGridPoints, grid%nDimensions)) allocate(dissipationTerm(grid%nGridPoints, nUnknowns)) - ! compute levelset. - call this%updateLevelset(mode, grid) - timeDerivativeFactor = 2.0_wp * pi / this%levelsetPeriod * cos(2.0_wp * pi * this%time / this%levelsetPeriod) - - ! compute levelset normal. - call grid%computeGradient(this%levelset(:, 1), this%levelsetNormal) - - do i = 1, grid%nGridPoints - ! levelset normal magnitude - buf = sqrt(sum(this%levelsetNormal(i,:) ** 2)) - - !TODO: include tangential component of the object velocity. - ! d/dt levelset = - wallShape * d/dt timeFactor - this%objectSpeed(i) = timeDerivativeFactor * this%wallShape(i) / buf - - ! Make the levelset normal a unit norm - if (buf .gt. 0.0_wp) this%levelsetNormal(i,:) = this%levelsetNormal(i,:) / buf - + !NOTE: remnant from jcode. + ! do i = 1, grid%nGridPoints ! ! Compute indicator function ! if (levelset(i, 1) .le. 0.0_wp) then ! indicatorFunction(i, 1) = 0.0_wp @@ -341,7 +319,7 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) ! ! ! Update the grid norm ! gridNorm(i, 1) = primitiveGridNorm(i, 1) * indicatorFunction(i, 1) - end do + ! end do this%nDotGradRho = 0.0_wp this%uDotGradRho = 0.0_wp @@ -349,10 +327,8 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) call grid%computeGradient(this%conservedVariables(:,1), densityGradient) do i = 1, grid%nGridPoints - objectVelocity = this%objectSpeed(i) * this%levelsetNormal(i, :) - this%nDotGradRho(i, 1) = this%nDotGradRho(i, 1) + sum(this%levelsetNormal(i, :) * densityGradient(i, :)) - this%uDotGradRho(i, 1) = this%uDotGradRho(i, 1) + sum(objectVelocity * densityGradient(i, :)) + this%uDotGradRho(i, 1) = this%uDotGradRho(i, 1) + sum(this%objectVelocity(i, :) * densityGradient(i, :)) end do do n = 1, grid%nDimensions @@ -375,79 +351,3 @@ subroutine updateIBMVariables(this, mode, grid, simulationFlags) call endTiming("updateIBMVariables") end subroutine updateIBMVariables - -subroutine setupLevelset(this, grid) - - ! <<< Derived types >>> - use Grid_mod, only : t_Grid - use State_mod, only : t_State - - ! <<< Internal modules >>> - use InputHelper, only : getRequiredOption - - implicit none - - ! <<< Arguments >>> - class(t_State) :: this - class(t_Grid) :: grid - - ! <<< Local variables >>> - integer, parameter :: wp = SCALAR_KIND - real(wp), parameter :: pi = 4.0_wp * atan(1.0_wp) - integer :: i, n - - call getRequiredOption("immersed_boundary/location", this%levelsetLoc, grid%comm) - call getRequiredOption("immersed_boundary/width", this%levelsetWidth, grid%comm) - call getRequiredOption("immersed_boundary/amplitude", this%levelsetAmp, grid%comm) - call getRequiredOption("immersed_boundary/period", this%levelsetPeriod, grid%comm) - - this%wallShape = 0.0_wp - do i = 1, grid%nGridPoints - if ((grid%coordinates(i, 1) < (this%levelsetLoc - 0.5_wp * this%levelsetWidth)) .or. & - (grid%coordinates(i, 1) > (this%levelsetLoc + 0.5_wp * this%levelsetWidth))) cycle - this%wallShape(i) = 0.5_wp + 0.5_wp * cos(2.0_wp * pi * (grid%coordinates(i, 1) - this%levelsetLoc) / this%levelsetWidth) - end do - - this%wallShape = this%wallShape * this%levelsetAmp - -end subroutine setupLevelset - -subroutine updateLevelset(this, mode, grid) - - ! <<< Derived types >>> - use Grid_mod, only : t_Grid - use State_mod, only : t_State - - ! <<< Enumerations >>> - use Region_enum, only : FORWARD - - ! <<< Internal modules >>> - use MPITimingsHelper, only : startTiming, endTiming - - implicit none - - ! <<< Arguments >>> - class(t_State) :: this - integer, intent(in) :: mode - class(t_Grid), intent(in) :: grid - - ! <<< Local variables >>> - integer, parameter :: wp = SCALAR_KIND - real(wp), parameter :: pi = 4.0_wp * atan(1.0_wp) - real(wp) :: timeFactor - - call startTiming("updateLevelset") - - if (mode .ne. FORWARD) then - return - end if - - assert(size(this%levelset, 1) == size(this%conservedVariables, 1)) - assert(size(this%levelset, 2) == 1) - - timeFactor = sin(2.0_wp * pi * this%time / this%levelsetPeriod) - this%levelset(:, 1) = grid%coordinates(:, 2) - this%wallShape * timeFactor - - call endTiming("updateLevelset") - -end subroutine updateLevelset diff --git a/src/RegionImpl.f90 b/src/RegionImpl.f90 index 84933e0f..2f7f322d 100644 --- a/src/RegionImpl.f90 +++ b/src/RegionImpl.f90 @@ -1148,6 +1148,11 @@ subroutine cleanupRegion(this) end if SAFE_DEALLOCATE(this%states) + if (this%simulationFlags%enableIBM) then + call this%levelsetFactory%cleanup() + nullify(this%levelsetFactory) + end if + if (allocated(this%patchFactories)) then do i = 1, size(this%patchFactories) call this%patchFactories(i)%connect(patch) @@ -1747,6 +1752,7 @@ subroutine computeRhs(this, mode, timeStep, stage) ! Update immersed boundary variables. if (this%simulationFlags%enableIBM) then + call this%levelsetFactory%updateLevelset(mode, this%grids, this%states) do i = 1, size(this%states) call this%states(i)%updateIBMVariables(mode, this%grids(i), this%simulationFlags) end do @@ -2040,3 +2046,37 @@ subroutine saveProbeData(this, mode, finish) end do end subroutine saveProbeData + +subroutine connectLevelsetFactory(this) + + ! <<< Derived types >>> + use Region_mod, only : t_Region + use LevelsetFactory_mod, only : t_LevelsetFactory + use SinusoidalWallLevelset_mod, only : t_SinusoidalWallLevelset + + ! <<< Internal modules >>> + use InputHelper, only : getRequiredOption + + implicit none + + ! <<< Arguments >>> + class(t_Region) :: this + + ! <<< Local variables >>> + character(len = STRING_LENGTH) :: levelsetType + + call getRequiredOption("immersed_boundary/levelset_type", levelsetType, this%comm) + + this%levelsetType = levelsetType + + select case (trim(levelsetType)) + + case ('sinusoidal_wall') + allocate(t_SinusoidalWallLevelset :: this%levelsetFactory) + + case default + this%levelsetType = "" + + end select + +end subroutine connectLevelsetFactory diff --git a/src/SinusoidalWallLevelsetImpl.f90 b/src/SinusoidalWallLevelsetImpl.f90 new file mode 100644 index 00000000..66d37730 --- /dev/null +++ b/src/SinusoidalWallLevelsetImpl.f90 @@ -0,0 +1,133 @@ +#include "config.h" + +subroutine setupSinusoidalWallLevelset(this, grids, states) + + ! <<< Derived types >>> + use SinusoidalWallLevelset_mod, only : t_SinusoidalWallLevelset + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + ! <<< Internal modules >>> + use InputHelper, only : getRequiredOption + + implicit none + + ! <<< Arguments >>> + class(t_SinusoidalWallLevelset) :: this + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + ! <<< Local variables >>> + integer, parameter :: wp = SCALAR_KIND + real(wp), parameter :: pi = 4.0_wp * atan(1.0_wp) + integer :: i, n + + call this%cleanup() + + assert(size(states) == size(grids)) + allocate(this%wallShapes(size(grids))) + do i = 1, size(grids) + allocate(this%wallShapes(i)%buffer(grids(i)%nGridPoints)) + end do + + call getRequiredOption("immersed_boundary/location", this%levelsetLoc, grids(1)%comm) + call getRequiredOption("immersed_boundary/width", this%levelsetWidth, grids(1)%comm) + call getRequiredOption("immersed_boundary/amplitude", this%levelsetAmp, grids(1)%comm) + call getRequiredOption("immersed_boundary/period", this%levelsetPeriod, grids(1)%comm) + + do n = 1, size(grids) + this%wallShapes(n)%buffer = 0.0_wp + do i = 1, grids(n)%nGridPoints + if ((grids(n)%coordinates(i, 1) < (this%levelsetLoc - 0.5_wp * this%levelsetWidth)) .or. & + (grids(n)%coordinates(i, 1) > (this%levelsetLoc + 0.5_wp * this%levelsetWidth))) cycle + this%wallShapes(n)%buffer(i) = 0.5_wp + 0.5_wp * cos(2.0_wp * pi * (grids(n)%coordinates(i, 1) - this%levelsetLoc) / this%levelsetWidth) + end do + this%wallShapes(n)%buffer = this%wallShapes(n)%buffer * this%levelsetAmp + end do + +end subroutine setupSinusoidalWallLevelset + +subroutine cleanupSinusoidalWallLevelset(this) + + ! <<< Derived types >>> + use SinusoidalWallLevelset_mod, only : t_SinusoidalWallLevelset + + ! <<< Arguments >>> + class(t_SinusoidalWallLevelset) :: this + + ! <<< Local variables >>> + integer :: i + + if (allocated(this%wallShapes)) then + do i = 1, size(this%wallShapes) + SAFE_DEALLOCATE(this%wallShapes(i)%buffer) + end do + SAFE_DEALLOCATE(this%wallShapes) + end if + +end subroutine cleanupSinusoidalWallLevelset + +subroutine updateSinusoidalWallLevelset(this, mode, grids, states) + + ! <<< Derived types >>> + use SinusoidalWallLevelset_mod, only : t_SinusoidalWallLevelset + use Grid_mod, only : t_Grid + use State_mod, only : t_State + + ! <<< Enumerations >>> + use Region_enum, only : FORWARD + + ! <<< Internal modules >>> + use MPITimingsHelper, only : startTiming, endTiming + + implicit none + + ! <<< Arguments >>> + class(t_SinusoidalWallLevelset) :: this + integer, intent(in) :: mode + class(t_Grid), intent(in) :: grids(:) + class(t_State) :: states(:) + + ! <<< Local variables >>> + integer, parameter :: wp = SCALAR_KIND + real(wp), parameter :: pi = 4.0_wp * atan(1.0_wp) + real(wp) :: timeFactor, timeDerivativeFactor, buf, objectSpeed + integer :: i, j + + call startTiming("updateSinusoidalWallLevelset") + + if (mode .ne. FORWARD) then + return + end if + + timeFactor = sin(2.0_wp * pi * states(1)%time / this%levelsetPeriod) + timeDerivativeFactor = 2.0_wp * pi / this%levelsetPeriod * cos(2.0_wp * pi * states(1)%time / this%levelsetPeriod) + + do i = 1, size(states) + assert(size(states(i)%levelset, 1) == size(states(i)%conservedVariables, 1)) + assert(size(states(i)%levelset, 2) == 1) + assert(size(states(i)%levelset, 1) == size(this%wallShapes(i)%buffer)) + + states(i)%levelset(:, 1) = grids(i)%coordinates(:, 2) & + - this%wallShapes(i)%buffer * timeFactor + + ! compute levelset normal. + call grids(i)%computeGradient(states(i)%levelset(:, 1), states(i)%levelsetNormal) + + do j = 1, grids(i)%nGridPoints + ! levelset normal magnitude + buf = sqrt(sum(states(i)%levelsetNormal(j,:) ** 2)) + + ! d/dt levelset = - wallShape * d/dt timeFactor + objectSpeed = timeDerivativeFactor * this%wallShapes(i)%buffer(j) / buf + + ! Make the levelset normal a unit norm + if (buf .gt. 0.0_wp) states(i)%levelsetNormal(j,:) = states(i)%levelsetNormal(j,:) / buf + + states(i)%objectVelocity(j,:) = objectSpeed * states(i)%levelsetNormal(j,:) + end do + end do + + call endTiming("updateSinusoidalWallLevelset") + +end subroutine updateSinusoidalWallLevelset diff --git a/src/SolverImpl.f90 b/src/SolverImpl.f90 index de12c949..ae70cb17 100644 --- a/src/SolverImpl.f90 +++ b/src/SolverImpl.f90 @@ -587,9 +587,9 @@ subroutine setupSolver(this, region, restartFilename, outputPrefix) call gracefulExit(region%comm, message) end if - do i = 1, size(region%states) - call region%states(i)%setupLevelset(region%grids(i)) - end do + call region%connectLevelsetFactory() + + call region%levelsetFactory%setup(region%grids, region%states) ! Determine minimum grid spacing (avoid holes) do i = 1, size(region%grids) diff --git a/src/StateImpl.f90 b/src/StateImpl.f90 index a0e0e7ac..79e00ef3 100644 --- a/src/StateImpl.f90 +++ b/src/StateImpl.f90 @@ -63,8 +63,7 @@ subroutine allocateData(this, simulationFlags, solverOptions, nGridPoints, nDime allocate(this%ibmDissipation(nGridPoints, solverOptions%nUnknowns)) allocate(this%nDotGradRho(nGridPoints, 1)) allocate(this%uDotGradRho(nGridPoints, 1)) - allocate(this%wallShape(nGridPoints)) - allocate(this%objectSpeed(nGridPoints)) + allocate(this%objectVelocity(nGridPoints, nDimensions)) end if end subroutine allocateData @@ -190,8 +189,7 @@ subroutine cleanupState(this) SAFE_DEALLOCATE(this%ibmDissipation) SAFE_DEALLOCATE(this%nDotGradRho) SAFE_DEALLOCATE(this%uDotGradRho) - SAFE_DEALLOCATE(this%wallShape) - SAFE_DEALLOCATE(this%objectSpeed) + SAFE_DEALLOCATE(this%objectVelocity) this%adjointForcingFactor = 1.0_wp diff --git a/utils/rhs.f90 b/utils/rhs.f90 index 78430f5e..8b6a9506 100644 --- a/utils/rhs.f90 +++ b/utils/rhs.f90 @@ -216,14 +216,13 @@ subroutine saveRhs(region, filename) ! resize the data buffer. do i = 1, size(data_) deallocate(data_(i)%buffer) - allocate(data_(i)%buffer(region%grids(i)%nGridPoints, region%grids(i)%nDimensions + 3)) + allocate(data_(i)%buffer(region%grids(i)%nGridPoints, 1 + 2 * region%grids(i)%nDimensions)) end do do j = 1, size(region%states) data_(j)%buffer(:, 1) = region%states(j)%levelset(:, 1) - data_(j)%buffer(:, 2) = region%states(j)%objectSpeed - data_(j)%buffer(:, 3) = region%states(j)%wallShape - data_(j)%buffer(:, 4:region%grids(j)%nDimensions + 3) = region%states(j)%levelsetNormal + data_(j)%buffer(:, 2:region%grids(j)%nDimensions + 1) = region%states(j)%levelsetNormal + data_(j)%buffer(:, region%grids(j)%nDimensions + 2 : 2 * region%grids(j)%nDimensions + 1) = region%states(j)%objectVelocity region%states(j)%dummyFunction => data_(j)%buffer end do