Skip to content

Commit ebbf142

Browse files
Merge pull request #334 from FluidityProject/parallel-non-extruded-ocean-boundaries
Parallel non extruded ocean boundaries
2 parents 30f7917 + cee0329 commit ebbf142

29 files changed

+3819
-252
lines changed

assemble/Adapt_State.F90

+6-8
Original file line numberDiff line numberDiff line change
@@ -1235,19 +1235,17 @@ subroutine adapt_state_internal(states, metric, initialise_fields)
12351235
call profiler_tic("find_particles_mesh_adapt")
12361236
do j = 1, size(detector_list_array)
12371237
call search_for_detectors(detector_list_array(j)%ptr, new_positions)
1238-
end do
1239-
call profiler_toc("find_particles_mesh_adapt")
1240-
#ifdef DDEBUG
1241-
! Sanity check that all local detectors are owned
1242-
call get_registered_detector_lists(detector_list_array)
1243-
do j = 1, size(detector_list_array)
1238+
1239+
! Sanity check that all local detectors are owned
12441240
detector=>detector_list_array(j)%ptr%first
12451241
do k = 1, detector_list_array(j)%ptr%length
1246-
assert(detector%element>0)
1242+
if (detector%element<=0) then
1243+
FLAbort("Lost one of the detectors during an adapt")
1244+
end if
12471245
detector=>detector%next
12481246
end do
12491247
end do
1250-
#endif
1248+
call profiler_toc("find_particles_mesh_adapt")
12511249
end if
12521250

12531251
! Then reallocate all fields

assemble/Discrete_Properties.F90

