Merge lp:~fluidity-core/fluidity/fieldweightedpartition into lp:fluidity

Proposed by Rhodri Davies
Status: Merged
Merged at revision: 4055
Proposed branch: lp:~fluidity-core/fluidity/fieldweightedpartition
Merge into: lp:fluidity
Diff against target: 877 lines (+664/-13)
15 files modified
assemble/Zoltan_callbacks.F90 (+19/-7)
assemble/Zoltan_global_variables.F90 (+2/-1)
assemble/Zoltan_integration.F90 (+30/-4)
main/Fluids.F90 (+1/-0)
manual/meshes.tex (+7/-1)
preprocessor/Populate_State.F90 (+9/-0)
schemas/adaptivity_options.rnc (+14/-0)
schemas/adaptivity_options.rng (+20/-0)
schemas/flredecomp.rnc (+14/-0)
schemas/flredecomp.rng (+20/-0)
tests/flredecomp_2d_fieldweighted/Makefile (+13/-0)
tests/flredecomp_2d_fieldweighted/check_partitions.py (+28/-0)
tests/flredecomp_2d_fieldweighted/flredecomp-2d-fieldweighted.flml (+410/-0)
tests/flredecomp_2d_fieldweighted/flredecomp_2d_fieldweighted.xml (+25/-0)
tests/flredecomp_2d_fieldweighted/src/Subduction_Mesh.geo (+52/-0)
To merge this branch: bzr merge lp:~fluidity-core/fluidity/fieldweightedpartition
Reviewer Review Type Date Requested Status
Jon Hill Approve
Review via email: mp+123569@code.launchpad.net

Description of the change

This branch includes changes that allow one to weight mesh partitions based upon a user prescribed scalar field. Based upon this information, flredecomp will try to load balance in such a way that the sum of user prescribed weights in each partition is equal.

I have added a test for this new functionality. Results look good.

I have also updated the manual to describe this change.

The buildbot branch is here:
http://buildbot-ocean.ese.ic.ac.uk:8080/builders/cap_fields

Will update when green (hopefully).

As usual, a big fat thank you and man hug to my office hommie skramer!!!

To post a comment you must log in.
4056. By Rhodri Davies

Correct flredecomp path

Revision history for this message
Rhodri Davies (rhodri-davies) wrote :

Update: Buildbot is as green as Wales' beautiful valleys!

4057. By Rhodri Davies

Merge trunk change into branch

Revision history for this message
Jon Hill (jon-hill) wrote :

Looks good. Go for it.

review: Approve
4058. By Rhodri Davies

