Skip to content

Commit aedd3df

Browse files
authored
Merge pull request #345 from FluidityProject/distinct_particle_attrib_on_spawn
ENH: Allow for independent particle attribute values on initialisation and advection
2 parents a8d2e6f + d70044d commit aedd3df

File tree

33 files changed

+1359
-1062
lines changed

33 files changed

+1359
-1062
lines changed

assemble/Adapt_State.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ subroutine adapt_state_first_timestep(states)
10061006

10071007
!Set particle attributes and dependent fields
10081008
call get_option("/timestepping/current_time", current_time)
1009-
call update_particle_attributes_and_fields(states, current_time, dt)
1009+
call update_particle_attributes_and_fields(states, current_time, dt, initial=.true.)
10101010
call calculate_diagnostic_fields_from_particles(states)
10111011

10121012
! Form the new metric

assemble/Particle_Diagnostics.F90

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,15 @@ module particle_diagnostics
4848
use detector_tools, only: temp_list_insert, insert, allocate, deallocate, temp_list_deallocate, &
4949
& remove, temp_list_remove
5050
use particles, only : get_particle_arrays, initialise_constant_particle_attributes, &
51-
& update_particle_attributes_and_fields, get_particle_arrays, particle_lists
51+
& particle_lists
5252
use multimaterial_module, only: calculate_sum_material_volume_fractions
5353

5454
implicit none
5555

5656
private
5757

58-
public :: update_particle_attributes_and_fields, calculate_particle_material_fields, &
59-
& calculate_diagnostic_fields_from_particles, initialise_constant_particle_diagnostics, &
60-
& particle_cv_check
58+
public :: calculate_particle_material_fields, calculate_diagnostic_fields_from_particles, &
59+
& initialise_constant_particle_diagnostics, particle_cv_check
6160

6261
contains
6362