+1-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ subroutine enforce_discrete_properties(states, only_prescribed, exclude_interpol
5858
type(state_type) :: alg_state
5959

6060
integer :: state, state_cnt, mesh_i
61-
integer :: mesh_cnt
6261

6362
character(len=255), dimension(1), parameter :: algorithms = (/&
6463
& "solenoidal" /)
@@ -71,7 +70,6 @@ subroutine enforce_discrete_properties(states, only_prescribed, exclude_interpol
7170

7271
ewrite(1, *) "In enforce_discrete_properties"
7372

74-
mesh_cnt = option_count("/geometry/mesh")
7573
alg_cnt = size(algorithms)
7674
state_cnt = size(states)
7775

@@ -85,7 +83,7 @@ subroutine enforce_discrete_properties(states, only_prescribed, exclude_interpol
8583
! only actually care about one algorithm at the moment but for futureproofing we'll do this in a loop
8684
ewrite(2, *) " Considering algorithm " // trim(algorithms(alg))
8785

88-
do mesh_i = 1, mesh_cnt
86+
do mesh_i = 1, mesh_count(states(state))
8987
mesh => extract_mesh(states(state), mesh_i)
9088
call insert(alg_state, mesh, name=trim(mesh%name))
9189
end do

assemble/Free_Surface.F90

+17-17
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ module free_surface_module
4545
use state_module
4646
use sparse_matrices_fields
4747
use boundary_conditions
48-
use vertical_extrapolation_module
4948
use halos
5049
use field_options
50+
use vertical_extrapolation_module
5151
use physics_from_options
5252
use coordinates
5353
use tidal_module, only: calculate_diagnostic_equilibrium_pressure
@@ -223,25 +223,28 @@ subroutine add_free_surface_to_cmc_projection(state, cmc, dt, &
223223
!!< that weakly enforces the kinematic boundary condition.
224224
!!<
225225
!!< The free surface is combined in with the pressure field such that
226-
!!< *at* the free surface p=g rho0 \eta. This has the advantage of combining
226+
!!< *at* the free surface p=g \Delta rho \eta. This has the advantage of combining
227227
!!< the pressure gradient and free surface gradient terms in the momentum
228228
!!< equation. It solves the continuity equation directly coupled with
229229
!!< the free surface.
230-
!!< With this approach all pressures are considered at the integer time
230+
!!< With this approach all pressures are considered at the integer time
231231
!!< levels, i.e. we apply a theta weighting for the pressure gradient term
232232
!!< in the momentum equation:
233-
!!< M (u^n+1-u^n) - dt C p^{n+theta_pressure_gradient} + ... = 0
233+
!!< M (u^n+1-u^n) - dt C p^{n+theta_pg} + ... = 0
234234
!!< We're solving the continuity equation:
235-
!!< C^T u^{n+theta_divergence}+ M_fs p^{n+1}-p^n = 0
235+
!!< C^T u^{n+theta_div}+ alpha M_fs p^{n+1}-p^n = 0
236236
!!< which leads to a projection equation of:
237-
!!< ( C^T M^-1 C dt dp + coef M_fs ) phi =
238-
!!< theta_divergence C^T u* + (1-theta_divergence) C^T u^n -
237+
!!< ( C^T M^-1 C dt dp + coef M_fs ) phi =
238+
!!< theta_div C^T u* + (1-theta_div) C^T u^n -
239239
!!< alpha M_fs (p*-p^n)
240-
!!< where M_fs is the free surface integral of M_i M_j,
241-
!!< alpha=1/(g dt), coef=alpha/(theta_divergence theta_pressure_gradient dt)
242-
!!< and phi=dp theta_divergence theta_pressure_gradient dt. Note however,
243-
!!< that dp in the routine stands for phi, see correct_pressure in
244-
!!< Momentum_Equation.F90
240+
!!< where M_fs is the free surface integral of M_i M_j,
241+
!!< alpha=1/(g dt), coef=alpha/(theta_div theta_pg dt)
242+
!!< and phi=dp theta_div theta_pg dt and dp=p^n+1-p^*
243+
!!< Notes:
244+
!!< - the above is slightly misleading because with a prognostic f.s. we only apply theta weighting
245+
!!< to the free surface (not interior pressure), but for the purposes of this routine we can ignore that
246+
!!< - the above assumes \Delta rho=1 but should be included in alpha M_fs (divided by). For
247+
!!< this will be included in the mass matrix, otherwise we apply it as an overall factor 1/\Delta rho
245248

246249
type(state_type), intent(inout) :: state
247250
type(csr_matrix), intent(inout) :: cmc
@@ -413,10 +416,6 @@ subroutine add_free_surface_to_cmc_projection(state, cmc, dt, &
413416
else
414417
delta_rho = rho0
415418
end if
416-
if (move_mesh .and. delta_rho/=1.0) then
417-
! Someone needs to go through the maths to see where we should divide by delta_rho
418-
FLExit("Free surface with a density difference that is not 1.0 and mesh movement not supported")
419-
end if
420419

421420
alpha=1.0/g/dt ! delta_rho included in alpha and coeff within element loop
422421
coef = alpha/(theta_pressure_gradient*theta_divergence*dt)
@@ -570,9 +569,10 @@ subroutine add_free_surface_element(surface_mesh_ele, sele)
570569
end if
571570

572571
if(present(rhs)) then
572+
assert(.not. variable_density)
573573
call addto(rhs, nodes, &
574574
-(matmul(mass_ele, top_pressures) &
575-
-matmul(mass_ele_old, old_top_pressures))*alpha)
575+
-matmul(mass_ele_old, old_top_pressures))*alpha/delta_rho)
576576
end if
577577
if (have_wd .and. present(rhs)) then
578578
call addto(rhs, nodes, &

assemble/Geostrophic_Pressure.F90

+1-1
Original file line numberDiff line numberDiff line change
@@ -2428,7 +2428,7 @@ subroutine initialise_geostrophic_interpolation_states(old_states, new_states)
24282428
type(vector_field), pointer :: new_velocity, old_velocity
24292429

24302430
do i = 1, size(new_states)
2431-
do j = 1, vector_field_count(old_states(i))
2431+
do j = 1, vector_field_count(new_states(i))
24322432
new_velocity => extract_vector_field(new_states(i), j)
24332433
if(have_option(trim(complete_field_path(new_velocity%option_path, stat = stat)) // "/geostrophic_interpolation")) then
24342434
old_velocity => extract_vector_field(old_states(i), new_velocity%name)

femtools/Boundary_Conditions.F90

+87-17
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,16 @@ module boundary_conditions
8383
end interface extract_scalar_surface_field
8484

8585
interface has_surface_field
86-
module procedure has_scalar_surface_field_specific, &
87-
has_vector_surface_field_specific
86+
module procedure has_scalar_surface_field_by_bc_number, &
87+
has_vector_surface_field_by_bc_number, &
88+
has_scalar_surface_field_by_bc_name, &
89+
has_vector_surface_field_by_bc_name
8890
end interface
91+
92+
interface has_scalar_surface_field
93+
module procedure vector_has_scalar_surface_field_by_bc_number, &
94+
vector_has_scalar_surface_field_by_bc_name
95+
end interface has_scalar_surface_field
8996

9097
interface get_boundary_condition_count
9198
module procedure get_scalar_boundary_condition_count, &
@@ -792,9 +799,9 @@ function extract_vector_scalar_surface_field_by_name(field, bc_name, name, stat)
792799

793800
end function extract_vector_scalar_surface_field_by_name
794801

795-
function has_scalar_surface_field_specific(field, n, name)
802+
function has_scalar_surface_field_by_bc_number(field, n, name)
796803
!!< Tells whether a surface_field with the given is present
797-
logical :: has_scalar_surface_field_specific
804+
logical :: has_scalar_surface_field_by_bc_number
798805
type(scalar_field), intent(in):: field
799806
integer, intent(in):: n
800807
character(len=*), intent(in):: name
@@ -808,19 +815,19 @@ function has_scalar_surface_field_specific(field, n, name)
808815
if (associated(bc%surface_fields)) then
809816
do i=1, size(bc%surface_fields)
810817
if (bc%surface_fields(i)%name==name) then
811-
has_scalar_surface_field_specific=.true.
818+
has_scalar_surface_field_by_bc_number=.true.
812819
return
813820
end if
814821
end do
815822
end if
816823

817-
has_scalar_surface_field_specific=.false.
824+
has_scalar_surface_field_by_bc_number=.false.
818825

819-
end function has_scalar_surface_field_specific
826+
end function has_scalar_surface_field_by_bc_number
820827

821-
function has_vector_surface_field_specific(field, n, name)
828+
function has_vector_surface_field_by_bc_number(field, n, name)
822829
!!< Tells whether a surface_field with the given is present
823-
logical :: has_vector_surface_field_specific
830+
logical :: has_vector_surface_field_by_bc_number
824831
type(vector_field), intent(in):: field
825832
integer, intent(in):: n
826833
character(len=*), intent(in):: name
@@ -834,19 +841,19 @@ function has_vector_surface_field_specific(field, n, name)
834841
if (associated(bc%surface_fields)) then
835842
do i=1, size(bc%surface_fields)
836843
if (bc%surface_fields(i)%name==name) then
837-
has_vector_surface_field_specific=.true.
844+
has_vector_surface_field_by_bc_number=.true.
838845
return
839846
end if
840847
end do
841848
end if
842849

843-
has_vector_surface_field_specific=.false.
850+
has_vector_surface_field_by_bc_number=.false.
844851

845-
end function has_vector_surface_field_specific
852+
end function has_vector_surface_field_by_bc_number
846853

847-
function has_scalar_surface_field(field, n, name)
854+
function vector_has_scalar_surface_field_by_bc_number(field, n, name)
848855
!!< Tells whether a surface_field with the given is present
849-
logical :: has_scalar_surface_field
856+
logical :: vector_has_scalar_surface_field_by_bc_number
850857
type(vector_field), intent(in):: field
851858
integer, intent(in):: n
852859
character(len=*), intent(in):: name
@@ -860,16 +867,79 @@ function has_scalar_surface_field(field, n, name)
860867
if (associated(bc%scalar_surface_fields)) then
861868
do i=1, size(bc%scalar_surface_fields)
862869
if (bc%scalar_surface_fields(i)%name==name) then
863-
has_scalar_surface_field=.true.
870+
vector_has_scalar_surface_field_by_bc_number=.true.
864871
return
865872
end if
866873
end do
867874
end if
868875

869-
has_scalar_surface_field=.false.
876+
vector_has_scalar_surface_field_by_bc_number=.false.
870877

871-
end function has_scalar_surface_field
878+
end function vector_has_scalar_surface_field_by_bc_number
879+
880+
function has_scalar_surface_field_by_bc_name(field, bc_name, name)
881+
!!< Tells whether a surface_field with the given name is present
882+
!!< If the bc_name does not exist an error is given
883+
logical :: has_scalar_surface_field_by_bc_name
884+
type(scalar_field), intent(in):: field
885+
character(len=*), intent(in):: bc_name, name
872886

887+
integer i
888+
889+
do i=1, size(field%bc%boundary_condition)
890+
if (field%bc%boundary_condition(i)%name==bc_name) then
891+
has_scalar_surface_field_by_bc_name = has_scalar_surface_field_by_bc_number(field, i, name)
892+
return
893+
end if
894+
end do
895+
896+
ewrite(-1,*) 'Unknown boundary condition: ', name
897+
FLAbort("Sorry!")
898+
899+
end function has_scalar_surface_field_by_bc_name
900+
901+
function has_vector_surface_field_by_bc_name(field, bc_name, name)
902+
!!< Tells whether a surface_field with the given name is present
903+
!!< If the bc_name does not exist an error is given
904+
logical :: has_vector_surface_field_by_bc_name
905+
type(vector_field), intent(in):: field
906+
character(len=*), intent(in):: bc_name, name
907+
908+
integer i
909+
910+
do i=1, size(field%bc%boundary_condition)
911+
if (field%bc%boundary_condition(i)%name==bc_name) then
912+
has_vector_surface_field_by_bc_name = has_vector_surface_field_by_bc_number(field, i, name)
913+
return
914+
end if
915+
end do
916+
917+
ewrite(-1,*) 'Unknown boundary condition: ', name
918+
FLAbort("Sorry!")
919+
920+
end function has_vector_surface_field_by_bc_name
921+
922+
function vector_has_scalar_surface_field_by_bc_name(field, bc_name, name)
923+
!!< Tells whether a scalar surface_field with the given name is present under a vector field bc
924+
!!< If the bc_name does not exist an error is given
925+
logical :: vector_has_scalar_surface_field_by_bc_name
926+
type(vector_field), intent(in):: field
927+
character(len=*), intent(in):: bc_name, name
928+
929+
integer i
930+
931+
do i=1, size(field%bc%boundary_condition)
932+
if (field%bc%boundary_condition(i)%name==bc_name) then
933+
vector_has_scalar_surface_field_by_bc_name = vector_has_scalar_surface_field_by_bc_number(field, i, name)
934+
return
935+
end if
936+
end do
937+
938+
ewrite(-1,*) 'Unknown boundary condition: ', name
939+
FLAbort("Sorry!")
940+
941+
end function vector_has_scalar_surface_field_by_bc_name
942+
873943
integer function get_scalar_boundary_condition_count(field)
874944
!!< Get number of boundary conditions of a scalar field
875945
type(scalar_field), intent(in):: field

femtools/Detector_Move_Lagrangian.F90

+2-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,8 @@ subroutine move_lagrangian_detectors(state, detector_list, dt)
231231

232232
!This call serialises send_list_array, sends it,
233233
!receives serialised receive_list_array, and unserialises that.
234-
call exchange_detectors(state(1),detector_list, send_list_array)
234+
call exchange_detectors(state(1),detector_list, send_list_array, &
235+
include_update_vector=.true.)
235236

236237
end do detector_timestepping_loop
237238
end do RKstages_loop

0 commit comments

Comments
 (0)