Merge trunk changes into branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'assemble/Zoltan_callbacks.F90'
2--- assemble/Zoltan_callbacks.F90 2011-10-18 09:36:51 +0000
3+++ assemble/Zoltan_callbacks.F90 2012-09-18 19:42:23 +0000
4@@ -64,7 +64,6 @@
5 ierr = ZOLTAN_OK
6 end function zoltan_cb_owned_node_count
7
8-
9 subroutine zoltan_cb_get_owned_nodes(data, num_gid_entries, num_lid_entries, global_ids, local_ids, wgt_dim, obj_wgts, ierr)
10 integer(zoltan_int), dimension(*), intent(in) :: data ! not used
11 integer(zoltan_int), intent(in) :: num_gid_entries, num_lid_entries
12@@ -75,7 +74,7 @@
13 integer(zoltan_int), intent(out) :: ierr
14
15 integer :: count, i
16- real(zoltan_float) :: max_obj_wgt
17+ real(zoltan_float) :: max_obj_wgt, min_obj_wgt
18
19 ewrite(1,*) "In zoltan_cb_get_owned_nodes"
20
21@@ -96,24 +95,38 @@
22 if(zoltan_global_migrate_extruded_mesh) then
23 ! weight the nodes according to the number of nodes in the column beneath it
24 max_obj_wgt = 1.0
25- do i=1,count
26+ do i = 1, count
27 obj_wgts(i) = float(row_length(zoltan_global_columns_sparsity, i))
28 max_obj_wgt = max(max_obj_wgt, obj_wgts(i))
29 end do
30 ! normalise according to the most nodes in a column
31- do i=1,count
32+ do i = 1, count
33 obj_wgts(i) = obj_wgts(i)/max_obj_wgt
34 end do
35 else
36- do i=1,count
37+ do i = 1, count
38 obj_wgts(i) = 1.0
39 end do
40 end if
41+
42+ if(zoltan_global_field_weighted_partitions) then
43+ max_obj_wgt = 1.0
44+ min_obj_wgt = 0.0
45+ do i = 1, count
46+ obj_wgts(i) = node_val(zoltan_global_field_weighted_partition_values,i)
47+ max_obj_wgt = max(max_obj_wgt, obj_wgts(i))
48+ min_obj_wgt = min(min_obj_wgt, obj_wgts(i))
49+ end do
50+
51+ if((max_obj_wgt > 1.0) .OR. (min_obj_wgt < 0.0)) then
52+ FLExit("0.0 <= FieldWeightedPartitionValues <= 1.0: condition not satisfied")
53+ end if
54+
55+ end if
56
57 ierr = ZOLTAN_OK
58 end subroutine zoltan_cb_get_owned_nodes
59
60-
61 subroutine zoltan_cb_get_num_edges(data, num_gid_entries, num_lid_entries, num_obj, global_ids, local_ids, num_edges, ierr)
62 integer(zoltan_int), dimension(*), intent(in) :: data
63 integer(zoltan_int), intent(in) :: num_gid_entries, num_lid_entries, num_obj
64@@ -150,7 +163,6 @@
65 ierr = ZOLTAN_OK
66 end subroutine zoltan_cb_get_num_edges
67
68-
69 subroutine zoltan_cb_get_edge_list(data, num_gid_entries, num_lid_entries, num_obj, global_ids, local_ids, &
70 & num_edges, nbor_global_id, nbor_procs, wgt_dim, ewgts, ierr)
71 integer(zoltan_int), intent(in) :: data
72
73=== modified file 'assemble/Zoltan_global_variables.F90'
74--- assemble/Zoltan_global_variables.F90 2011-09-26 17:04:31 +0000
75+++ assemble/Zoltan_global_variables.F90 2012-09-18 19:42:23 +0000
76@@ -34,11 +34,12 @@
77 ! Needed for zoltan_cb_get_owned_nodes
78 type(csr_sparsity), save :: zoltan_global_columns_sparsity
79 logical, save :: zoltan_global_migrate_extruded_mesh
80+ logical, save :: zoltan_global_field_weighted_partitions
81+ type(scalar_field), save :: zoltan_global_field_weighted_partition_values
82
83 ! Needed for zoltan_cb_get_num_edges
84 type(csr_sparsity), save, pointer :: zoltan_global_zz_sparsity_one
85
86-
87 ! Needed for zoltan_cb_get_edge_list
88 logical, save :: zoltan_global_calculate_edge_weights
89 ! elements with quality greater than this value are ok
90
91=== modified file 'assemble/Zoltan_integration.F90'
92--- assemble/Zoltan_integration.F90 2011-12-07 11:33:45 +0000
93+++ assemble/Zoltan_integration.F90 2012-09-18 19:42:23 +0000
94@@ -136,12 +136,20 @@
95 zoltan_global_migrate_extruded_mesh = option_count('/geometry/mesh/from_mesh/extrude') > 0 &
96 .and. .not. present_and_true(ignore_extrusion)
97
98+ zoltan_global_field_weighted_partitions = &
99+ have_option(trim(zoltan_global_base_option_path) // "/field_weighted_partitions")
100+
101+ if(zoltan_global_migrate_extruded_mesh .AND. zoltan_global_field_weighted_partitions) then
102+ ewrite(-1,*) "Cannot weight mesh partitions based upon extruded columns"// &
103+ "and a prescribed field. Select one option only or fix the code."
104+ FLExit("Use Weighted mesh partitions for EITHER extruded meshes or prescribed fields")
105+ end if
106+
107 call setup_module_variables(states, final_adapt_iteration, zz)
108-
109+
110 call setup_quality_module_variables(states, metric) ! this needs to be called after setup_module_variables
111 ! (but only on the 2d mesh with 2+1d adaptivity)
112
113-
114 load_imbalance_tolerance = get_load_imbalance_tolerance(final_adapt_iteration)
115 call set_zoltan_parameters(final_adapt_iteration, flredecomp, flredecomp_target_procs, load_imbalance_tolerance, zz)
116
117@@ -424,7 +432,22 @@
118 call insert(zoltan_global_universal_element_number_to_region_id, universal_element_number, zoltan_global_zz_positions%mesh%region_ids(i))
119 end do
120 end if
121-
122+
123+ if(zoltan_global_field_weighted_partitions) then
124+ zoltan_global_field_weighted_partition_values = extract_scalar_field(states, "FieldWeightedPartitionValues")
125+ assert(zoltan_global_field_weighted_partition_values%mesh == zoltan_global_zz_mesh)
126+
127+ if(zoltan_global_field_weighted_partition_values%mesh%name /= zoltan_global_zz_mesh%name) then
128+ ewrite(-1,*) "FieldWeightedPartitionValues and Zoltan Global ZZ Mesh must be on the " // &
129+ "same mesh. 99.9% of the time, this means that FieldWeightedPartitionValues " // &
130+ "must be on the external mesh."
131+ FLExit("FieldWeightedPartitionValues must be on the external mesh")
132+ end if
133+
134+ call incref(zoltan_global_field_weighted_partition_values)
135+
136+ end if
137+
138 end subroutine setup_module_variables
139
140 subroutine setup_quality_module_variables(states, metric)
141@@ -724,6 +747,10 @@
142 if(zoltan_global_migrate_extruded_mesh) then
143 call deallocate(zoltan_global_columns_sparsity)
144 end if
145+ if(zoltan_global_field_weighted_partitions) then
146+ call deallocate(zoltan_global_field_weighted_partition_values)
147+ end if
148+
149 end subroutine cleanup_quality_module_variables
150
151 subroutine cleanup_other_module_variables
152@@ -1787,7 +1814,6 @@
153
154 end subroutine initialise_transfer
155
156-
157 subroutine update_detector_list_element(detector_list_array)
158 ! Update the detector%element field for every detector left in our list
159 ! and check that we did not miss any in the first send
160
161=== modified file 'main/Fluids.F90'
162--- main/Fluids.F90 2012-09-05 08:44:55 +0000
163+++ main/Fluids.F90 2012-09-18 19:42:23 +0000
164@@ -893,6 +893,7 @@
165 end if
166
167 end do timestep_loop
168+
169 ! ****************************
170 ! *** END OF TIMESTEP LOOP ***
171 ! ****************************
172
173=== modified file 'manual/meshes.tex'
174--- manual/meshes.tex 2011-11-07 12:52:36 +0000
175+++ manual/meshes.tex 2012-09-18 19:42:23 +0000
176@@ -238,7 +238,13 @@
177 The output of running flredecomp is a series of mesh and vtu files as well
178 as the new flml; in this case \lstinline+foo_flredecomp.flml+.
179 Note that \lstinline[language=bash]+flredecomp+ must be run on a number of processors equal to the larger number of processors between input and output.
180-More information can be found in section~\ref{sec:flredecomp}.
181+
182+When using flredecomp, it is possible to partition the mesh based upon a user defined weighting.
183+This is achieved by prescribing a scalar field, bounded between values of 0 and 1, under
184+\option{/flredecomp/field\_weighted\_partitions}. Flredecomp will then try to ensure that the sum
185+of weights on each partition is approximately equal.
186+
187+Further information on flredecomp can be found in section~\ref{sec:flredecomp}.
188
189 \subsection{Decomposing a periodic mesh}
190 \index{mesh!meshing tools!periodise}
191
192=== modified file 'preprocessor/Populate_State.F90'
193--- preprocessor/Populate_State.F90 2012-09-03 11:38:44 +0000
194+++ preprocessor/Populate_State.F90 2012-09-18 19:42:23 +0000
195@@ -1211,6 +1211,15 @@
196 states(1), dont_allocate_prognostic_value_spaces=dont_allocate_prognostic_value_spaces)
197 end if
198
199+ ! Field that controls the weighting of partitions:
200+ if (have_option('/flredecomp/field_weighted_partitions')) then
201+ call allocate_and_insert_scalar_field('/flredecomp/field_weighted_partitions/scalar_field::FieldWeightedPartitionValues', states(1))
202+ end if
203+
204+ if (have_option('/mesh_adaptivity/hr_adaptivity/zoltan_options/field_weighted_partitions')) then
205+ call allocate_and_insert_scalar_field('/mesh_adaptivity/hr_adaptivity/zoltan_options/field_weighted_partitions/scalar_field::FieldWeightedPartitionValues', states(1))
206+ end if
207+
208 ! grid velocity
209 if (have_option('/mesh_adaptivity/mesh_movement/vector_field::GridVelocity')) then
210 call allocate_and_insert_vector_field('/mesh_adaptivity/mesh_movement/vector_field::GridVelocity', &
211
212=== modified file 'schemas/adaptivity_options.rnc'
213--- schemas/adaptivity_options.rnc 2012-03-21 10:13:54 +0000
214+++ schemas/adaptivity_options.rnc 2012-09-18 19:42:23 +0000
215@@ -974,6 +974,20 @@
216 element additional_adapt_iterations {
217 integer
218 }?,
219+ element field_weighted_partitions {
220+ ## Field weighted partitions: turning on this option allows one to
221+ ## weight mesh partitions, based upon a prescribed scalar field.
222+ ## Note that the field should have a minimum value of 0 and a maximum
223+ ## value of 1 (no normalisation is done within the code).
224+ element scalar_field {
225+ attribute rank { "0" },
226+ attribute name { "FieldWeightedPartitionValues" },
227+ element prescribed {
228+ coordinate_mesh_choice,
229+ prescribed_scalar_field
230+ }
231+ }
232+ }?,
233 ## Zoltan Debugging
234 ##
235 ## Turn on more verbose output for use when debugging Zoltan.
236
237=== modified file 'schemas/adaptivity_options.rng'
238--- schemas/adaptivity_options.rng 2012-03-21 10:13:54 +0000
239+++ schemas/adaptivity_options.rng 2012-09-18 19:42:23 +0000
240@@ -1143,6 +1143,26 @@
241 </element>
242 </optional>
243 <optional>
244+ <element name="field_weighted_partitions">
245+ <element name="scalar_field">
246+ <a:documentation>Field weighted partitions: turning on this option allows one to
247+weight mesh partitions, based upon a prescribed scalar field.
248+Note that the field should have a minimum value of 0 and a maximum
249+value of 1 (no normalisation is done within the code).</a:documentation>
250+ <attribute name="rank">
251+ <value>0</value>
252+ </attribute>
253+ <attribute name="name">
254+ <value>FieldWeightedPartitionValues</value>
255+ </attribute>
256+ <element name="prescribed">
257+ <ref name="coordinate_mesh_choice"/>
258+ <ref name="prescribed_scalar_field"/>
259+ </element>
260+ </element>
261+ </element>
262+ </optional>
263+ <optional>
264 <element name="zoltan_debug">
265 <a:documentation>Zoltan Debugging
266
267
268=== modified file 'schemas/flredecomp.rnc'
269--- schemas/flredecomp.rnc 2011-09-12 11:17:09 +0000
270+++ schemas/flredecomp.rnc 2012-09-18 19:42:23 +0000
271@@ -30,6 +30,20 @@
272 }
273 }
274 }?,
275+ element field_weighted_partitions {
276+ ## Field weighted partitions: turning on this option allows one to
277+ ## weight mesh partitions, based upon a prescribed scalar field.
278+ ## Note that the field should have a minimum value of 0 and a maximum
279+ ## value of 1 (no normalisation is done within the code).
280+ element scalar_field {
281+ attribute rank { "0" },
282+ attribute name { "FieldWeightedPartitionValues" },
283+ element prescribed {
284+ coordinate_mesh_choice,
285+ prescribed_scalar_field
286+ }
287+ }
288+ }?,
289 ## Zoltan Debugging
290 ##
291 ## Turn on more verbose output for use when debugging Zoltan.
292
293=== modified file 'schemas/flredecomp.rng'
294--- schemas/flredecomp.rng 2011-09-12 11:17:09 +0000
295+++ schemas/flredecomp.rng 2012-09-18 19:42:23 +0000
296@@ -38,6 +38,26 @@
297 </element>
298 </optional>
299 <optional>
300+ <element name="field_weighted_partitions">
301+ <element name="scalar_field">
302+ <a:documentation>Field weighted partitions: turning on this option allows one to
303+weight mesh partitions, based upon a prescribed scalar field.
304+Note that the field should have a minimum value of 0 and a maximum
305+value of 1 (no normalisation is done within the code).</a:documentation>
306+ <attribute name="rank">
307+ <value>0</value>
308+ </attribute>
309+ <attribute name="name">
310+ <value>FieldWeightedPartitionValues</value>
311+ </attribute>
312+ <element name="prescribed">
313+ <ref name="coordinate_mesh_choice"/>
314+ <ref name="prescribed_scalar_field"/>
315+ </element>
316+ </element>
317+ </element>
318+ </optional>
319+ <optional>
320 <element name="zoltan_debug">
321 <a:documentation>Zoltan Debugging
322
323
324=== added directory 'tests/flredecomp_2d_fieldweighted'
325=== added file 'tests/flredecomp_2d_fieldweighted/Makefile'
326--- tests/flredecomp_2d_fieldweighted/Makefile 1970-01-01 00:00:00 +0000
327+++ tests/flredecomp_2d_fieldweighted/Makefile 2012-09-18 19:42:23 +0000
328@@ -0,0 +1,13 @@
329+MODEL=flredecomp-2d-fieldweighted
330+
331+default: input
332+
333+input: clean
334+ gmsh -2 -optimize src/Subduction_Mesh.geo
335+ cp src/Subduction_Mesh.msh .
336+ ../../bin/gmsh2triangle --2d -i Subduction_Mesh.msh
337+
338+clean:
339+ rm -f *.ele *.edge *.node *.vtu *.stat *.msh *.detectors fluidity.* Parallel*
340+ rm -R -f $(MODEL)_*
341+
342
343=== added file 'tests/flredecomp_2d_fieldweighted/check_partitions.py'
344--- tests/flredecomp_2d_fieldweighted/check_partitions.py 1970-01-01 00:00:00 +0000
345+++ tests/flredecomp_2d_fieldweighted/check_partitions.py 2012-09-18 19:42:23 +0000
346@@ -0,0 +1,28 @@
347+#! /usr/bin/env python
348+
349+import sys
350+import numpy
351+
352+num_partitions = 16
353+
354+def calculate_partition_weights():
355+ partition_weights = numpy.zeros(num_partitions,dtype=float)
356+
357+ for i in range(num_partitions):
358+ filename = 'Parallel-NP16-flredecomp-2d-fieldweighted_CoordinateMesh_%d.ele'%i
359+ elements = numpy.loadtxt(filename, skiprows=1)
360+ # Sum weights across each partition.
361+ # Note prognostic region ID == 27: weighting (in .flml) == 1.0
362+ # Prescribed regions ID == 24, 30: weighting (in .flml) == 0.01
363+ for j in range(elements.shape[0]):
364+ if(elements[j,4] == 27):
365+ partition_weights[i] = partition_weights[i] + 1.0
366+ else:
367+ partition_weights[i] = partition_weights[i] + 0.005
368+
369+ min_weight = min(partition_weights)
370+ max_weight = max(partition_weights)
371+ max_load_imbalance = max_weight / min_weight
372+
373+ return max_load_imbalance
374+
375
376=== added file 'tests/flredecomp_2d_fieldweighted/flredecomp-2d-fieldweighted.flml'
377--- tests/flredecomp_2d_fieldweighted/flredecomp-2d-fieldweighted.flml 1970-01-01 00:00:00 +0000
378+++ tests/flredecomp_2d_fieldweighted/flredecomp-2d-fieldweighted.flml 2012-09-18 19:42:23 +0000
379@@ -0,0 +1,410 @@
380+<?xml version='1.0' encoding='utf-8'?>
381+<fluidity_options>
382+ <simulation_name>
383+ <string_value lines="1">flredecomp_field_weighted_partition_test</string_value>
384+ <comment>Checks for field_weighted_partitions in flredecomp and gmsh2triangle -i. </comment>
385+ </simulation_name>
386+ <problem_type>
387+ <string_value lines="1">stokes</string_value>
388+ </problem_type>
389+ <geometry>
390+ <dimension>
391+ <integer_value rank="0">2</integer_value>
392+ </dimension>
393+ <mesh name="CoordinateMesh">
394+ <from_file file_name="Subduction_Mesh">
395+ <format name="triangle"/>
396+ <stat>
397+ <include_in_stat/>
398+ </stat>
399+ </from_file>
400+ </mesh>
401+ <mesh name="VelocityMesh">
402+ <from_mesh>
403+ <mesh name="CoordinateMesh"/>
404+ <mesh_shape>
405+ <polynomial_degree>
406+ <integer_value rank="0">2</integer_value>
407+ </polynomial_degree>
408+ </mesh_shape>
409+ <stat>
410+ <exclude_from_stat/>
411+ </stat>
412+ </from_mesh>
413+ </mesh>
414+ <quadrature>
415+ <degree>
416+ <integer_value rank="0">5</integer_value>
417+ </degree>
418+ </quadrature>
419+ </geometry>
420+ <io>
421+ <dump_format>
422+ <string_value>vtk</string_value>
423+ </dump_format>
424+ <dump_period>
425+ <constant>
426+ <real_value rank="0">2e12</real_value>
427+ </constant>
428+ </dump_period>
429+ <output_mesh name="CoordinateMesh"/>
430+ <stat>
431+ <output_at_start/>
432+ </stat>
433+ <detectors>
434+ <static_detector name="Temperature6060">
435+ <location>
436+ <real_value shape="2" dim1="dim" rank="1">60000. -60000.</real_value>
437+ </location>
438+ </static_detector>
439+ <detector_array name="TSlab">
440+ <number_of_detectors>
441+ <integer_value rank="0">36</integer_value>
442+ </number_of_detectors>
443+ <static/>
444+ <python>
445+ <string_value lines="20" type="code" language="python">def val(t):
446+ import numpy
447+ start = numpy.array([0, 0])
448+ end = numpy.array([210000, -210000])
449+ output = []
450+ for i in range(36):
451+ output.append(start + (float(i)/35) * end)
452+ return output</string_value>
453+ </python>
454+ </detector_array>
455+ <detector_array name="TWedge">
456+ <number_of_detectors>
457+ <integer_value rank="0">78</integer_value>
458+ </number_of_detectors>
459+ <static/>
460+ <python>
461+ <string_value lines="20" type="code" language="python">def val(t):
462+ output1 = []
463+ for i in range(12):
464+ for j in range(12):
465+ if i &gt;= j:
466+ output1.append([54000 + (float(i)/20) * 120000, -54000 + (float(j)/20) * (-120000)])
467+ return output1</string_value>
468+ </python>
469+ </detector_array>
470+ <fail_outside_domain/>
471+ </detectors>
472+ </io>
473+ <timestepping>
474+ <current_time>
475+ <real_value rank="0">0.0</real_value>
476+ </current_time>
477+ <timestep>
478+ <real_value rank="0">1e11</real_value>
479+ </timestep>
480+ <finish_time>
481+ <real_value rank="0">1.0e15</real_value>
482+ </finish_time>
483+ <adaptive_timestep>
484+ <requested_cfl>
485+ <real_value rank="0">3.0</real_value>
486+ </requested_cfl>
487+ <courant_number name="CFLNumber">
488+ <mesh name="CoordinateMesh"/>
489+ </courant_number>
490+ <increase_tolerance>
491+ <real_value rank="0">5</real_value>
492+ </increase_tolerance>
493+ </adaptive_timestep>
494+ <steady_state>
495+ <tolerance>
496+ <real_value rank="0">1e-3</real_value>
497+ <infinity_norm/>
498+ </tolerance>
499+ </steady_state>
500+ </timestepping>
501+ <material_phase name="Fluid">
502+ <scalar_field name="Pressure" rank="0">
503+ <prognostic>
504+ <mesh name="CoordinateMesh"/>
505+ <spatial_discretisation>
506+ <continuous_galerkin>
507+ <remove_stabilisation_term/>
508+ </continuous_galerkin>
509+ </spatial_discretisation>
510+ <scheme>
511+ <poisson_pressure_solution>
512+ <string_value lines="1">never</string_value>
513+ </poisson_pressure_solution>
514+ <use_projection_method>
515+ <full_schur_complement>
516+ <inner_matrix name="FullMomentumMatrix">
517+ <solver>
518+ <iterative_method name="preonly"/>
519+ <preconditioner name="lu"/>
520+ <relative_error>
521+ <real_value rank="0">1.0e-6</real_value>
522+ </relative_error>
523+ <max_iterations>
524+ <integer_value rank="0">10000</integer_value>
525+ </max_iterations>
526+ <start_from_zero/>
527+ <never_ignore_solver_failures/>
528+ <diagnostics>
529+ <monitors/>
530+ </diagnostics>
531+ </solver>
532+ </inner_matrix>
533+ <preconditioner_matrix name="DiagonalSchurComplement"/>
534+ </full_schur_complement>
535+ </use_projection_method>
536+ </scheme>
537+ <solver>
538+ <iterative_method name="fgmres"/>
539+ <preconditioner name="jacobi"/>
540+ <relative_error>
541+ <real_value rank="0">1.0e-4</real_value>
542+ </relative_error>
543+ <max_iterations>
544+ <integer_value rank="0">10000</integer_value>
545+ </max_iterations>
546+ <never_ignore_solver_failures/>
547+ <diagnostics>
548+ <monitors/>
549+ </diagnostics>
550+ </solver>
551+ <output/>
552+ <stat/>
553+ <convergence>
554+ <include_in_convergence/>
555+ </convergence>
556+ <detectors>
557+ <exclude_from_detectors/>
558+ </detectors>
559+ <steady_state>
560+ <exclude_from_steady_state/>
561+ </steady_state>
562+ <consistent_interpolation/>
563+ </prognostic>
564+ </scalar_field>
565+ <vector_field name="Velocity" rank="1">
566+ <prognostic>
567+ <mesh name="VelocityMesh"/>
568+ <equation name="LinearMomentum"/>
569+ <spatial_discretisation>
570+ <continuous_galerkin>
571+ <stabilisation>
572+ <no_stabilisation/>
573+ </stabilisation>
574+ <mass_terms>
575+ <exclude_mass_terms/>
576+ </mass_terms>
577+ <advection_terms>
578+ <exclude_advection_terms/>
579+ </advection_terms>
580+ <stress_terms>
581+ <tensor_form/>
582+ </stress_terms>
583+ </continuous_galerkin>
584+ <conservative_advection>
585+ <real_value rank="0">1.0</real_value>
586+ </conservative_advection>
587+ </spatial_discretisation>
588+ <temporal_discretisation>
589+ <theta>
590+ <real_value rank="0">1.0</real_value>
591+ </theta>
592+ <relaxation>
593+ <real_value rank="0">1.0</real_value>
594+ </relaxation>
595+ </temporal_discretisation>
596+ <solver>
597+ <iterative_method name="preonly"/>
598+ <preconditioner name="lu"/>
599+ <relative_error>
600+ <real_value rank="0">1.0e-6</real_value>
601+ </relative_error>
602+ <max_iterations>
603+ <integer_value rank="0">10000</integer_value>
604+ </max_iterations>
605+ <never_ignore_solver_failures/>
606+ <diagnostics>
607+ <monitors/>
608+ </diagnostics>
609+ </solver>
610+ <initial_condition name="Batchelor">
611+ <region_ids>
612+ <integer_value shape="1" rank="1">27</integer_value>
613+ </region_ids>
614+ <python>
615+ <string_value lines="20" type="code" language="python">def val(X, t):
616+
617+ from math import sqrt, atan, cos, sin, pi
618+
619+ Xcoord = X[0]
620+ Ycoord = X[1]
621+
622+ Depth = (X[1] * -1.) -50000.
623+ Xdist = X[0] -50000.
624+
625+ if(Xdist == 0.) :
626+ Xdist = 0.000000000000001
627+
628+ if Depth == 0 :
629+
630+ Vx = 0.
631+ Vy = 0.
632+
633+ else :
634+
635+ ALFA = atan(1)
636+ THETA = atan(Depth/Xdist)
637+
638+ VTHETA = (((ALFA - THETA) * sin(THETA) * sin(ALFA)) - (ALFA * THETA * sin(ALFA-THETA))) / (ALFA**2 - (sin(ALFA)**2))
639+ VTHETA = VTHETA * (0.05/(3600.*24.*365.)) *-1.
640+
641+ VR = (((ALFA - THETA) * cos(THETA) * sin(ALFA)) - (sin(ALFA) * sin(THETA)) - (ALFA * sin(ALFA-THETA)) + (ALFA*THETA*cos(ALFA-THETA))) / ((ALFA**2) - (sin(ALFA))**2)
642+ VR = VR * (0.05/(3600.*24.*365.))
643+
644+ Vx = -( VTHETA*sin(THETA) - VR*cos(THETA) )
645+ Vy = - (VTHETA*cos(THETA) + VR*sin(THETA) )
646+
647+ return [Vx, Vy]</string_value>
648+ </python>
649+ </initial_condition>
650+ <prescribed_region name="Crust">
651+ <region_ids>
652+ <integer_value shape="1" rank="1">24</integer_value>
653+ </region_ids>
654+ <constant>
655+ <real_value shape="2" dim1="dim" rank="1">0. 0.</real_value>
656+ </constant>
657+ </prescribed_region>
658+ <prescribed_region name="Slab">
659+ <region_ids>
660+ <integer_value shape="1" rank="1">30</integer_value>
661+ </region_ids>
662+ <python>
663+ <string_value lines="20" type="code" language="python">def val(X, t):
664+ from math import sqrt
665+ vx = sqrt(((0.05/(3600.*24.*365.))**2.)/2.)
666+ vy = -sqrt(((0.05/(3600.*24.*365.))**2.)/2.)
667+ return [vx,vy]</string_value>
668+ </python>
669+ </prescribed_region>
670+ <boundary_conditions name="Crust">
671+ <surface_ids>
672+ <integer_value shape="1" rank="1">32</integer_value>
673+ </surface_ids>
674+ <type name="dirichlet">
675+ <align_bc_with_cartesian>
676+ <x_component>
677+ <constant>
678+ <real_value rank="0">0.0</real_value>
679+ </constant>
680+ </x_component>
681+ <y_component>
682+ <constant>
683+ <real_value rank="0">0.0</real_value>
684+ </constant>
685+ </y_component>
686+ </align_bc_with_cartesian>
687+ </type>
688+ </boundary_conditions>
689+ <boundary_conditions name="Slab">
690+ <surface_ids>
691+ <integer_value shape="1" rank="1">31</integer_value>
692+ </surface_ids>
693+ <type name="dirichlet">
694+ <align_bc_with_cartesian>
695+ <x_component>
696+ <python>
697+ <string_value lines="20" type="code" language="python">def val(X, t):
698+ from math import sqrt
699+ vx = sqrt(((0.05/(3600.*24.*365.))**2.)/2.)
700+ return vx</string_value>
701+ </python>
702+ </x_component>
703+ <y_component>
704+ <python>
705+ <string_value lines="20" type="code" language="python">def val(X, t):
706+ from math import sqrt
707+ vy = -sqrt(((0.05/(3600.*24.*365.))**2.)/2.)
708+ return vy</string_value>
709+ </python>
710+ </y_component>
711+ </align_bc_with_cartesian>
712+ </type>
713+ </boundary_conditions>
714+ <tensor_field name="Viscosity" rank="2">
715+ <prescribed>
716+ <value name="WholeMesh">
717+ <isotropic>
718+ <constant>
719+ <real_value rank="0">1.0e21</real_value>
720+ </constant>
721+ </isotropic>
722+ </value>
723+ <output/>
724+ </prescribed>
725+ </tensor_field>
726+ <output/>
727+ <stat>
728+ <include_in_stat/>
729+ <surface_integral type="normal" name="Outflow">
730+ <surface_ids>
731+ <integer_value shape="2" rank="1">13 16</integer_value>
732+ </surface_ids>
733+ </surface_integral>
734+ <surface_integral type="normal" name="All">
735+ <surface_ids>
736+ <integer_value shape="3" rank="1">12 13 16</integer_value>
737+ </surface_ids>
738+ </surface_integral>
739+ <previous_time_step>
740+ <exclude_from_stat/>
741+ </previous_time_step>
742+ <nonlinear_field>
743+ <exclude_from_stat/>
744+ </nonlinear_field>
745+ </stat>
746+ <convergence>
747+ <include_in_convergence/>
748+ </convergence>
749+ <detectors>
750+ <include_in_detectors/>
751+ </detectors>
752+ <steady_state>
753+ <include_in_steady_state/>
754+ </steady_state>
755+ <consistent_interpolation/>
756+ </prognostic>
757+ </vector_field>
758+ </material_phase>
759+ <flredecomp>
760+ <field_weighted_partitions>
761+ <scalar_field name="FieldWeightedPartitionValues" rank="0">
762+ <prescribed>
763+ <mesh name="CoordinateMesh"/>
764+ <value name="Prognostic_Regions">
765+ <region_ids>
766+ <integer_value shape="1" rank="1">27</integer_value>
767+ </region_ids>
768+ <constant>
769+ <real_value rank="0">1.</real_value>
770+ </constant>
771+ </value>
772+ <value name="Prescribed_Regions">
773+ <region_ids>
774+ <integer_value shape="2" rank="1">24 30</integer_value>
775+ </region_ids>
776+ <constant>
777+ <real_value rank="0">0.005</real_value>
778+ </constant>
779+ </value>
780+ <output/>
781+ <stat/>
782+ <detectors>
783+ <exclude_from_detectors/>
784+ </detectors>
785+ </prescribed>
786+ </scalar_field>
787+ </field_weighted_partitions>
788+ </flredecomp>
789+</fluidity_options>
790
791=== added file 'tests/flredecomp_2d_fieldweighted/flredecomp_2d_fieldweighted.xml'
792--- tests/flredecomp_2d_fieldweighted/flredecomp_2d_fieldweighted.xml 1970-01-01 00:00:00 +0000
793+++ tests/flredecomp_2d_fieldweighted/flredecomp_2d_fieldweighted.xml 2012-09-18 19:42:23 +0000
794@@ -0,0 +1,25 @@
795+<?xml version='1.0' encoding='utf-8'?>
796+<testproblem>
797+ <name>flredecomp-2d-fieldweighted</name>
798+ <owner userid="rhodrid"/>
799+ <tags>flml</tags>
800+
801+ <problem_definition length="medium" nprocs="1">
802+ <command_line>mpiexec -n 16 flredecomp -i 1 -o 16 flredecomp-2d-fieldweighted Parallel-NP16-flredecomp-2d-fieldweighted</command_line>
803+ </problem_definition>
804+
805+ <variables>
806+ <variable name="max_load_imbalance" language="python">
807+from check_partitions import *
808+max_load_imbalance = calculate_partition_weights()
809+ <comment>Calculates the weight of each partition (i.e. sums weights of elements in each partition). The weights are prescribed in the flml to be 1.0 for region 27, and 0.005 elsewhere.</comment>
810+ </variable>
811+ </variables>
812+
813+ <pass_tests>
814+ <test name="maximum load imbalance .lt. 1.5 " language="python">
815+ assert ( max_load_imbalance &lt; 1.5 )
816+ </test>
817+ </pass_tests>
818+
819+</testproblem>
820
821=== added directory 'tests/flredecomp_2d_fieldweighted/src'
822=== added file 'tests/flredecomp_2d_fieldweighted/src/Subduction_Mesh.geo'
823--- tests/flredecomp_2d_fieldweighted/src/Subduction_Mesh.geo 1970-01-01 00:00:00 +0000
824+++ tests/flredecomp_2d_fieldweighted/src/Subduction_Mesh.geo 2012-09-18 19:42:23 +0000
825@@ -0,0 +1,52 @@
826+// Gmsh project created on Fri Dec 4 14:59:47 2009
827+// We reproduce a subduction zone on a (660x600) km domain.
828+// The kinematically moving slab (see image, on the left) subducts under a 50km-thick plate (up, right) and hence dynamically inducing a flow in the upper-mantle wedge (down, on the right).
829+// We therefore are trying to match the benchmark results established by vanKeken2008 for this problem, computing the thermal field throughout the domain by use of finite element methods.
830+// The structured, non-adaptive mesh shown in the images contains for instance the sought information at the mesh nodes, spaced out 2.5 km from each other near the critical point of contact between the three// different regions of our domain, and 7.5km everywhere else. In this particular case, the test uses a prescribed wedge flow (Batchelor1967) and is mainly intended to check for the validity of initial condi// tions at the various boundaries.
831+
832+minsize=4000;
833+maxsize=4000;
834+
835+Point(1) = {0,0,0,minsize};
836+Point(2) = {660000,0,0,maxsize};
837+Point(3) = {660000,-50000,0,maxsize};
838+Point(4) = {660000,-600000,0,maxsize};
839+Point(5) = {600000,-600000,0,maxsize};
840+Point(6) = {0,-600000,0,maxsize};
841+Point(7) = {50000,-50000,0,minsize};
842+Point(8) = {660000,-420000,0,maxsize};
843+
844+Line(1) = {1,2};
845+Line(2) = {2,3};
846+Line(3) = {3,8};
847+Line(4) = {4,5};
848+Line(5) = {5,6};
849+Line(7) = {1,7};
850+Line(9) = {7,3};
851+Line(10) = {8,4};
852+Line(11) = {7,5};
853+Line(14) = {6,1};
854+
855+Physical Line(10) = {1};
856+Physical Line(11) = {2};
857+Physical Line(12) = {3};
858+Physical Line(13) = {4};
859+Physical Line(19) = {5};
860+Physical Line(15) = {14};
861+Physical Line(16) = {10};
862+// Physical Line(17) = {9};
863+// Physical Line(18) = {11};
864+// Physical Line(20) = {7};
865+
866+Line Loop(22) = {1,2,-9,-7};
867+Plane Surface(23) = {22};
868+Physical Surface(24) = {23};
869+Line Loop(25) = {9,3,10,4,-11};
870+Plane Surface(26) = {25};
871+Physical Surface(27) = {26};
872+Line Loop(28) = {5,14,7,11};
873+Plane Surface(29) = {28};
874+Physical Surface(30) = {29};
875+
876+Physical Line(31) = {11};
877+Physical Line(32) = {9};