Merge lp:~michael-lange/fluidity/fix_detector_init into lp:fluidity

Proposed by Michael Lange
Status: Merged
Approved by: Mark Filipiak
Approved revision: 4031
Merged at revision: 4127
Proposed branch: lp:~michael-lange/fluidity/fix_detector_init
Merge into: lp:fluidity
Diff against target: 325 lines (+235/-19)
6 files modified
femtools/Diagnostic_variables.F90 (+18/-17)
femtools/Node_Owner_Finder_Fortran.F90 (+13/-2)
tests/detectors_parallel_init/Makefile (+15/-0)
tests/detectors_parallel_init/detectors.flml (+121/-0)
tests/detectors_parallel_init/detectors_parallel_init.xml (+61/-0)
tests/detectors_parallel_init/src/square.geo (+7/-0)
To merge this branch: bzr merge lp:~michael-lange/fluidity/fix_detector_init
Reviewer Review Type Date Requested Status
Mark Filipiak (community) Approve
Review via email: mp+119699@code.launchpad.net

Description of the change

Fixing the initialisation of detectors in parallel (lp:967093) and adding an according test case. Many thanks to M. Filipiak for providing the patch.

Also fixing detector initialisation from file in parallel, which would previously segfault, due to the legacy restriction to only one proc.

To post a comment you must log in.
4030. By Michael Lange

Merge from trunk

4031. By Michael Lange

The new test case should use flredecomp.

Revision history for this message
Mark Filipiak (mjf-q) wrote :

Not sure if I'm allowed to review the changes since I'm one of the authors but I'd like to get this fix into the trunk so I can then add the fldecomp-to-flredecomp change.

The change to get the detectors read in from file in parallel looks ok (and matches what is done for a checkpointed detector file in parallel). The new test fails on the old trunk and passes with this branch.

I looked again at the code I added to work out the owner of a detector. I still think it's OK. It's has a slight inefficiency as James Maddison noticed but I don't know if changing the picker construction to consider only owned elements will break other things (e.g. interpolate_boundary_values(Geostrophic_Pressure.F90)). Changing find_serial() to have the same ownership test as find_parallel() might *seem* cleaner but will certainly break interpolate_boundary_values(Geostrophic_Pressure.F90).

I think the names of the routine find_serial() and find_parallel() are perhaps not descriptive, the first really means 'find any element, that this process has in its mesh, that contains the point, even if this process doesn't own that element': I don't think it is worth changing the names.

It can be merged into the trunk (Michael, I have a version of fix_detector_init that I merged trunk r4125 into and tested up to medium tests locally, not in buildbot).

review: Approve
4032. By Michael Lange