@@ -95,9 +94,12 @@ subroutine initialise_constant_particle_diagnostics(state)
9594
do j = 1,particle_arrays(i)
9695
particle => particle_lists(list_counter)%first
9796
subgroup_path = trim(group_path) // "/particle_subgroup["//int2str(j-1)//"]"
98-
if (option_count(trim(subgroup_path) // "/attributes/scalar_attribute/constant") + &
99-
& option_count(trim(subgroup_path) // "/attributes/vector_attribute/constant") + &
100-
& option_count(trim(subgroup_path) // "/attributes/tensor_attribute/constant")>0) then
97+
if (option_count(trim(subgroup_path) // "/attributes/scalar_attribute/initial_attribute_value/constant") + &
98+
& option_count(trim(subgroup_path) // "/attributes/scalar_attribute/attribute_value/constant") + &
99+
& option_count(trim(subgroup_path) // "/attributes/vector_attribute/initial_attribute_value/constant") + &
100+
& option_count(trim(subgroup_path) // "/attributes/vector_attribute/attribute_value/constant") + &
101+
& option_count(trim(subgroup_path) // "/attributes/tensor_attribute/initial_attribute_value/constant") + &
102+
& option_count(trim(subgroup_path) // "/attributes/tensor_attribute/attribute_value/constant")>0) then
101103
call initialise_constant_particle_attributes(state, subgroup_path, particle_lists(list_counter))
102104
end if
103105
list_counter = list_counter + 1
@@ -126,24 +128,24 @@ subroutine calculate_diagnostic_fields_from_particles(state)
126128

127129
!Initialise diagnostic fields generated from particles
128130
do i = 1,size(state)
129-
do k = 1,scalar_field_count(state(i))
130-
s_field => extract_scalar_field(state(i),k)
131-
if (have_option(trim(s_field%option_path)//"/diagnostic/algorithm::from_particles")) then
132-
call get_option(trim(s_field%option_path)//"/name", name)
133-
if (name=="MaterialVolumeFraction") cycle
134-
call calculate_field_from_particles(state, i, s_field)
135-
end if
136-
end do
131+
do k = 1,scalar_field_count(state(i))
132+
s_field => extract_scalar_field(state(i),k)
133+
if (have_option(trim(s_field%option_path)//"/diagnostic/algorithm::from_particles")) then
134+
call get_option(trim(s_field%option_path)//"/name", name)
135+
if (name=="MaterialVolumeFraction") cycle
136+
call calculate_field_from_particles(state, i, s_field)
137+
end if
138+
end do
137139
end do
138140

139141
!Initialise fields based on number of particles if present
140142
do i = 1,size(state)
141-
do k = 1,scalar_field_count(state(i))
142-
s_field => extract_scalar_field(state(i),k)
143-
if (have_option(trim(s_field%option_path)//"/diagnostic/algorithm::number_of_particles")) then
144-
call calculate_field_from_particles(state, i, s_field)
145-
end if
146-
end do
143+
do k = 1,scalar_field_count(state(i))
144+
s_field => extract_scalar_field(state(i),k)
145+
if (have_option(trim(s_field%option_path)//"/diagnostic/algorithm::number_of_particles")) then
146+
call calculate_field_from_particles(state, i, s_field)
147+
end if
148+
end do
147149
end do
148150

149151
end subroutine calculate_diagnostic_fields_from_particles

docker/actions/Dockerfile.actions.bionic

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ RUN apt-get -y update && \
88
rm -rf /var/cache/apt/archives && \
99
rm -rf /var/lib/apt/lists
1010

11+
RUN python3 -m pip install --upgrade numpy scipy
12+
1113
RUN adduser fluidity sudo
1214
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
1315

examples/particle_rayleigh_taylor_mu10/particle-rayleigh-taylor-mu10-24.flml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,11 @@
125125
</initial_position>
126126
<attributes>
127127
<scalar_attribute name="Chem1">
128-
<constant>
129-
<real_value rank="0">0</real_value>
130-
</constant>
128+
<attribute_value>
129+
<constant>
130+
<real_value rank="0">0</real_value>
131+
</constant>
132+
</attribute_value>
131133
</scalar_attribute>
132134
</attributes>
133135
</particle_subgroup>
@@ -156,9 +158,11 @@
156158
</initial_position>
157159
<attributes>
158160
<scalar_attribute name="Chem1">
159-
<constant>
160-
<real_value rank="0">1</real_value>
161-
</constant>
161+
<attribute_value>
162+
<constant>
163+
<real_value rank="0">1</real_value>
164+
</constant>
165+
</attribute_value>
162166
</scalar_attribute>
163167
</attributes>
164168
</particle_subgroup>

examples/particle_rayleigh_taylor_mu10/particle-rayleigh-taylor-mu10-48.flml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,11 @@
125125
</initial_position>
126126
<attributes>
127127
<scalar_attribute name="Chem1">
128-
<constant>
129-
<real_value rank="0">0</real_value>
130-
</constant>
128+
<attribute_value>
129+
<constant>
130+
<real_value rank="0">0</real_value>
131+
</constant>
132+
</attribute_value>
131133
</scalar_attribute>
132134
</attributes>
133135
</particle_subgroup>
@@ -156,9 +158,11 @@
156158
</initial_position>
157159
<attributes>
158160
<scalar_attribute name="Chem1">
159-
<constant>
160-
<real_value rank="0">1</real_value>
161-
</constant>
161+
<attribute_value>
162+
<constant>
163+
<real_value rank="0">1</real_value>
164+
</constant>
165+
</attribute_value>
162166
</scalar_attribute>
163167
</attributes>
164168
</particle_subgroup>

femtools/CGAL_Tools.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
module cgal_tools
33

44
use fldebug
5-
use fields
65
use element_numbering
6+
use fields
77
implicit none
88

99
interface

femtools/Detector_Tools.F90

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ end subroutine set_particle_scalar_attribute_from_python
784784
!! specified in the string func at that location.
785785
subroutine set_particle_scalar_attribute_from_python_fields(particle_list, state, positions, lcoords, ele, natt, &
786786
attributes, old_attr_names, old_attr_counts, old_attr_Dims, old_attributes, field_names, field_counts, old_field_names, &
787-
old_field_counts, func, time, dt, is_array)
787+
old_field_counts, func, time, dt, is_array, first_newly_init_part)
788788
!! Particle list for which to evaluate the function
789789
type(detector_linked_list), intent(in) :: particle_list
790790
!! Model state structure
@@ -828,6 +828,8 @@ subroutine set_particle_scalar_attribute_from_python_fields(particle_list, state
828828
real, intent(in) :: dt
829829
!! Whether this is an array-valued attribute
830830
logical, intent(in) :: is_array
831+
!> Pointer to the first newly initialised particle
832+
type(detector_type), pointer, optional :: first_newly_init_part
831833

832834
! locals
833835
integer :: i
@@ -864,7 +866,12 @@ subroutine set_particle_scalar_attribute_from_python_fields(particle_list, state
864866
field_vals, dim)
865867

866868
! copy old fields off particles
867-
particle => particle_list%first
869+
if (present(first_newly_init_part)) then
870+
particle => first_newly_init_part
871+
else
872+
particle => particle_list%first
873+
end if
874+
868875
do i = 1, nparts
869876
old_field_vals(:,i) = particle%old_fields(:)
870877
particle => particle%next
@@ -874,9 +881,9 @@ subroutine set_particle_scalar_attribute_from_python_fields(particle_list, state
874881
lvx, lvy, lvz, time, dt, field_counts, field_names, field_vals, old_field_counts, old_field_names, &
875882
old_field_vals, old_attr_counts, old_attr_names, old_attr_dims, old_attributes, is_array, attributes, stat)
876883
if (stat/=0) then
877-
ewrite(-1, *) "Python error, Python string was:"
878-
ewrite(-1 , *) trim(func)
879-
FLExit("Dying")
884+
ewrite(-1, *) "Python error, Python string was:"
885+
ewrite(-1 , *) trim(func)
886+
FLExit("Dying")
880887
end if
881888

882889
deallocate(field_vals)
@@ -943,7 +950,7 @@ end subroutine set_particle_vector_attribute_from_python
943950
!! specified in the string func at that location.
944951
subroutine set_particle_vector_attribute_from_python_fields(particle_list, state, positions, lcoords, ele, natt, &
945952
attributes, old_attr_names, old_attr_counts, old_attr_dims, old_attributes, field_names, field_counts, old_field_names, &
946-
old_field_counts, func, time, dt, is_array)
953+
old_field_counts, func, time, dt, is_array, first_newly_init_part)
947954
!! Particle list for which to evaluate the function
948955
type(detector_linked_list), intent(in) :: particle_list
949956
!! Model state structure
@@ -987,6 +994,8 @@ subroutine set_particle_vector_attribute_from_python_fields(particle_list, state
987994
real, intent(in) :: dt
988995
!! Whether this is an array-valued attribute
989996
logical, intent(in) :: is_array
997+
!> Pointer to the first newly initialised particle
998+
type(detector_type), pointer, optional :: first_newly_init_part
990999

9911000
! locals
9921001
integer :: i
@@ -1023,7 +1032,12 @@ subroutine set_particle_vector_attribute_from_python_fields(particle_list, state
10231032
field_vals, dim)
10241033

10251034
! copy old fields off particles
1026-
particle => particle_list%first
1035+
if (present(first_newly_init_part)) then
1036+
particle => first_newly_init_part
1037+
else
1038+
particle => particle_list%first
1039+
end if
1040+
10271041
do i = 1, nparts
10281042
old_field_vals(:,i) = particle%old_fields(:)
10291043
particle => particle%next
@@ -1109,7 +1123,7 @@ end subroutine set_particle_tensor_attribute_from_python
11091123
!! specified in the string func at that location.
11101124
subroutine set_particle_tensor_attribute_from_python_fields(particle_list, state, positions, lcoords, ele, natt, &
11111125
attributes, old_attr_names, old_attr_counts, old_attr_dims, old_attributes, field_names, field_counts, old_field_names, &
1112-
old_field_counts, func, time, dt, is_array)
1126+
old_field_counts, func, time, dt, is_array, first_newly_init_part)
11131127
!! Particle list for which to evaluate the function
11141128
type(detector_linked_list), intent(in) :: particle_list
11151129
!! Model state structure
@@ -1153,6 +1167,8 @@ subroutine set_particle_tensor_attribute_from_python_fields(particle_list, state
11531167
real, intent(in) :: dt
11541168
!! Whether this is an array-valued attribute
11551169
logical, intent(in) :: is_array
1170+
!> Pointer to the first newly initialised particle
1171+
type(detector_type), pointer, optional :: first_newly_init_part
11561172

11571173
! locals
11581174
integer :: i
@@ -1190,7 +1206,12 @@ subroutine set_particle_tensor_attribute_from_python_fields(particle_list, state
11901206
field_vals, dim)
11911207

11921208
! copy old fields off particles
1193-
particle => particle_list%first
1209+
if (present(first_newly_init_part)) then
1210+
particle => first_newly_init_part
1211+
else
1212+
particle => particle_list%first
1213+
end if
1214+
11941215
do i = 1, nparts
11951216
old_field_vals(:,i) = particle%old_fields(:)
11961217
particle => particle%next

0 commit comments

Comments
 (0)