Merge from trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'femtools/Diagnostic_variables.F90'
--- femtools/Diagnostic_variables.F90 2012-01-20 15:54:44 +0000
+++ femtools/Diagnostic_variables.F90 2012-11-08 12:08:22 +0000
@@ -1369,7 +1369,10 @@
1369 assert(xfield%dim+1==local_coord_count(shape))1369 assert(xfield%dim+1==local_coord_count(shape))
13701370
1371 ! Determine element and local_coords from position1371 ! Determine element and local_coords from position
1372 call picker_inquire(xfield,position,element,local_coord=lcoords,global=.false.)1372 ! In parallel, global=.false. can often work because there will be
1373 ! a halo of non-owned elements in your process and so you can work out
1374 ! ownership without communication. But in general it won't work.
1375 call picker_inquire(xfield,position,element,local_coord=lcoords,global=.true.)
13731376
1374 ! If we're in parallel and don't own the element, skip this detector1377 ! If we're in parallel and don't own the element, skip this detector
1375 if (isparallel()) then1378 if (isparallel()) then
@@ -1568,26 +1571,24 @@
1568 else1571 else
15691572
1570 ! Reading from a binary file where the user has placed the detector positions1573 ! Reading from a binary file where the user has placed the detector positions
1571 if (getprocno() == 1) then1574 default_stat%detector_file_unit=free_unit()
1572 default_stat%detector_file_unit=free_unit()1575 call get_option("/io/detectors/detector_array/from_file/file_name",detector_file_filename)
1573 call get_option("/io/detectors/detector_array/from_file/file_name",detector_file_filename)
15741576
1575#ifdef STREAM_IO1577#ifdef STREAM_IO
1576 open(unit = default_stat%detector_file_unit, file = trim(detector_file_filename), &1578 open(unit = default_stat%detector_file_unit, file = trim(detector_file_filename), &
1577 & action = "read", access = "stream", form = "unformatted")1579 & action = "read", access = "stream", form = "unformatted")
1578#else1580#else
1579 FLAbort("No stream I/O support")1581 FLAbort("No stream I/O support")
1580#endif1582#endif
1581 1583
1582 do j=1,ndete1584 do j=1,ndete
1583 write(detector_name, fmt) trim(funcnam)//"_", j1585 write(detector_name, fmt) trim(funcnam)//"_", j
1584 default_stat%detector_list%detector_names(k)=trim(detector_name)1586 default_stat%detector_list%detector_names(k)=trim(detector_name)
1585 read(default_stat%detector_file_unit) detector_location1587 read(default_stat%detector_file_unit) detector_location
1586 call create_single_detector(default_stat%detector_list, xfield, &1588 call create_single_detector(default_stat%detector_list, xfield, &
1587 detector_location, k, type_det, trim(detector_name))1589 detector_location, k, type_det, trim(detector_name))
1588 k=k+1 1590 k=k+1
1589 end do1591 end do
1590 end if
1591 end if1592 end if
1592 end do 1593 end do
1593 else 1594 else
15941595
=== modified file 'femtools/Node_Owner_Finder_Fortran.F90'
--- femtools/Node_Owner_Finder_Fortran.F90 2010-11-09 14:08:19 +0000
+++ femtools/Node_Owner_Finder_Fortran.F90 2012-11-08 12:08:22 +0000
@@ -268,8 +268,16 @@
268 call cnode_owner_finder_query_output(id, nele_ids)268 call cnode_owner_finder_query_output(id, nele_ids)
269269
270 closest_ele_id = -1270 closest_ele_id = -1
271 do j = 1, nele_ids271 possible_elements_loop: do j = 1, nele_ids
272 call cnode_owner_finder_get_output(id, possible_ele_id, j)272 call cnode_owner_finder_get_output(id, possible_ele_id, j)
273 ! If this process does not own this possible_ele_id element then
274 ! don't consider it. This filter is needed to make this subroutine work in
275 ! parallel without having to use universal numbers, which aren't defined
276 ! for all the meshes that use this subroutine.
277 if(.not.element_owned(positions_a,possible_ele_id)) then
278 assert(isparallel())
279 cycle possible_elements_loop
280 end if
273 ! Zero tolerance - we're not using an "epsilon-ball" approach here281 ! Zero tolerance - we're not using an "epsilon-ball" approach here
274 if(ownership_predicate(positions_a, possible_ele_id, positions(:, i), 0.0, miss = miss)) then282 if(ownership_predicate(positions_a, possible_ele_id, positions(:, i), 0.0, miss = miss)) then
275 ele_ids(i) = possible_ele_id283 ele_ids(i) = possible_ele_id
@@ -281,7 +289,7 @@
281 closest_ele_id = possible_ele_id289 closest_ele_id = possible_ele_id
282 closest_misses(i) = miss290 closest_misses(i) = miss
283 end if291 end if
284 end do292 end do possible_elements_loop
285293
286 ! We didn't find an owner, so choose the element with the closest miss294 ! We didn't find an owner, so choose the element with the closest miss
287 ele_ids(i) = closest_ele_id295 ele_ids(i) = closest_ele_id
@@ -310,6 +318,9 @@
310 ! Another processes has a smaller miss for this coordinate318 ! Another processes has a smaller miss for this coordinate
311 ele_ids(i) = -1319 ele_ids(i) = -1
312 end if320 end if
321 ! if no process has closest_misses(i) < out_of_bounds_tolerance
322 ! then ele_ids(i) is already set to -1 in positions_loop above
323 ! on all processes. This matches the find_serial(0) behaviour.
313 end do324 end do
314#endif325#endif
315 326
316327
=== added directory 'tests/detectors_parallel_init'
=== added file 'tests/detectors_parallel_init/Makefile'
--- tests/detectors_parallel_init/Makefile 1970-01-01 00:00:00 +0000
+++ tests/detectors_parallel_init/Makefile 2012-11-08 12:08:22 +0000
@@ -0,0 +1,15 @@
1default: input
2
3input: clean
4 gmsh -2 -o src/square.msh src/square.geo
5 ../../bin/gmsh2triangle --2d src/square.msh
6 mpiexec -n 2 ../../bin/flredecomp -i 1 -o 2 detectors detectors_flredecomp
7
8clean: clean-mesh clean-run
9clean-mesh:
10 rm -f *.ele *.edge *.face *.node *.halo *.pvtu *.vtu *.detectors *.detectors.dat *.stat
11 rm -f gmsh.log gmsh_err.log
12clean-run:
13 rm -f matrixdump matrixdump.info
14 rm -f fluidity.err-* fluidity.log-*
15 rm -rf detectors_[0-4]* *flredecomp*
016
=== added file 'tests/detectors_parallel_init/detectors.flml'
--- tests/detectors_parallel_init/detectors.flml 1970-01-01 00:00:00 +0000
+++ tests/detectors_parallel_init/detectors.flml 2012-11-08 12:08:22 +0000
@@ -0,0 +1,121 @@
1<?xml version='1.0' encoding='utf-8'?>
2<fluidity_options>
3 <simulation_name>
4 <string_value lines="1">detectors</string_value>
5 </simulation_name>
6 <problem_type>
7 <string_value lines="1">fluids</string_value>
8 </problem_type>
9 <geometry>
10 <dimension>
11 <integer_value rank="0">2</integer_value>
12 </dimension>
13 <mesh name="CoordinateMesh">
14 <from_file file_name="square">
15 <format name="triangle"/>
16 <stat>
17 <include_in_stat/>
18 </stat>
19 </from_file>
20 </mesh>
21 <mesh name="VelocityMesh">
22 <from_mesh>
23 <mesh name="CoordinateMesh"/>
24 <stat>
25 <exclude_from_stat/>
26 </stat>
27 </from_mesh>
28 </mesh>
29 <quadrature>
30 <degree>
31 <integer_value rank="0">6</integer_value>
32 </degree>
33 </quadrature>
34 </geometry>
35 <io>
36 <dump_format>
37 <string_value>vtk</string_value>
38 </dump_format>
39 <dump_period>
40 <constant>
41 <real_value rank="0">0.0</real_value>
42 </constant>
43 </dump_period>
44 <output_mesh name="VelocityMesh"/>
45 <stat/>
46 <detectors>
47 <static_detector name="MidPoint">
48 <location>
49 <real_value shape="2" dim1="dim" rank="1">0.5 0.5</real_value>
50 </location>
51 </static_detector>
52 <detector_array name="DArray">
53 <number_of_detectors>
54 <integer_value rank="0">3</integer_value>
55 </number_of_detectors>
56 <static/>
57 <from_file file_name="positions.dat">
58 <format>
59 <string_value>binary</string_value>
60 </format>
61 </from_file>
62 </detector_array>
63 <fail_outside_domain/>
64 </detectors>
65 </io>
66 <timestepping>
67 <current_time>
68 <real_value rank="0">0.0</real_value>
69 </current_time>
70 <timestep>
71 <real_value rank="0">1.0</real_value>
72 </timestep>
73 <finish_time>
74 <real_value rank="0">1.0</real_value>
75 </finish_time>
76 </timestepping>
77 <physical_parameters/>
78 <material_phase name="Water">
79 <vector_field name="Velocity" rank="1">
80 <prescribed>
81 <mesh name="VelocityMesh"/>
82 <value name="WholeMesh">
83 <python>
84 <string_value lines="20" type="code" language="python">def val(X,t):
85 return(X[1],0.0)</string_value>
86 </python>
87 </value>
88 <output/>
89 <stat>
90 <include_in_stat/>
91 </stat>
92 <detectors>
93 <include_in_detectors/>
94 </detectors>
95 </prescribed>
96 </vector_field>
97 <scalar_field name="Tracer" rank="0">
98 <prescribed>
99 <mesh name="VelocityMesh"/>
100 <value name="WholeMesh">
101 <python>
102 <string_value lines="20" type="code" language="python">def val(X,t):
103 return X[0]</string_value>
104 </python>
105 </value>
106 <output/>
107 <stat/>
108 <detectors>
109 <include_in_detectors/>
110 </detectors>
111 </prescribed>
112 </scalar_field>
113 </material_phase>
114 <flredecomp>
115 <final_partitioner>
116 <zoltan>
117 <method>graph</method>
118 </zoltan>
119 </final_partitioner>
120 </flredecomp>
121</fluidity_options>
0122
=== added file 'tests/detectors_parallel_init/detectors_parallel_init.xml'
--- tests/detectors_parallel_init/detectors_parallel_init.xml 1970-01-01 00:00:00 +0000
+++ tests/detectors_parallel_init/detectors_parallel_init.xml 2012-11-08 12:08:22 +0000
@@ -0,0 +1,61 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2
3<testproblem>
4 <name>detectors_parallel_init</name>
5 <owner userid="mlange"/>
6 <tags>flml</tags>
7 <problem_definition length="short" nprocs="1">
8 <command_line>mpiexec -n 2 ../../bin/fluidity detectors_flredecomp.flml </command_line>
9 <!-- Test that detectors are initialised correctly in parallel. -->
10 </problem_definition>
11 <variables>
12 <variable name="solvers_converged" language="python">
13import os
14files = os.listdir("./")
15solvers_converged = not "matrixdump" in files and not "matrixdump.info" in files
16 </variable>
17 <variable name = "time" language = "python">
18from fluidity_tools import stat_parser
19time = stat_parser("detectors.stat")["ElapsedTime"]["value"]
20 </variable>
21 <variable name = "det_midpoint" language = "python">
22from fluidity_tools import stat_parser
23det_midpoint = stat_parser("detectors.detectors")["MidPoint"]['position']
24 </variable>
25 <variable name = "det_arr1" language = "python">
26from fluidity_tools import stat_parser
27det_arr1 = stat_parser("detectors.detectors")["DArray_1"]['position']
28 </variable>
29 <variable name = "det_arr2" language = "python">
30from fluidity_tools import stat_parser
31det_arr2 = stat_parser("detectors.detectors")["DArray_2"]['position']
32 </variable>
33 <variable name = "det_arr3" language = "python">
34from fluidity_tools import stat_parser
35det_arr3 = stat_parser("detectors.detectors")["DArray_3"]['position']
36 </variable>
37 </variables>
38 <pass_tests>
39 <test name="Solvers converged" language="python">
40 assert(solvers_converged)
41 </test>
42 <test name="Test finished" language="python">
43assert abs(time - 1.0) &lt; 1.0e-6
44 </test>
45 <test name="Detector output" language="python">
46assert abs(len(time) - len(det_midpoint[-1])) &lt; 1.0e-6
47 </test>
48 <test name="Detectors initialised correctly" language="python">
49assert abs(det_midpoint[0] - 0.5).all() &lt; 1.0e-6
50assert abs(det_midpoint[1] - 0.5).all() &lt; 1.0e-6
51assert abs(det_arr1[0]).all() &lt; 1.0e-6
52assert abs(det_arr1[1] - 1.0).all() &lt; 1.0e-6
53assert abs(det_arr2[0] - 0.5).all() &lt; 1.0e-6
54assert abs(det_arr2[1] - 0.5).all() &lt; 1.0e-6
55assert abs(det_arr3[0] - 1.0).all() &lt; 1.0e-6
56assert abs(det_arr3[1]).all() &lt; 1.0e-6
57 </test>
58 </pass_tests>
59 <warn_tests>
60 </warn_tests>
61</testproblem>
062
=== added file 'tests/detectors_parallel_init/positions.dat'
1Binary files tests/detectors_parallel_init/positions.dat 1970-01-01 00:00:00 +0000 and tests/detectors_parallel_init/positions.dat 2012-11-08 12:08:22 +0000 differ63Binary files tests/detectors_parallel_init/positions.dat 1970-01-01 00:00:00 +0000 and tests/detectors_parallel_init/positions.dat 2012-11-08 12:08:22 +0000 differ
=== added directory 'tests/detectors_parallel_init/src'
=== added file 'tests/detectors_parallel_init/src/square.geo'
--- tests/detectors_parallel_init/src/square.geo 1970-01-01 00:00:00 +0000
+++ tests/detectors_parallel_init/src/square.geo 2012-11-08 12:08:22 +0000
@@ -0,0 +1,7 @@
1Point (1) = {0, 0, 0};
2Extrude {1,0,0} {
3 Point{1}; Layers{2};
4}
5Extrude {0,1,0} {
6 Line{1}; Layers{2};
7}