Merge lp:~g-bhutani12/fluidity/PBM into lp:fluidity
- PBM
- Merge into dev-trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~g-bhutani12/fluidity/PBM |
Merge into: | lp:fluidity |
Diff against target: |
8540 lines (+7592/-53) 66 files modified
Makefile.in (+7/-0) assemble/Adapt_State.F90 (+8/-2) assemble/Diagnostic_fields_wrapper.F90 (+7/-1) assemble/Multiphase.F90 (+86/-18) configure (+2/-1) configure.in (+1/-0) diagnostics/Multiphase_Diagnostics.F90 (+21/-3) examples/tephra_settling/tephra_settling.flml (+3/-1) main/Fluids.F90 (+20/-1) population_balance/DQMOM.F90 (+999/-0) population_balance/Makefile.dependencies (+10/-0) population_balance/Makefile.in (+66/-0) preprocessor/Field_Priority_Lists.F90 (+42/-0) preprocessor/Populate_State.F90 (+23/-2) schemas/diagnostic_algorithms.rnc (+2/-1) schemas/diagnostic_algorithms.rng (+8/-1) schemas/fluidity_options.rnc (+448/-2) schemas/fluidity_options.rng (+649/-1) schemas/multiphase_interaction.rnc (+6/-1) schemas/multiphase_interaction.rng (+7/-0) tests/mphase_dusty_gas_shock_tube/mphase_dusty_gas_shock_tube.flml (+6/-2) tests/mphase_inlet_velocity_bc_compressible/mphase_inlet_velocity_bc_compressible.flml (+3/-1) tests/mphase_rogue_shock_tube_dense_bed_glass/mphase_rogue_shock_tube_dense_bed_glass.flml (+3/-1) tests/mphase_rogue_shock_tube_dense_bed_nylon/mphase_rogue_shock_tube_dense_bed_nylon.flml (+3/-1) tests/mphase_stokes_law/mphase_stokes_law.flml (+6/-2) tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p0p1.flml (+3/-1) tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p2p1.flml (+3/-1) tests/mphase_subtract_out_reference_profile/mphase_subtract_out_reference_profile_1d.flml (+3/-1) tests/mphase_tephra_settling/mphase_tephra_settling.flml (+6/-2) tests/mphase_wen_yu_drag_correlation/mphase_wen_yu_drag_correlation.flml (+6/-2) tests/popbal_homog_brk_aggr/Makefile (+5/-0) tests/popbal_homog_brk_aggr/popbal_homog_N2.flml (+723/-0) tests/popbal_homog_brk_aggr/popbal_homog_N2_brk_aggr.xml (+34/-0) tests/popbal_homog_brk_aggr/src/minimal.geo (+28/-0) tests/popbal_nonhomog2_2d_adapt/Makefile (+5/-0) tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.flml (+670/-0) tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.xml (+46/-0) tests/popbal_nonhomog2_2d_adapt/readme (+13/-0) tests/popbal_nonhomog2_2d_adapt/src/channel.geo (+16/-0) tests/popbal_nonhomog2_2d_cg_p1/Makefile (+5/-0) tests/popbal_nonhomog2_2d_cg_p1/popbal_nonhomog2_2d.flml (+614/-0) tests/popbal_nonhomog2_2d_cg_p1/popbal_nonhomog2_2d_cg_p1.xml (+46/-0) tests/popbal_nonhomog2_2d_cg_p1/readme (+12/-0) tests/popbal_nonhomog2_2d_cg_p1/src/channel.geo (+16/-0) tests/popbal_nonhomog2_2d_cg_p2/Makefile (+5/-0) tests/popbal_nonhomog2_2d_cg_p2/popbal_nonhomog2_2d.flml (+633/-0) tests/popbal_nonhomog2_2d_cg_p2/popbal_nonhomog2_2d_cg_p2.xml (+46/-0) tests/popbal_nonhomog2_2d_cg_p2/readme (+12/-0) tests/popbal_nonhomog2_2d_cg_p2/src/channel.geo (+16/-0) tests/popbal_nonhomog2_2d_dg_p1/Makefile (+5/-0) tests/popbal_nonhomog2_2d_dg_p1/popbal_nonhomog2_2d.flml (+630/-0) tests/popbal_nonhomog2_2d_dg_p1/popbal_nonhomog2_2d_dg_p1.xml (+46/-0) tests/popbal_nonhomog2_2d_dg_p1/readme (+11/-0) tests/popbal_nonhomog2_2d_dg_p1/src/channel.geo (+16/-0) tests/popbal_nonhomog2_2d_dg_p2/Makefile (+5/-0) tests/popbal_nonhomog2_2d_dg_p2/popbal_nonhomog2_2d.flml (+630/-0) tests/popbal_nonhomog2_2d_dg_p2/popbal_nonhomog2_2d_dg_p2.xml (+45/-0) tests/popbal_nonhomog2_2d_dg_p2/readme (+11/-0) tests/popbal_nonhomog2_2d_dg_p2/src/channel.geo (+16/-0) tests/popbal_nonhomog2_2d_dg_p2/time_versus_norm (+20/-0) tests/popbal_nonhomog_2d_cg_p1/Makefile (+5/-0) tests/popbal_nonhomog_2d_cg_p1/popbal_nonhomog_2d.flml (+672/-0) tests/popbal_nonhomog_2d_cg_p1/popbal_nonhomog_2d_cg_p1.xml (+46/-0) tests/popbal_nonhomog_2d_cg_p1/readme (+12/-0) tests/popbal_nonhomog_2d_cg_p1/src/channel.geo (+17/-0) tools/Supermesh_Difference.F90 (+3/-4) |
To merge this branch: | bzr merge lp:~g-bhutani12/fluidity/PBM |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
sam | Pending | ||
Review via email: mp+183296@code.launchpad.net |
Commit message
Description of the change
A fully functional population balance modelling capability has been added to Fluidity, It is based on the famous Direct Quadrature Method of Moments (DQMOM) by Marchisio and Fox (2005). Currently it can solve population balance equations with one internal variable. Support for multiple internal variables will be added at a later stage (1-2 years time). The branch has been tested for adaptivity and parallel runs.
- 4210. By Gaurav Bhutani
-
Removed some old test cases
- 4211. By Gaurav Bhutani
-
Merge with trunk
- 4212. By Gaurav Bhutani
-
Removed a few old test cases
- 4213. By Gaurav Bhutani
-
Changes made to diamond tree in Multiphase options to accept a scalar field for partcle diameter (only accepted a constant earlier). Multiphase.F90 modified to accept a scalar field as particle diameter and use it in drag force term calculations for momentum equations; the file has also been modified for new diamond structure. Multiphase test cases modified to suit modified diamond structure. All tests passed with this new modifications.
- 4214. By Gaurav Bhutani
-
Included the scalar field -- SauterMeanDia -- in the list of statistics. Modified the comparison conditions for other statistics to exact string comparison. Modified the rnc file to include the scalar field called SauterMeanDia in the list of statistics. SauterMeanDia has been added to the statistics so that it can be calculated after every non-linear iteration in Fluids.F90 and the new sauter mean diameter be used in the momentum calculations.
- 4215. By Gaurav Bhutani
-
Changes to Fluids.F90 to call dqmom_calculate
_moments( ) and dqmom_calculate _statistics inside the nonlinear loop. This updates the SauterMeanDia after every nonlinear iteration to be used in the drag force term in the momentum equation in next nonlinear iteration. - 4216. By Gaurav Bhutani
-
Corrected the PD algorithm implementation in DQMOM.F90
Gaurav Bhutani (g-bhutani12) wrote : | # |
Hi Tim,
Yes, I have been working on the branch recently to couple it with Multiphase.F90.
Apologies, I completely forgot to change the status of it to WIP.
Thanks for that.
I will propose it for a merge very soon with all the documentation and test cases in it.
Regards,
Gaurav
_______
From: <email address hidden> [<email address hidden>] on behalf of Tim Greaves [<email address hidden>]
Sent: 01 November 2013 17:41
To: Bhutani, Gaurav
Subject: Re: [Merge] lp:~g-bhutani12/fluidity/PBM into lp:fluidity
Hi Gaurav -- given this was proposed more than a couple of months ago and looks to be in active development at the moment I'm setting it back to 'in progress'; if you get to the point you want to move for a review and merge, please do set back to 'needs review'.
--
https:/
You are the owner of lp:~g-bhutani12/fluidity/PBM.
- 4217. By Gaurav Bhutani
-
Included a breakage kernel as used by McCoy and Madras (2003) for the daughter distribution function. Also corrected the aggregation birth term contribution into source to handle negative abscissas and their cube roots.
- 4218. By Gaurav Bhutani
-
Added a test case for homogeneous population balance with breakage and aggregation. The analytical solution of McCoy and Madras (2003) was used to compare against the numerical results.
- 4219. By Gaurav Bhutani
-
Added saling factor to scale Sauter Mean Diameter in case of non-dimensional implementation of PBE.
- 4220. By Gaurav Bhutani
-
Added modified Schiller & Naumann (1933) interphase drag coefficient to Multiphase.F90 as implemented in ANSYS CFX. Changes made to diamond tree for the option for this new drag coefficient. Slight change in Multiphase.F90 to change defualt to default in a switch-case statement.
- 4221. By Gaurav Bhutani
-
Slight change to Schiller-Naumann (1933) drag implementation - multiplied by the volume fraction of continuous phase in drag force term as done by Abbasi et. al. (2013).
- 4222. By Gaurav Bhutani
-
PBM: Added a sum_aggregation kernel as implemented by Abbasi et. al. (2013). Also added the population balance statistic called MeanDia10 (d_10). DQMOM.F90 and fluidity_
oprions. rnc modified for the two changes. - 4223. By Gaurav Bhutani
-
Modified Multiphase_
Diagnostics. F90 to allow particle_ reynolds_ number to take a scalar field for particle diameter. schemas/ diagnostic_ algorithms. rnc was also modified for the same reason. flml in 4 test cases in multiphase were modified as per the schema modifications.
Unmerged revisions
- 4223. By Gaurav Bhutani
-
Modified Multiphase_
Diagnostics. F90 to allow particle_ reynolds_ number to take a scalar field for particle diameter. schemas/ diagnostic_ algorithms. rnc was also modified for the same reason. flml in 4 test cases in multiphase were modified as per the schema modifications. - 4222. By Gaurav Bhutani
-
PBM: Added a sum_aggregation kernel as implemented by Abbasi et. al. (2013). Also added the population balance statistic called MeanDia10 (d_10). DQMOM.F90 and fluidity_
oprions. rnc modified for the two changes. - 4221. By Gaurav Bhutani
-
Slight change to Schiller-Naumann (1933) drag implementation - multiplied by the volume fraction of continuous phase in drag force term as done by Abbasi et. al. (2013).
- 4220. By Gaurav Bhutani
-
Added modified Schiller & Naumann (1933) interphase drag coefficient to Multiphase.F90 as implemented in ANSYS CFX. Changes made to diamond tree for the option for this new drag coefficient. Slight change in Multiphase.F90 to change defualt to default in a switch-case statement.
- 4219. By Gaurav Bhutani
-
Added saling factor to scale Sauter Mean Diameter in case of non-dimensional implementation of PBE.
- 4218. By Gaurav Bhutani
-
Added a test case for homogeneous population balance with breakage and aggregation. The analytical solution of McCoy and Madras (2003) was used to compare against the numerical results.
- 4217. By Gaurav Bhutani
-
Included a breakage kernel as used by McCoy and Madras (2003) for the daughter distribution function. Also corrected the aggregation birth term contribution into source to handle negative abscissas and their cube roots.
- 4216. By Gaurav Bhutani
-
Corrected the PD algorithm implementation in DQMOM.F90
- 4215. By Gaurav Bhutani
-
Changes to Fluids.F90 to call dqmom_calculate
_moments( ) and dqmom_calculate _statistics inside the nonlinear loop. This updates the SauterMeanDia after every nonlinear iteration to be used in the drag force term in the momentum equation in next nonlinear iteration. - 4214. By Gaurav Bhutani
-
Included the scalar field -- SauterMeanDia -- in the list of statistics. Modified the comparison conditions for other statistics to exact string comparison. Modified the rnc file to include the scalar field called SauterMeanDia in the list of statistics. SauterMeanDia has been added to the statistics so that it can be calculated after every non-linear iteration in Fluids.F90 and the new sauter mean diameter be used in the momentum calculations.
Preview Diff
1 | === modified file 'Makefile.in' |
2 | --- Makefile.in 2013-11-13 00:28:27 +0000 |
3 | +++ Makefile.in 2013-12-12 22:35:40 +0000 |
4 | @@ -310,6 +310,8 @@ |
5 | @cd horizontal_adaptivity; $(MAKE) |
6 | @echo " MAKE preprocessor" |
7 | @cd preprocessor; $(MAKE) |
8 | + @echo " MAKE population_balance" |
9 | + @cd population_balance; $(MAKE) |
10 | @echo " MAKE error_measures" |
11 | @cd error_measures; $(MAKE) |
12 | @echo " MAKE assemble" |
13 | @@ -340,6 +342,7 @@ |
14 | forward_interfaces/*.o \ |
15 | horizontal_adaptivity/*.o \ |
16 | preprocessor/*.o \ |
17 | +population_balance/*.o \ |
18 | error_measures/*.o \ |
19 | assemble/*.o \ |
20 | diagnostics/*.o \ |
21 | @@ -387,6 +390,8 @@ |
22 | @cd diagnostics; $(MAKE) clean |
23 | @echo " CLEAN preprocessor" |
24 | @cd preprocessor; $(MAKE) clean |
25 | + @echo " CLEAN population_balance" |
26 | + @cd population_balance; $(MAKE) clean |
27 | @echo " CLEAN error_measures/tests" |
28 | @cd error_measures/tests; $(MAKE) clean |
29 | @echo " CLEAN error_measures" |
30 | @@ -588,6 +593,8 @@ |
31 | @echo " Generating preprocessor dependencies" |
32 | @cd preprocessor; ../bin/create_makefile --exclude \ |
33 | "register_diagnostics.F90 check_options.F90" $(TESTOPTS) |
34 | + @echo " Generating population_balance dependencies" |
35 | + @cd population_balance; ../bin/create_makefile $(TESTOPTS) |
36 | @echo " Generating error_measures dependencies" |
37 | @cd error_measures; ../bin/create_makefile $(TESTOPTS) |
38 | @echo " Generating assemble dependencies" |
39 | |
40 | === modified file 'assemble/Adapt_State.F90' |
41 | --- assemble/Adapt_State.F90 2013-11-13 01:51:23 +0000 |
42 | +++ assemble/Adapt_State.F90 2013-12-12 22:35:40 +0000 |
43 | @@ -74,6 +74,7 @@ |
44 | use diagnostic_fields_wrapper_new, only : calculate_diagnostic_variables_new => calculate_diagnostic_variables |
45 | use pickers |
46 | use write_gmsh |
47 | + use dqmom |
48 | #ifdef HAVE_ZOLTAN |
49 | use zoltan_integration |
50 | use mpi_interfaces |
51 | @@ -878,7 +879,7 @@ |
52 | type(state_type), dimension(:), intent(inout) :: states |
53 | |
54 | character(len = *), parameter :: base_path = "/mesh_adaptivity/hr_adaptivity/adapt_at_first_timestep" |
55 | - integer :: adapt_iterations, i |
56 | + integer :: adapt_iterations, i, i_state |
57 | type(mesh_type), pointer :: old_mesh |
58 | type(tensor_field) :: metric |
59 | type(vector_field), pointer :: output_positions |
60 | @@ -896,7 +897,6 @@ |
61 | call copy_to_stored_values(states,"Old") |
62 | call copy_to_stored_values(states,"Iterated") |
63 | call relax_to_nonlinear(states) |
64 | - |
65 | call calculate_diagnostic_variables(states) |
66 | call calculate_diagnostic_variables_new(states) |
67 | |
68 | @@ -916,6 +916,12 @@ |
69 | ! Adapt state, initialising fields from the options tree rather than |
70 | ! interpolating them |
71 | call adapt_state(states, metric, initialise_fields = .true.) |
72 | + |
73 | + ! dqmom_init helps to recalculate the abscissas and weights based on moment initial conditions (if provided) |
74 | + call dqmom_init(states) |
75 | +! do i_state = 1, option_count("/material_phase") |
76 | +! call dqmom_calculate_moments(states(i_state)) |
77 | +! end do |
78 | end do |
79 | |
80 | if(have_option(trim(base_path) // "/output_adapted_mesh")) then |
81 | |
82 | === modified file 'assemble/Diagnostic_fields_wrapper.F90' |
83 | --- assemble/Diagnostic_fields_wrapper.F90 2013-04-16 11:38:41 +0000 |
84 | +++ assemble/Diagnostic_fields_wrapper.F90 2013-12-12 22:35:40 +0000 |
85 | @@ -54,6 +54,7 @@ |
86 | use momentum_diagnostic_fields |
87 | use spontaneous_potentials, only: calculate_formation_conductivity |
88 | use sediment_diagnostics |
89 | + use dqmom |
90 | use geostrophic_pressure |
91 | use multiphase_module |
92 | |
93 | @@ -80,7 +81,7 @@ |
94 | type(state_type), dimension(:), pointer :: submaterials |
95 | |
96 | ewrite(1, *) "In calculate_diagnostic_variables" |
97 | - |
98 | + |
99 | do i = 1, size(state) |
100 | |
101 | ! start of fields that can be called through the generic calculate_diagnostic_variable |
102 | @@ -562,6 +563,11 @@ |
103 | call calculate_sediment_active_layer_volume_fractions(state(i)) |
104 | end if |
105 | ! End of sediment diagnostics. |
106 | + |
107 | + ! Start of population balance diagnostics. |
108 | + call dqmom_calculate_moments(state(i)) |
109 | + call dqmom_calculate_statistics(state(i)) |
110 | + ! End of population balance diagnostics. |
111 | |
112 | ! Multiphase-related diagnostic fields |
113 | s_field => extract_scalar_field(state(i), "PhaseVolumeFraction", stat) |
114 | |
115 | === modified file 'assemble/Multiphase.F90' |
116 | --- assemble/Multiphase.F90 2013-03-03 01:36:16 +0000 |
117 | +++ assemble/Multiphase.F90 2013-12-12 22:35:40 +0000 |
118 | @@ -284,9 +284,10 @@ |
119 | |
120 | ! Types of drag correlation |
121 | integer, parameter :: DRAG_CORRELATION_TYPE_STOKES = 1, DRAG_CORRELATION_TYPE_WEN_YU = 2, DRAG_CORRELATION_TYPE_ERGUN = 3 |
122 | + integer, parameter :: DRAG_CORRELATION_TYPE_SCHILLER_NAUMANN = 4 |
123 | |
124 | ewrite(1, *) "Entering add_fluid_particle_drag" |
125 | - |
126 | + |
127 | ! Let's check whether we actually have at least one particle phase. |
128 | if(option_count("/material_phase/multiphase_properties/particle_diameter") == 0) then |
129 | FLExit("Fluid-particle drag enabled but no particle_diameter has been specified for the particle phase(s).") |
130 | @@ -357,6 +358,8 @@ |
131 | |
132 | type(scalar_field), pointer :: vfrac_fluid, vfrac_particle |
133 | type(scalar_field), pointer :: density_fluid, density_particle |
134 | + type(scalar_field), pointer :: pd_scalar_field ! scalar field defining particle diameter |
135 | + |
136 | type(vector_field), pointer :: velocity_fluid, velocity_particle |
137 | type(vector_field), pointer :: oldu_fluid, oldu_particle |
138 | type(vector_field), pointer :: nu_fluid, nu_particle ! Non-linear approximation to the Velocities |
139 | @@ -364,7 +367,9 @@ |
140 | type(scalar_field) :: nvfrac_fluid, nvfrac_particle |
141 | real :: d ! Particle diameter |
142 | character(len=OPTION_PATH_LEN) :: drag_correlation_name |
143 | + character(len=OPTION_PATH_LEN) :: pd_field_name ! name of scalar field that defines particle diameter (can be the sauter mean dia) |
144 | integer :: drag_correlation |
145 | + logical :: have_constant_pd ! checks if the particle diameter is a constant or not |
146 | |
147 | ! Get the necessary fields to calculate the drag force |
148 | velocity_fluid => extract_vector_field(state(istate_fluid), "Velocity") |
149 | @@ -376,8 +381,15 @@ |
150 | density_fluid => extract_scalar_field(state(istate_fluid), "Density") |
151 | density_particle => extract_scalar_field(state(istate_particle), "Density") |
152 | viscosity_fluid => extract_tensor_field(state(istate_fluid), "Viscosity") |
153 | - |
154 | - call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter", d) |
155 | + |
156 | + if(have_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/constant")) then |
157 | + call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/constant", d) |
158 | + have_constant_pd = .true. |
159 | + else if(have_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/use_scalar_field")) then |
160 | + call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/use_scalar_field", pd_field_name) |
161 | + pd_scalar_field => extract_scalar_field(state(istate_particle), pd_field_name) |
162 | + have_constant_pd = .false. |
163 | + end if |
164 | |
165 | ! Calculate the non-linear approximation to the PhaseVolumeFractions |
166 | call allocate(nvfrac_fluid, vfrac_fluid%mesh, "NonlinearPhaseVolumeFraction") |
167 | @@ -401,7 +413,9 @@ |
168 | drag_correlation = DRAG_CORRELATION_TYPE_WEN_YU |
169 | case("ergun") |
170 | drag_correlation = DRAG_CORRELATION_TYPE_ERGUN |
171 | - case("default") |
172 | + case("schiller_naumann") |
173 | + drag_correlation = DRAG_CORRELATION_TYPE_SCHILLER_NAUMANN |
174 | + case default |
175 | FLAbort("Unknown correlation for fluid-particle drag") |
176 | end select |
177 | |
178 | @@ -420,7 +434,9 @@ |
179 | density_fluid, density_particle, & |
180 | nu_fluid, nu_particle, & |
181 | oldu_fluid, oldu_particle, & |
182 | - viscosity_fluid, d, drag_correlation) |
183 | + viscosity_fluid, & |
184 | + have_constant_pd, d, pd_scalar_field, & |
185 | + drag_correlation) |
186 | end if |
187 | |
188 | end do element_loop |
189 | @@ -438,7 +454,9 @@ |
190 | density_fluid, density_particle, & |
191 | nu_fluid, nu_particle, & |
192 | oldu_fluid, oldu_particle, & |
193 | - viscosity_fluid, d, drag_correlation) |
194 | + viscosity_fluid, & |
195 | + have_constant_pd, dia, pd_scalar_field, & |
196 | + drag_correlation) |
197 | |
198 | integer, intent(in) :: ele |
199 | type(element_type), intent(in) :: test_function |
200 | @@ -449,12 +467,14 @@ |
201 | |
202 | type(scalar_field), intent(in) :: vfrac_fluid, vfrac_particle |
203 | type(scalar_field), intent(in) :: density_fluid, density_particle |
204 | + type(scalar_field), intent(in) :: pd_scalar_field ! Scalar field representing particle diameter |
205 | type(vector_field), intent(in) :: nu_fluid, nu_particle |
206 | type(vector_field), intent(in) :: oldu_fluid, oldu_particle |
207 | type(tensor_field), intent(in) :: viscosity_fluid |
208 | - real, intent(in) :: d ! Particle diameter |
209 | + real, intent(in) :: dia ! Constant particle diameter |
210 | integer, intent(in) :: drag_correlation |
211 | - |
212 | + logical, intent(in) :: have_constant_pd ! is true if particle diameter is a constant. is false if it is a scalar field (e.g. sauter mean dia) |
213 | + |
214 | ! Local variables |
215 | real, dimension(ele_ngi(u,ele)) :: vfrac_fluid_gi, vfrac_particle_gi |
216 | real, dimension(ele_ngi(u,ele)) :: density_fluid_gi, density_particle_gi |
217 | @@ -473,6 +493,7 @@ |
218 | real, dimension(ele_ngi(u,ele)) :: particle_re_gi ! Particle Reynolds number |
219 | real, dimension(ele_ngi(u,ele)) :: drag_coefficient_gi |
220 | real, dimension(ele_ngi(u,ele)) :: magnitude_gi ! |v_f - v_p| |
221 | + real, dimension(ele_ngi(u,ele)) :: d_gi ! particle diameter at the Gauss points |
222 | |
223 | real, dimension(ele_ngi(u,ele)) :: K |
224 | real, dimension(ele_ngi(u,ele)) :: drag_force_big_m |
225 | @@ -497,9 +518,16 @@ |
226 | magnitude_gi(gi) = norm2(nu_fluid_gi(:,gi) - nu_particle_gi(:,gi)) |
227 | end do |
228 | |
229 | + ! Compute the particle diameter at the Gauss points |
230 | + if(have_constant_pd) then |
231 | + d_gi = dia |
232 | + else |
233 | + d_gi = ele_val_at_quad(pd_scalar_field, ele) |
234 | + end if |
235 | + |
236 | ! Compute the particle Reynolds number |
237 | ! (Assumes isotropic viscosity for now) |
238 | - particle_re_gi = (vfrac_fluid_gi*density_fluid_gi*magnitude_gi*d) / viscosity_fluid_gi(1,1,:) |
239 | + particle_re_gi = (vfrac_fluid_gi*density_fluid_gi*magnitude_gi*d_gi) / viscosity_fluid_gi(1,1,:) |
240 | |
241 | ! Compute the drag coefficient |
242 | select case(drag_correlation) |
243 | @@ -525,6 +553,18 @@ |
244 | |
245 | case(DRAG_CORRELATION_TYPE_ERGUN) |
246 | ! No drag coefficient is needed here. |
247 | + |
248 | + case(DRAG_CORRELATION_TYPE_SCHILLER_NAUMANN) |
249 | + ! Schiller & Naumann (1933) drag correlation |
250 | + ! Since the particle Reynolds number definition currently contains vfrac_fluid in numerator, |
251 | + ! we need to take that out by dividing as done below. Must be changed when Reynolds number defn is changed - gb812 |
252 | + do gi = 1, ele_ngi(u,ele) |
253 | + if((particle_re_gi(gi)/vfrac_fluid_gi(gi)) < 1000) then |
254 | + drag_coefficient_gi(gi) = (24.0/(particle_re_gi(gi)/vfrac_fluid_gi(gi)))*(1.0+0.15*(particle_re_gi(gi)/vfrac_fluid_gi(gi))**0.687) |
255 | + else |
256 | + drag_coefficient_gi(gi) = 0.44 |
257 | + end if |
258 | + end do |
259 | end select |
260 | |
261 | ! Don't let the drag_coefficient_gi be NaN |
262 | @@ -536,12 +576,15 @@ |
263 | |
264 | select case(drag_correlation) |
265 | case(DRAG_CORRELATION_TYPE_STOKES) |
266 | - K = vfrac_particle_gi*(3.0/4.0)*drag_coefficient_gi*(vfrac_fluid_gi*density_fluid_gi*magnitude_gi)/(d) |
267 | + K = vfrac_particle_gi*(3.0/4.0)*drag_coefficient_gi*(vfrac_fluid_gi*density_fluid_gi*magnitude_gi)/(d_gi) |
268 | case(DRAG_CORRELATION_TYPE_WEN_YU) |
269 | ! Wen & Yu (1966) drag term |
270 | - K = vfrac_particle_gi*(3.0/4.0)*drag_coefficient_gi*(vfrac_fluid_gi*density_fluid_gi*magnitude_gi)/(d*vfrac_fluid_gi**2.7) |
271 | + K = vfrac_particle_gi*(3.0/4.0)*drag_coefficient_gi*(vfrac_fluid_gi*density_fluid_gi*magnitude_gi)/(d_gi*vfrac_fluid_gi**2.7) |
272 | case(DRAG_CORRELATION_TYPE_ERGUN) |
273 | - K = 150.0*((vfrac_particle_gi**2)*viscosity_fluid_gi(1,1,:))/(vfrac_fluid_gi*(d**2)) + 1.75*(vfrac_particle_gi*density_fluid_gi*magnitude_gi/d) |
274 | + K = 150.0*((vfrac_particle_gi**2)*viscosity_fluid_gi(1,1,:))/(vfrac_fluid_gi*(d_gi**2)) + & |
275 | + 1.75*(vfrac_particle_gi*density_fluid_gi*magnitude_gi/d_gi) |
276 | + case(DRAG_CORRELATION_TYPE_SCHILLER_NAUMANN) |
277 | + K = vfrac_fluid_gi*vfrac_particle_gi*(3.0/4.0)*drag_coefficient_gi*(density_fluid_gi*magnitude_gi)/(d_gi) |
278 | end select |
279 | |
280 | if(is_particle_phase) then |
281 | @@ -680,6 +723,7 @@ |
282 | |
283 | type(scalar_field), pointer :: vfrac_fluid, vfrac_particle |
284 | type(scalar_field), pointer :: density_fluid, density_particle |
285 | + type(scalar_field), pointer :: pd_scalar_field ! scalar field defining particle diameter |
286 | type(vector_field), pointer :: velocity_fluid, velocity_particle |
287 | type(scalar_field), pointer :: internal_energy_fluid, internal_energy_particle |
288 | type(scalar_field), pointer :: old_internal_energy_fluid, old_internal_energy_particle |
289 | @@ -691,6 +735,8 @@ |
290 | real :: C_fluid, C_particle ! Specific heat of the fluid and particle phases at constant volume |
291 | real :: gamma ! Ratio of specific heats for compressible phase |
292 | integer :: kstat, cstat_fluid, cstat_particle, gstat |
293 | + character(len=OPTION_PATH_LEN) :: pd_field_name ! name of scalar field that defines particle diameter (can be the sauter mean dia) |
294 | + logical :: have_constant_pd ! checks if the particle diameter is a constant or not |
295 | |
296 | ! Get the necessary fields to calculate the heat transfer term |
297 | velocity_fluid => extract_vector_field(state(istate_fluid), "Velocity") |
298 | @@ -703,7 +749,14 @@ |
299 | density_particle => extract_scalar_field(state(istate_particle), "Density") |
300 | viscosity_fluid => extract_tensor_field(state(istate_fluid), "Viscosity") |
301 | |
302 | - call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter", d) |
303 | + if(have_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/constant")) then |
304 | + call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/constant", d) |
305 | + have_constant_pd = .true. |
306 | + else if(have_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/use_scalar_field")) then |
307 | + call get_option(trim(state(istate_particle)%option_path)//"/multiphase_properties/particle_diameter/use_scalar_field", pd_field_name) |
308 | + pd_scalar_field => extract_scalar_field(state(istate_particle), pd_field_name) |
309 | + have_constant_pd = .false. |
310 | + end if |
311 | |
312 | call get_option(trim(state(istate_fluid)%option_path)//"/multiphase_properties/effective_conductivity", k, kstat) |
313 | |
314 | @@ -759,7 +812,9 @@ |
315 | internal_energy_particle, & |
316 | old_internal_energy_fluid, & |
317 | old_internal_energy_particle, & |
318 | - viscosity_fluid, d, k, C_fluid, & |
319 | + viscosity_fluid, & |
320 | + have_constant_pd, d, pd_scalar_field, & |
321 | + k, C_fluid, & |
322 | C_particle, gamma) |
323 | end if |
324 | |
325 | @@ -781,7 +836,9 @@ |
326 | internal_energy_particle, & |
327 | old_internal_energy_fluid, & |
328 | old_internal_energy_particle, & |
329 | - viscosity_fluid, d, k, C_fluid, & |
330 | + viscosity_fluid, & |
331 | + have_constant_pd, dia, pd_scalar_field, & |
332 | + k, C_fluid, & |
333 | C_particle, gamma) |
334 | |
335 | integer, intent(in) :: ele |
336 | @@ -794,11 +851,14 @@ |
337 | |
338 | type(scalar_field), intent(in) :: vfrac_fluid, vfrac_particle |
339 | type(scalar_field), intent(in) :: density_fluid, density_particle |
340 | + type(scalar_field), intent(in) :: pd_scalar_field ! Scalar field representing particle diameter |
341 | type(vector_field), intent(in) :: nu_fluid, nu_particle |
342 | type(scalar_field), intent(in) :: internal_energy_fluid, internal_energy_particle |
343 | type(scalar_field), intent(in) :: old_internal_energy_fluid, old_internal_energy_particle |
344 | type(tensor_field), intent(in) :: viscosity_fluid |
345 | - real, intent(in) :: d, k, C_fluid, C_particle, gamma |
346 | + real, intent(in) :: dia ! Constant particle diameter |
347 | + real, intent(in) :: k, C_fluid, C_particle, gamma |
348 | + logical, intent(in) :: have_constant_pd ! is true if particle diameter is a constant. is false if it is a scalar field (e.g. sauter mean dia) |
349 | |
350 | ! Local variables |
351 | real, dimension(ele_ngi(x,ele)) :: internal_energy_fluid_gi, internal_energy_particle_gi |
352 | @@ -814,6 +874,7 @@ |
353 | real, dimension(ele_loc(internal_energy,ele)) :: rhs_addto |
354 | real, dimension(ele_loc(internal_energy,ele), ele_loc(internal_energy,ele)) :: matrix_addto |
355 | |
356 | + real, dimension(ele_ngi(x,ele)) :: d_gi ! particle diameter at quadrature points |
357 | real, dimension(ele_ngi(x,ele)) :: particle_Re ! Particle Reynolds number |
358 | real, dimension(ele_ngi(x,ele)) :: Pr ! Prandtl number |
359 | real, dimension(ele_ngi(x,ele)) :: particle_Nu ! Particle Nusselt number |
360 | @@ -844,9 +905,16 @@ |
361 | velocity_magnitude(gi) = norm2(nu_fluid_gi(:,gi) - nu_particle_gi(:,gi)) |
362 | end do |
363 | |
364 | + ! Compute the particle diameter at quadrature points |
365 | + if(have_constant_pd) then |
366 | + d_gi = dia |
367 | + else |
368 | + d_gi = ele_val_at_quad(pd_scalar_field, ele) |
369 | + end if |
370 | + |
371 | ! Compute the particle Reynolds number |
372 | ! (Assumes isotropic viscosity for now) |
373 | - particle_Re = (density_fluid_gi*velocity_magnitude*d) / viscosity_fluid_gi(1,1,:) |
374 | + particle_Re = (density_fluid_gi*velocity_magnitude*d_gi) / viscosity_fluid_gi(1,1,:) |
375 | |
376 | ! Compute the Prandtl number |
377 | ! (Assumes isotropic viscosity for now) |
378 | @@ -856,7 +924,7 @@ |
379 | particle_Nu = (7.0 - 10.0*vfrac_fluid_gi + 5.0*vfrac_fluid_gi**2)*(1.0 + 0.7*(particle_Re**0.2)*(Pr**(1.0/3.0))) + & |
380 | (1.33 - 2.4*vfrac_fluid_gi + 1.2*vfrac_fluid_gi**2)*(particle_Re**0.7)*(Pr**(1.0/3.0)) |
381 | |
382 | - Q = (6.0*k*vfrac_particle_gi*particle_Nu)/(d**2) |
383 | + Q = (6.0*k*vfrac_particle_gi*particle_Nu)/(d_gi**2) |
384 | |
385 | ! Note that the transfer term is defined in terms of temperatures (T_fluid and T_particle) |
386 | ! Let's convert the temperatures to internal energy (E) using E_i = C_i*T_i, |
387 | |
388 | === modified file 'configure' |
389 | --- configure 2013-10-17 17:13:25 +0000 |
390 | +++ configure 2013-12-12 22:35:40 +0000 |
391 | @@ -14918,7 +14918,7 @@ |
392 | |
393 | #******************* |
394 | |
395 | -ac_config_files="$ac_config_files Makefile debug/Makefile bathymetry/Makefile ocean_forcing/Makefile ocean_forcing/tests/Makefile sediments/Makefile hyperlight/Makefile femtools/Makefile femtools/tests/Makefile forward_interfaces/Makefile horizontal_adaptivity/Makefile horizontal_adaptivity/tests/Makefile preprocessor/Makefile error_measures/Makefile error_measures/tests/Makefile parameterisation/Makefile parameterisation/tests/Makefile fldecomp/Makefile assemble/Makefile assemble/tests/Makefile diagnostics/Makefile main/Makefile tools/Makefile tools/version-info python/setup.py adjoint/Makefile adjoint/tests/Makefile climatology/Makefile libmba2d/Makefile libmba3d/Makefile libjudy/Makefile libjudy/src/Makefile libjudy/src/JudyCommon/Makefile libjudy/src/Judy1/Makefile libjudy/src/JudyL/Makefile libjudy/src/JudySL/Makefile libjudy/src/JudyHS/Makefile libwm/Makefile libvtkfortran/Makefile schemas/flml reduced_modelling/Makefile" |
396 | +ac_config_files="$ac_config_files Makefile debug/Makefile bathymetry/Makefile ocean_forcing/Makefile ocean_forcing/tests/Makefile sediments/Makefile population_balance/Makefile hyperlight/Makefile femtools/Makefile femtools/tests/Makefile forward_interfaces/Makefile horizontal_adaptivity/Makefile horizontal_adaptivity/tests/Makefile preprocessor/Makefile error_measures/Makefile error_measures/tests/Makefile parameterisation/Makefile parameterisation/tests/Makefile fldecomp/Makefile assemble/Makefile assemble/tests/Makefile diagnostics/Makefile main/Makefile tools/Makefile tools/version-info python/setup.py adjoint/Makefile adjoint/tests/Makefile climatology/Makefile libmba2d/Makefile libmba3d/Makefile libjudy/Makefile libjudy/src/Makefile libjudy/src/JudyCommon/Makefile libjudy/src/Judy1/Makefile libjudy/src/JudyL/Makefile libjudy/src/JudySL/Makefile libjudy/src/JudyHS/Makefile libwm/Makefile libvtkfortran/Makefile schemas/flml reduced_modelling/Makefile" |
397 | |
398 | cat >confcache <<\_ACEOF |
399 | # This file is a shell script that caches the results of configure |
400 | @@ -15629,6 +15629,7 @@ |
401 | "ocean_forcing/Makefile") CONFIG_FILES="$CONFIG_FILES ocean_forcing/Makefile" ;; |
402 | "ocean_forcing/tests/Makefile") CONFIG_FILES="$CONFIG_FILES ocean_forcing/tests/Makefile" ;; |
403 | "sediments/Makefile") CONFIG_FILES="$CONFIG_FILES sediments/Makefile" ;; |
404 | + "population_balance/Makefile") CONFIG_FILES="$CONFIG_FILES population_balance/Makefile" ;; |
405 | "hyperlight/Makefile") CONFIG_FILES="$CONFIG_FILES hyperlight/Makefile" ;; |
406 | "femtools/Makefile") CONFIG_FILES="$CONFIG_FILES femtools/Makefile" ;; |
407 | "femtools/tests/Makefile") CONFIG_FILES="$CONFIG_FILES femtools/tests/Makefile" ;; |
408 | |
409 | === modified file 'configure.in' |
410 | --- configure.in 2013-09-23 20:07:28 +0000 |
411 | +++ configure.in 2013-12-12 22:35:40 +0000 |
412 | @@ -1503,6 +1503,7 @@ |
413 | bathymetry/Makefile |
414 | ocean_forcing/Makefile ocean_forcing/tests/Makefile |
415 | sediments/Makefile |
416 | + population_balance/Makefile |
417 | hyperlight/Makefile |
418 | femtools/Makefile femtools/tests/Makefile |
419 | forward_interfaces/Makefile |
420 | |
421 | === modified file 'diagnostics/Multiphase_Diagnostics.F90' |
422 | --- diagnostics/Multiphase_Diagnostics.F90 2011-10-24 02:20:27 +0000 |
423 | +++ diagnostics/Multiphase_Diagnostics.F90 2013-12-12 22:35:40 +0000 |
424 | @@ -56,7 +56,10 @@ |
425 | type(scalar_field), intent(inout) :: s_field ! Particle Reynolds number field |
426 | |
427 | !! Sub-options of the diagnostic field |
428 | - real :: d ! Particle diameter |
429 | + real :: dia ! Particle diameter |
430 | + character(len = OPTION_PATH_LEN) :: pd_field_name !name of scalar field that defines particle diameter (can be the sauter mean dia) |
431 | + type(scalar_field), pointer :: pd_scalar_field ! scalar field referring to particle diameter |
432 | + logical :: have_constant_pd ! checks if the particle diameter is a constant or not |
433 | character(len = OPTION_PATH_LEN) :: continuous_phase_name |
434 | |
435 | !! Other local variables |
436 | @@ -78,6 +81,7 @@ |
437 | real, dimension(mesh_dim(s_field), ele_ngi(s_field, 1)) :: u_continuous_gi, u_particle_gi |
438 | real, dimension(mesh_dim(s_field), mesh_dim(s_field), ele_ngi(s_field, 1)) :: viscosity_gi |
439 | real, dimension(ele_ngi(s_field, 1)) :: density_gi, vfrac_gi |
440 | + real, dimension(ele_ngi(s_field, 1)) :: d_gi ! particle diameter at the Gauss points |
441 | |
442 | real, dimension(:), allocatable :: magnitude ! |v_f - v_p| |
443 | |
444 | @@ -93,7 +97,14 @@ |
445 | ewrite(1,*) 'Entering calculate_particle_reynolds_number' |
446 | |
447 | ! Get sub-options from under the diagnostic field in the options tree |
448 | - call get_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/particle_diameter', d) |
449 | + if(have_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/particle_diameter/constant')) then |
450 | + call get_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/particle_diameter/constant', dia) |
451 | + have_constant_pd = .true. |
452 | + else if(have_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/particle_diameter/use_scalar_field')) then |
453 | + call get_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/particle_diameter/use_scalar_field', pd_field_name) |
454 | + pd_scalar_field => extract_scalar_field(states(state_index), pd_field_name) |
455 | + have_constant_pd = .false. |
456 | + end if |
457 | call get_option(trim(s_field%option_path)//'/diagnostic/algorithm::particle_reynolds_number/continuous_phase_name', continuous_phase_name) |
458 | |
459 | ! Find the index of the continuous phase in states |
460 | @@ -130,13 +141,20 @@ |
461 | density_gi = ele_val_at_quad(density, ele) |
462 | vfrac_gi = ele_val_at_quad(vfrac, ele) |
463 | |
464 | + ! Compute the particle diameter at the Gauss points |
465 | + if(have_constant_pd) then |
466 | + d_gi = dia |
467 | + else |
468 | + d_gi = ele_val_at_quad(pd_scalar_field, ele) |
469 | + end if |
470 | + |
471 | do gi = 1, ele_ngi(u_continuous, ele) |
472 | magnitude(gi) = norm2(u_continuous_gi(:,gi) - u_particle_gi(:,gi)) |
473 | end do |
474 | |
475 | ! Compute the particle Reynolds number |
476 | ! (Assumes isotropic viscosity for now) |
477 | - particle_re_gi = (vfrac_gi*density_gi*magnitude*d) / viscosity_gi(1,1,:) |
478 | + particle_re_gi = (vfrac_gi*density_gi*magnitude*d_gi) / viscosity_gi(1,1,:) |
479 | |
480 | ! Invert the mass matrix to get the particle_re value at each node |
481 | particle_re_mat = matmul(inverse(shape_shape(particle_re_shape, particle_re_shape, detwei)), & |
482 | |
483 | === modified file 'examples/tephra_settling/tephra_settling.flml' |
484 | --- examples/tephra_settling/tephra_settling.flml 2013-05-30 11:47:42 +0000 |
485 | +++ examples/tephra_settling/tephra_settling.flml 2013-12-12 22:35:40 +0000 |
486 | @@ -584,7 +584,9 @@ |
487 | </scalar_field> |
488 | <multiphase_properties> |
489 | <particle_diameter> |
490 | - <real_value rank="0">48e-6</real_value> |
491 | + <constant> |
492 | + <real_value rank="0">48e-6</real_value> |
493 | + </constant> |
494 | </particle_diameter> |
495 | </multiphase_properties> |
496 | </material_phase> |
497 | |
498 | === modified file 'main/Fluids.F90' |
499 | --- main/Fluids.F90 2013-10-07 16:23:35 +0000 |
500 | +++ main/Fluids.F90 2013-12-12 22:35:40 +0000 |
501 | @@ -103,6 +103,7 @@ |
502 | use detector_parallel, only: sync_detector_coordinates, deallocate_detector_list_array |
503 | use momentum_diagnostic_fields, only: calculate_densities |
504 | use sediment_diagnostics, only: calculate_sediment_flux |
505 | + use DQMOM |
506 | |
507 | implicit none |
508 | |
509 | @@ -248,13 +249,16 @@ |
510 | & default=1) |
511 | call get_option("/timestepping/nonlinear_iterations/tolerance", & |
512 | & nonlinear_iteration_tolerance, default=0.0) |
513 | - |
514 | + |
515 | if(have_option("/mesh_adaptivity/hr_adaptivity/adapt_at_first_timestep")) then |
516 | |
517 | if(have_option("/timestepping/nonlinear_iterations/nonlinear_iterations_at_adapt")) then |
518 | call get_option('/timestepping/nonlinear_iterations/nonlinear_iterations_at_adapt',nonlinear_iterations_adapt) |
519 | nonlinear_iterations = nonlinear_iterations_adapt |
520 | end if |
521 | + |
522 | + ! set population balance initial conditions - for first adaptivity |
523 | + call dqmom_init(state) |
524 | |
525 | call adapt_state_first_timestep(state) |
526 | |
527 | @@ -299,6 +303,9 @@ |
528 | call populate_sub_state(state,sub_state) |
529 | end if |
530 | |
531 | + ! set population balance initial conditions |
532 | + call dqmom_init(state) |
533 | + |
534 | ! Calculate the number of scalar fields to solve for and their correct |
535 | ! solve order taking into account dependencies. |
536 | call get_ntsol(ntsol) |
537 | @@ -571,6 +578,9 @@ |
538 | |
539 | call compute_goals(state) |
540 | |
541 | + ! Calculate source terms for populations ------ |
542 | + call dqmom_calculate_source_terms(state, ITS) |
543 | + |
544 | !------------------------------------------------ |
545 | ! Addition for calculating drag force ------ jem 05-06-2008 |
546 | if (have_option("/imported_solids/calculate_drag_on_surface")) then |
547 | @@ -750,6 +760,7 @@ |
548 | end if |
549 | end do |
550 | |
551 | + |
552 | ! This is where the non-legacy momentum stuff happens |
553 | ! a loop over state (hence over phases) is incorporated into this subroutine call |
554 | ! hence this lives outside the phase_loop |
555 | @@ -762,6 +773,14 @@ |
556 | call solve_momentum(state,at_first_timestep=((timestep==1).and.(its==1)),timestep=timestep, POD_state=POD_state) |
557 | end if |
558 | |
559 | + ! calculate abscissa for populations ----- |
560 | + ! this must be done at the end of each non-linear iteration |
561 | + call dqmom_calculate_abscissa(state) |
562 | + do i = 1, size(state) |
563 | + call dqmom_calculate_moments(state(i)) |
564 | + call dqmom_calculate_statistics(state(i)) |
565 | + end do |
566 | + |
567 | if(nonlinear_iterations > 1) then |
568 | ! Check for convergence between non linear iteration loops |
569 | call test_and_write_convergence(state, current_time + dt, dt, its, change) |
570 | |
571 | === added directory 'population_balance' |
572 | === added file 'population_balance/DQMOM.F90' |
573 | --- population_balance/DQMOM.F90 1970-01-01 00:00:00 +0000 |
574 | +++ population_balance/DQMOM.F90 2013-12-12 22:35:40 +0000 |
575 | @@ -0,0 +1,999 @@ |
576 | +! Copyright (C) 2006 Imperial College London and others. |
577 | +! |
578 | +! Please see the AUTHORS file in the main source directory for a full list |
579 | +! of copyright holders. |
580 | +! |
581 | +! Prof. C Pain |
582 | +! Applied Modelling and Computation Group |
583 | +! Department of Earth Science and Engineering |
584 | +! Imperial College London |
585 | +! |
586 | +! amcgsoftware@imperial.ac.uk |
587 | +! |
588 | +! This library is free software; you can redistribute it and/or |
589 | +! modify it under the terms of the GNU Lesser General Public |
590 | +! License as published by the Free Software Foundation, |
591 | +! version 2.1 of the License. |
592 | +! |
593 | +! This library is distributed in the hope that it will be useful, |
594 | +! but WITHOUT ANY WARRANTY; without even the implied arranty of |
595 | +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
596 | +! Lesser General Public License for more details. |
597 | +! |
598 | +! You should have received a copy of the GNU Lesser General Public |
599 | +! License along with this library; if not, write to the Free Software |
600 | +! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
601 | +! USA |
602 | + |
603 | +#include "fdebug.h" |
604 | + |
605 | +module dqmom |
606 | + |
607 | + use vector_tools |
608 | + use spud |
609 | + use fields |
610 | + use state_module |
611 | + use state_fields_module |
612 | + use initialise_fields_module |
613 | + use global_parameters, only: OPTION_PATH_LEN, FIELD_NAME_LEN |
614 | +! use sparsity_patterns_meshes |
615 | + use sparse_tools |
616 | + use solvers |
617 | + |
618 | + implicit none |
619 | + |
620 | + public dqmom_init, dqmom_calculate_source_terms, dqmom_calculate_abscissa,& |
621 | + & dqmom_check_options, dqmom_calculate_moments, dqmom_calculate_statistics |
622 | + |
623 | + private |
624 | + |
625 | + !! TODO: |
626 | + !! 1. Make field_finding algorithm work for multiple phases and make sure it works for |
627 | + !! several pop_balances |
628 | + !! 3. Make check_options run |
629 | + !! 4. Check all prognostic fields are identical (possible bar initial conditions) |
630 | + !! 5. Check prognostic Source terms are set to diagnostic, Internal |
631 | + !! 6. Minimum weight |
632 | + !! 7. Check diagnostic fields are set to Internal |
633 | + !! 8. Entire set up of fields is a horrible hack - could do with sorting out - suggest |
634 | + !! new blueprint for how this could work - will only work for one pop_balance per phase. IMPORTANT |
635 | + !! 9. Make changes to function dqmom_calculate_abscissa so that it works for a state insteaad of all states. |
636 | + !! Make necessary changes to the place this is called in the code. |
637 | + !! 10.In Fluids.F90 use conditions on presence of population balance tree and call the functions inside the if condition. |
638 | + !! Loop on states inside Fluids.F90 (or any other file where DQMOM functions are called) instead of doing it inside DQMOM functions. |
639 | + |
640 | + !! Changes made by gb812 |
641 | + !! 1. in 'Construct C matrix (rhs pt. 2)' -> took grad_D out or squared term |
642 | + !! 2. in 'Construct C matrix (rhs pt. 2)' -> while summing grad_D in the next line, changed from sum(grad_D) to sum(grad_D,1) |
643 | +contains |
644 | + |
645 | + subroutine get_pop_field(state, i_pop, i_field, type, item, stat, iterated) |
646 | + |
647 | + ! Returns the required population balance field |
648 | + |
649 | + type(state_type), intent(in) :: state |
650 | + integer, intent(in) :: i_pop, i_field |
651 | + character(len=FIELD_NAME_LEN) :: type ! moments, weights, ascissa, or weighted_abscissa |
652 | + type(scalar_field), pointer, intent(out) :: item |
653 | + integer, intent(out), optional :: stat |
654 | + logical, intent(in), optional :: iterated |
655 | + |
656 | + character(len=FIELD_NAME_LEN) :: name |
657 | + character(len=OPTION_PATH_LEN) :: option_path |
658 | + |
659 | + call get_pop_option_path(state, i_pop, option_path) |
660 | + call get_option(trim(option_path)//'/'//trim(type)//'/scalar_field['//int2str(i_field -& |
661 | + 1)//']/name', name) |
662 | + if (present(iterated)) then |
663 | + if (iterated) then |
664 | + name = 'Iterated'//trim(name) |
665 | + end if |
666 | + end if |
667 | + item => extract_scalar_field(state, trim(name), stat) |
668 | + |
669 | + end subroutine get_pop_field |
670 | + |
671 | + subroutine get_pop_option_path(state, i_pop, option_path) |
672 | + |
673 | + type(state_type), intent(in) :: state |
674 | + integer, intent(in) :: i_pop |
675 | + character(len=OPTION_PATH_LEN), intent(out) :: option_path |
676 | + |
677 | + option_path = trim(state%option_path)//'/population_balance' |
678 | + if (option_count(option_path) > 1) then |
679 | + option_path = trim(state%option_path)//'/population_balance['& |
680 | + &//int2str(i_pop)//']' |
681 | + end if |
682 | + |
683 | + end subroutine get_pop_option_path |
684 | + |
685 | + subroutine dqmom_init(states) |
686 | + |
687 | + type(state_type), intent(in), dimension(:) :: states |
688 | + |
689 | + integer :: i_state, i_pop |
690 | + character(len=OPTION_PATH_LEN) :: option_path |
691 | + |
692 | + do i_state = 1, option_count("/material_phase") |
693 | + do i_pop = 1, option_count(trim(states(i_state)%option_path)//& |
694 | + '/population_balance') |
695 | + call get_pop_option_path(states(i_state), i_pop, option_path) |
696 | + if (have_option(trim(option_path)// & |
697 | + '/calculate_initial_conditions_from_moments')) then |
698 | + call dqmom_PD_algorithm(states(i_state), i_pop) |
699 | + end if |
700 | + end do |
701 | + end do |
702 | + |
703 | + call dqmom_calculate_abscissa(states) |
704 | + |
705 | + end subroutine dqmom_init |
706 | + |
707 | + subroutine dqmom_PD_algorithm(state, i_pop) |
708 | + |
709 | + ! Algorithm for calculating abscissa and weights from the moment of a distribution |
710 | + ! See Gordon 1968 and Mcgraw 1997 |
711 | + |
712 | + type(state_type), intent(in) :: state |
713 | + integer, intent(in) :: i_pop |
714 | + |
715 | + type(scalar_field_pointer), dimension(:), allocatable :: moments |
716 | + type(scalar_field_pointer), dimension(:), allocatable :: weighted_abscissa |
717 | + type(scalar_field_pointer), dimension(:), allocatable :: weights |
718 | + type(vector_field), pointer:: position |
719 | + |
720 | + ! J - Jacobi matrix |
721 | + ! P and alpha are required working arrays |
722 | + ! e_values - eigenvalues |
723 | + ! e_vectors - corresponding eigenvectors |
724 | + real, dimension(:,:), allocatable :: P, Jac, e_vectors |
725 | + real, dimension(:), allocatable :: alpha, e_values |
726 | + character(len=OPTION_PATH_LEN) :: option_path |
727 | + character(len=FIELD_NAME_LEN) :: type |
728 | + integer :: i_field, n_abscissa, i_node, i, j, stat |
729 | + |
730 | + call get_pop_option_path(state, i_pop, option_path) |
731 | + n_abscissa = option_count(trim(option_path)//'/abscissa/scalar_field') |
732 | + |
733 | + allocate(moments(2*n_abscissa)) |
734 | + allocate(weighted_abscissa(n_abscissa)) |
735 | + allocate(weights(n_abscissa)) |
736 | + allocate(P(2*n_abscissa + 1,2*n_abscissa + 1)) |
737 | + allocate(Jac(n_abscissa,n_abscissa)) |
738 | + allocate(alpha(2*n_abscissa)) |
739 | + allocate(e_vectors(n_abscissa,n_abscissa)) |
740 | + allocate(e_values(n_abscissa)) |
741 | + |
742 | + position => extract_vector_field(state, "Coordinate") |
743 | + do i_field = 1, 2*n_abscissa |
744 | + ! collect moment fields and initialise from initial conditions |
745 | + ! will not be done automatically as this is a diagnostic field |
746 | + type = 'moments' |
747 | + call get_pop_field(state, i_pop, i_field, type, moments(i_field)%ptr) |
748 | + call zero(moments(i_field)%ptr) |
749 | + call initialise_field_over_regions(moments(i_field)%ptr, & |
750 | + trim(moments(i_field)%ptr%option_path)//'/diagnostic/initial_condition', position) |
751 | + end do |
752 | + |
753 | + do i_field = 1, n_abscissa |
754 | + ! collect weighted_abscissa and weight fields and zero |
755 | + type = 'weights' |
756 | + call get_pop_field(state, i_pop, i_field, type, weights(i_field)%ptr) |
757 | + type = 'weighted_abscissa' |
758 | + call get_pop_field(state, i_pop, i_field, type, & |
759 | + weighted_abscissa(i_field)%ptr) |
760 | + call zero(weights(i_field)%ptr) |
761 | + call zero(weighted_abscissa(i_field)%ptr) |
762 | + end do |
763 | + |
764 | + do i_node = 1, node_count(moments(1)%ptr) |
765 | + ! zero working arrays |
766 | + P = 0.0 |
767 | + Jac = 0.0 |
768 | + alpha = 0.0 |
769 | + e_vectors = 0.0 |
770 | + e_values = 0.0 |
771 | + |
772 | + ! Construct P matrix |
773 | + P(1,1) = 1.0 |
774 | + ! set the zero'th moment to 1.0 for the purposes of finding the abscissa |
775 | + ! weights will be multiplied by the zero'th moment later to obtain their correct |
776 | + ! values |
777 | + P(1,2) = 1.0 |
778 | + do i = 2, 2*n_abscissa |
779 | + P(i,2) = (-1)**(i-1)*(node_val(moments(i)%ptr, i_node)/node_val(moments(1)%ptr, i_node)) |
780 | + end do |
781 | + do j = 3, 2*n_abscissa + 1 |
782 | + do i = 1, (2*n_abscissa + 1) - (j - 1) |
783 | + P(i,j) = P(1,j-1)*P(i+1,j-2) - P(1,j-2)*P(i+1,j-1) |
784 | + end do |
785 | + end do |
786 | + ! Construct alpha array |
787 | + alpha(1) = 0.0 |
788 | + do i = 2, 2*n_abscissa |
789 | + alpha(i) = P(1,i+1)/(P(1,i)*P(1,i-1)) |
790 | + end do |
791 | + ! Construct jacobi matrix |
792 | + do i = 1, n_abscissa |
793 | + Jac(i,i) = alpha(2*i) + alpha(2*i - 1) |
794 | + end do |
795 | + do i = 1, n_abscissa - 1 |
796 | + Jac(i, i+1) = ((alpha(2*i + 1)*alpha(2*i))**2.0)**0.25 |
797 | + Jac(i+1, i) = ((alpha(2*i + 1)*alpha(2*i))**2.0)**0.25 |
798 | + end do |
799 | + |
800 | + ! Calculate eigenvalues and eigenvectors |
801 | + call eigendecomposition_symmetric(Jac, e_vectors, e_values, stat) |
802 | + if (stat /= 0) then |
803 | + FLExit('Cannot compute abscissa and weights using PD algorithm') |
804 | + end if |
805 | + |
806 | + do i_field = 1, n_abscissa |
807 | + ! set prognostic field values |
808 | + call set(weights(i_field)%ptr, i_node, & |
809 | + node_val(moments(1)%ptr, i_node) * e_vectors(1,i_field)**2) |
810 | + call set(weighted_abscissa(i_field)%ptr, i_node, & |
811 | + node_val(weights(i_field)%ptr, i_node) * e_values(i_field)) |
812 | + end do |
813 | + |
814 | + end do |
815 | + |
816 | + deallocate(moments, weighted_abscissa, weights, P, Jac, alpha, e_vectors, e_values) |
817 | + |
818 | + end subroutine dqmom_PD_algorithm |
819 | + |
820 | + subroutine dqmom_calculate_abscissa(states) |
821 | + |
822 | + type(state_type), dimension(:), intent(in) :: states |
823 | + |
824 | + type(scalar_field), pointer :: abscissa, weight, weighted_abscissa |
825 | + type(scalar_field) :: inv_weight |
826 | + integer :: i_state, i_pop, i_abscissa |
827 | + character(len=OPTION_PATH_LEN) :: option_path |
828 | + character(len=FIELD_NAME_LEN) :: type |
829 | + |
830 | + ewrite(1, *) "In dqmom_calculate_abscissa" |
831 | + do i_state = 1, option_count("/material_phase") |
832 | + do i_pop = 1, option_count(trim(states(i_state)%option_path)//'/population_balance') |
833 | + call get_pop_option_path(states(i_state), i_pop, option_path) |
834 | + do i_abscissa = 1, option_count(trim(option_path)//'/abscissa/scalar_field') |
835 | + ! get required fields |
836 | + type = 'abscissa' |
837 | + call get_pop_field(states(i_state), i_pop, i_abscissa, type, abscissa) |
838 | + type = 'weights' |
839 | + call get_pop_field(states(i_state), i_pop, i_abscissa, type, weight) |
840 | + type = 'weighted_abscissa' |
841 | + call get_pop_field(states(i_state), i_pop, i_abscissa, type, weighted_abscissa) |
842 | + |
843 | + ! calculate the inverse of the weights |
844 | + call allocate(inv_weight, weight%mesh, 'InverseWeight') |
845 | + call set(inv_weight, weight) |
846 | + where (inv_weight%val/=0.0) |
847 | + inv_weight%val=1./inv_weight%val |
848 | + end where |
849 | + |
850 | + ! calculate abscissa |
851 | + call set(abscissa, weighted_abscissa) |
852 | + call scale(abscissa, inv_weight) |
853 | + |
854 | + call deallocate(inv_weight) |
855 | + end do |
856 | + end do |
857 | + end do |
858 | + ewrite(1, *) "Exiting dqmom_calculate_abscissa" |
859 | + end subroutine dqmom_calculate_abscissa |
860 | + |
861 | + subroutine dqmom_calculate_source_terms(states, it) |
862 | + |
863 | + type(state_type), dimension(:), intent(inout) :: states |
864 | + integer, intent(in) :: it |
865 | + |
866 | + integer :: i_state, i_pop |
867 | + |
868 | + do i_state = 1, option_count("/material_phase") |
869 | + do i_pop = 1, option_count(trim(states(i_state)%option_path)//'/population_balance') |
870 | + call dqmom_calculate_source_term_pop(states(i_state), it, i_pop) |
871 | + end do |
872 | + end do |
873 | + |
874 | + end subroutine dqmom_calculate_source_terms |
875 | + |
876 | + subroutine dqmom_calculate_source_term_pop(state, it, i_pop) |
877 | + |
878 | + type(state_type), intent(inout) :: state |
879 | + integer, intent(in) :: it |
880 | + |
881 | + type(scalar_field_pointer), dimension(:), allocatable :: abscissa,& |
882 | + weight, it_abscissa, it_weight, s_weighted_abscissa, s_weight |
883 | + type(scalar_field), pointer :: lumped_mass |
884 | + type(csr_matrix), pointer :: mass_matrix |
885 | + type(scalar_field), dimension(:), allocatable :: r_abscissa, r_weight |
886 | + type(tensor_field), pointer :: D |
887 | + type(vector_field), pointer :: X |
888 | + real :: theta, cond, growth_r, internal_dispersion_coeff, aggregation_freq_const, breakage_freq_const, breakage_freq_degree, perturb_val |
889 | + integer :: i_pop, N, i, j, stat |
890 | + character(len=OPTION_PATH_LEN) :: option_path |
891 | + character(len=FIELD_NAME_LEN) :: type, field_name, growth_type, aggregation_freq_type, breakage_freq_type, breakage_dist_type, singular_option |
892 | + logical :: have_D = .false. |
893 | + logical :: have_growth = .FALSE. |
894 | + logical :: have_internal_dispersion = .FALSE. |
895 | + logical :: have_aggregation = .FALSE. |
896 | + logical :: have_breakage = .FALSE. |
897 | + |
898 | + call get_pop_option_path(state, i_pop, option_path) |
899 | + N = option_count(trim(option_path)//'/abscissa/scalar_field') |
900 | + allocate(abscissa(N), weight(N), it_abscissa(N), it_weight(N), & |
901 | + r_abscissa(N), r_weight(N), s_weighted_abscissa(N), s_weight(N)) |
902 | + |
903 | + do i = 1, N |
904 | + ! collect abscissa and weight fields |
905 | + type = 'weights' |
906 | + call get_pop_field(state, i_pop, i, type, weight(i)%ptr) |
907 | + call get_pop_field(state, i_pop, i, type, it_weight(i)%ptr, iterated=.true.) |
908 | + type = 'abscissa' |
909 | + call get_pop_field(state, i_pop, i, type, abscissa(i)%ptr) |
910 | + call get_pop_field(state, i_pop, i, type, it_abscissa(i)%ptr, iterated=.true.) |
911 | + |
912 | + ! get source fields (note this is the weighted abscissa source not the abscissa source) |
913 | + s_weight(i)%ptr => extract_scalar_field(state, trim(weight(i)%ptr%name)//'Source') |
914 | + call get_option(trim(option_path)//'/weighted_abscissa/scalar_field['// & |
915 | + int2str(i - 1)//']/name', field_name) |
916 | + s_weighted_abscissa(i)%ptr => extract_scalar_field(state, trim(field_name)//'Source') |
917 | + call zero(s_weight(i)%ptr) |
918 | + call zero(s_weighted_abscissa(i)%ptr) |
919 | + |
920 | + ! relax non-linear values |
921 | + ! all temporal relaxations must be the same |
922 | + call get_option(trim(weight(i)%ptr%option_path)// & |
923 | + '/prognostic/temporal_discretisation/theta', theta) |
924 | + ! do not recalculate source terms if theta = 0.0 after first non-linear iteration |
925 | + if ((theta == 0.0) .and. (it /= 1)) then |
926 | + return |
927 | + end if |
928 | + call allocate(r_abscissa(i), abscissa(i)%ptr%mesh, & |
929 | + "RelaxedAbscissa"//int2str(i)) |
930 | + call allocate(r_weight(i), weight(i)%ptr%mesh, "RelaxedWeight"//int2str(i)) |
931 | + call set(r_abscissa(i), it_abscissa(i)%ptr) |
932 | + call scale(r_abscissa(i), theta) |
933 | + call addto(r_abscissa(i), abscissa(i)%ptr, 1.0-theta) |
934 | + call set(r_weight(i), it_weight(i)%ptr) |
935 | + call scale(r_weight(i), theta) |
936 | + call addto(r_weight(i), weight(i)%ptr, 1.0-theta) |
937 | + end do |
938 | + |
939 | + ! get diffusion |
940 | + D => extract_tensor_field(state, trim(weight(1)%ptr%name)//'Diffusivity',stat) |
941 | + if (stat == 0) then |
942 | + have_D = .true. |
943 | + end if |
944 | + |
945 | + ! check for growth term |
946 | + if (have_option(trim(option_path)//'/population_balance_source_terms/growth')) then |
947 | + have_growth = .TRUE. |
948 | + if (have_option(trim(option_path)//'/population_balance_source_terms/growth/power_law_growth')) then |
949 | + growth_type = 'power_law_growth'; |
950 | + call get_option(trim(option_path)//'/population_balance_source_terms/growth/power_law_growth', growth_r) |
951 | + end if |
952 | + else |
953 | + have_growth = .FALSE. |
954 | + end if |
955 | + |
956 | + ! check for internal dispersion term |
957 | + if (have_option(trim(option_path)//'/population_balance_source_terms/internal_dispersion')) then |
958 | + have_internal_dispersion = .TRUE. |
959 | + call get_option(trim(option_path)//'/population_balance_source_terms/internal_dispersion', internal_dispersion_coeff) |
960 | + else |
961 | + have_internal_dispersion = .FALSE. |
962 | + end if |
963 | + |
964 | + ! check for aggregation term |
965 | + if (have_option(trim(option_path)//'/population_balance_source_terms/aggregation')) then |
966 | + have_aggregation = .TRUE. |
967 | + if (have_option(trim(option_path)//'/population_balance_source_terms/aggregation/aggregation_frequency/constant_aggregation')) then |
968 | + aggregation_freq_type = 'constant_aggregation' |
969 | + call get_option(trim(option_path)//'/population_balance_source_terms/aggregation/aggregation_frequency/constant_aggregation', aggregation_freq_const) |
970 | + else if (have_option(trim(option_path)//'/population_balance_source_terms/aggregation/aggregation_frequency/hydrodynamic_aggregation')) then |
971 | + aggregation_freq_type = 'hydrodynamic_aggregation' |
972 | + else if (have_option(trim(option_path)//'/population_balance_source_terms/aggregation/aggregation_frequency/sum_aggregation')) then |
973 | + aggregation_freq_type = 'sum_aggregation' |
974 | + call get_option(trim(option_path)//'/population_balance_source_terms/aggregation/aggregation_frequency/sum_aggregation', aggregation_freq_const) |
975 | + end if |
976 | + else |
977 | + have_aggregation = .FALSE. |
978 | + end if |
979 | + |
980 | + ! check for breakage term |
981 | + if (have_option(trim(option_path)//'/population_balance_source_terms/breakage')) then |
982 | + have_breakage = .TRUE. |
983 | + if (have_option(trim(option_path)//'/population_balance_source_terms/breakage/breakage_frequency/constant_breakage')) then |
984 | + breakage_freq_type = 'constant_breakage' |
985 | + call get_option(trim(option_path)//'/population_balance_source_terms/breakage/breakage_frequency/constant_breakage', breakage_freq_const) |
986 | + else if (have_option(trim(option_path)//'/population_balance_source_terms/breakage/breakage_frequency/power_law_breakage')) then |
987 | + breakage_freq_type = 'power_law_breakage' |
988 | + call get_option(trim(option_path)//'/population_balance_source_terms/breakage/breakage_frequency/power_law_breakage/coefficient', breakage_freq_const) |
989 | + call get_option(trim(option_path)//'/population_balance_source_terms/breakage/breakage_frequency/power_law_breakage/degree', breakage_freq_degree) |
990 | + end if |
991 | + |
992 | + if (have_option(trim(option_path)//'/population_balance_source_terms/breakage/distribution_function/symmetric_fragmentation')) then |
993 | + breakage_dist_type = 'symmetric_fragmentation' |
994 | + else if (have_option(trim(option_path)//'/population_balance_source_terms/breakage/distribution_function/mcCoy_madras_2003')) then |
995 | + breakage_dist_type = 'mcCoy_madras_2003' |
996 | + end if |
997 | + |
998 | + else |
999 | + have_breakage = .FALSE. |
1000 | + end if |
1001 | + |
1002 | + ! get ill-conditioned matrix settings |
1003 | + call get_option(trim(option_path)//'/ill_conditioned_matrices/required_condition_number', cond) |
1004 | + if (have_option(trim(option_path)//'/ill_conditioned_matrices/set_source_to_zero')) then |
1005 | + singular_option = 'set_source_to_zero'; |
1006 | + else if (have_option(trim(option_path)//'/ill_conditioned_matrices/perturbate')) then |
1007 | + singular_option = 'perturbate'; |
1008 | + call get_option(trim(option_path)//'/ill_conditioned_matrices/perturbate/perturbation', perturb_val) |
1009 | +! else if (have_option(trim(option_path)//'/ill_conditioned_matrices/average_surrounding_nodes')) then |
1010 | +! singular_option = 'average_surrounding_nodes'; |
1011 | + end if |
1012 | + |
1013 | + X => extract_vector_field(state, 'Coordinate') |
1014 | + ! assembly loop |
1015 | + do i = 1, ele_count(r_abscissa(1)) |
1016 | + call dqmom_calculate_source_term_ele(r_abscissa, r_weight, s_weighted_abscissa, s_weight, & |
1017 | + &D, have_D, have_growth, growth_type, growth_r, have_internal_dispersion, internal_dispersion_coeff, & |
1018 | + &have_aggregation, aggregation_freq_type, aggregation_freq_const, & |
1019 | + &have_breakage, breakage_freq_type, breakage_freq_const, breakage_freq_degree, breakage_dist_type, X, singular_option, perturb_val, cond, i) |
1020 | + end do |
1021 | + |
1022 | + ! for non-DG we apply inverse mass globally |
1023 | + if(continuity(r_abscissa(1))>=0) then |
1024 | + if(have_option(trim(option_path)//'/adv_diff_source_term_interpolation/use_full_mass_matrix')) then |
1025 | + mass_matrix => get_mass_matrix(state, r_abscissa(1)%mesh) |
1026 | + ! r_abscissa(1) is used as a dummy scalar field here since it is not needed anymore. |
1027 | + do j = 1, N |
1028 | + call zero(r_abscissa(1)) |
1029 | + call petsc_solve(r_abscissa(1), mass_matrix, s_weight(j)%ptr, trim(option_path)//'/adv_diff_source_term_interpolation/use_full_mass_matrix') |
1030 | + call set(s_weight(j)%ptr, r_abscissa(1)) |
1031 | + call zero(r_abscissa(1)) |
1032 | + call petsc_solve(r_abscissa(1), mass_matrix, s_weighted_abscissa(j)%ptr, trim(option_path)//'/adv_diff_source_term_interpolation/use_full_mass_matrix') |
1033 | + call set(s_weighted_abscissa(j)%ptr, r_abscissa(1)) |
1034 | + end do |
1035 | + else if(have_option(trim(option_path)//'/adv_diff_source_term_interpolation/use_mass_lumping')) then |
1036 | + lumped_mass => get_lumped_mass(state, r_abscissa(1)%mesh) |
1037 | + do j = 1, N |
1038 | + do i = 1, node_count(r_abscissa(1)) |
1039 | + call set(s_weighted_abscissa(j)%ptr, i, node_val(s_weighted_abscissa(j)%ptr,i)& |
1040 | + &/node_val(lumped_mass,i)) |
1041 | + call set(s_weight(j)%ptr, i, node_val(s_weight(j)%ptr,i)& |
1042 | + &/node_val(lumped_mass,i)) |
1043 | + end do |
1044 | + end do |
1045 | + else |
1046 | + FLAbort("Check the .flml file. You must specify an option under 'population_balance/adv_diff_source_term_interpolation'") |
1047 | + end if |
1048 | + end if |
1049 | + |
1050 | + do i = 1, N |
1051 | + call deallocate(r_abscissa(i)) |
1052 | + call deallocate(r_weight(i)) |
1053 | + end do |
1054 | + deallocate(abscissa, weight, it_abscissa, it_weight, & |
1055 | + r_abscissa, r_weight) |
1056 | + |
1057 | + end subroutine dqmom_calculate_source_term_pop |
1058 | + |
1059 | + subroutine dqmom_calculate_source_term_ele(abscissa, weight, s_weighted_abscissa, s_weight, & |
1060 | + &D, have_D, have_growth, growth_type, growth_r, have_internal_dispersion, internal_dispersion_coeff, & |
1061 | + &have_aggregation, aggregation_freq_type, aggregation_freq_const, & |
1062 | + &have_breakage, breakage_freq_type, breakage_freq_const, breakage_freq_degree, breakage_dist_type, X, singular_option, perturb_val, cond, ele) |
1063 | + |
1064 | + type(scalar_field), dimension(:), intent(in) :: abscissa, weight |
1065 | + type(scalar_field_pointer), dimension(:), intent(inout) :: s_weighted_abscissa, s_weight |
1066 | + type(tensor_field), pointer, intent(in) :: D |
1067 | + type(vector_field), pointer, intent(in) :: X |
1068 | + integer, intent(in) :: ele |
1069 | + real, intent(in) :: cond, growth_r, internal_dispersion_coeff, aggregation_freq_const, breakage_freq_const, breakage_freq_degree, perturb_val |
1070 | + logical, intent(in) :: have_D, have_growth, have_internal_dispersion, have_aggregation, have_breakage |
1071 | + character(len=FIELD_NAME_LEN), intent(in) :: growth_type, aggregation_freq_type, breakage_freq_type, breakage_dist_type, singular_option |
1072 | + |
1073 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)) :: abscissa_val_at_quad |
1074 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)*2, size(abscissa)*2) :: A |
1075 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)*2, size(abscissa)) :: A_3 |
1076 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)) :: C |
1077 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)*2) :: S_rhs ! source term (includes growth, breakage and coalescence term): gb 15-11-2012 |
1078 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)*2, size(abscissa)) :: moment_daughter_dist_func |
1079 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)) :: break_freq |
1080 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa), size(abscissa)) :: aggregation_freq ! at present it is not dependent on space coordinate, but can be dependent and will have to be a scalar fields |
1081 | + real, dimension(size(abscissa)*2, 1) :: b |
1082 | + real, dimension(ele_ngi(abscissa(1), ele), size(abscissa)) :: abscissa_S_at_quad |
1083 | + real, dimension(ele_ngi(abscissa(1), ele), size(weight)) :: weight_S_at_quad |
1084 | + real, dimension(ele_loc(abscissa(1), ele)) :: abscissa_S_at_nodes |
1085 | + real, dimension(ele_loc(abscissa(1), ele)) :: weight_S_at_nodes |
1086 | + real, dimension(ele_loc(abscissa(1), ele), ele_loc(abscissa(1), ele)) :: invmass |
1087 | + real, dimension(ele_ngi(abscissa(1), ele)) :: detwei |
1088 | + real, dimension(X%dim, ele_ngi(abscissa(1), ele)) :: grad_D |
1089 | + real, dimension(X%dim, X%dim, ele_ngi(abscissa(1), ele)) :: D_at_quad |
1090 | + type(element_type), pointer :: shape |
1091 | + integer, dimension(:), pointer :: nodes |
1092 | + real, dimension(ele_loc(abscissa(1), ele), ele_ngi(abscissa(1), ele), X%dim) :: dshape |
1093 | + real, dimension(size(abscissa)*2, size(abscissa)*2) :: svd_tmp1, svd_tmp2 |
1094 | + real, dimension(size(abscissa)*2) :: SV |
1095 | + integer :: stat, N, i, j, k |
1096 | + real :: curr_time |
1097 | + real, dimension(size(abscissa)) :: perturb |
1098 | + integer :: p_num |
1099 | + real, dimension(size(abscissa)) :: absc_init |
1100 | + |
1101 | + N = size(abscissa) |
1102 | + |
1103 | + nodes => ele_nodes(abscissa(1), ele) |
1104 | + shape => ele_shape(abscissa(1), ele) |
1105 | + |
1106 | + call transform_to_physical(X, ele, shape, dshape=dshape, detwei=detwei) |
1107 | + |
1108 | + ! construct A matrices (lhs knowns) |
1109 | + do i = 1, N |
1110 | + abscissa_val_at_quad(:,i) = ele_val_at_quad(abscissa(i), ele) |
1111 | +!! print*, "abscissa = ", abscissa_val_at_quad(1,i) |
1112 | + end do |
1113 | + A = A_matrix(abscissa_val_at_quad) |
1114 | + |
1115 | + ! construct A_3 matrix (rhs pt.1) |
1116 | + do i = 1, 2*N |
1117 | + do j = 1, N |
1118 | + A_3(:,i,j) = (i-1)*(i-2)*ele_val_at_quad(abscissa(j), ele)**(i-3) |
1119 | + end do |
1120 | + end do |
1121 | + |
1122 | + ! construct C matrix (rhs pt.2) |
1123 | + if (have_D) then |
1124 | + do i = 1, N |
1125 | + D_at_quad = ele_val_at_quad(D, ele) |
1126 | + do j = 1, X%dim |
1127 | + grad_D(j,:) = D_at_quad(j,j,:) |
1128 | + end do |
1129 | + grad_D = ((ele_grad_at_quad(abscissa(i), ele, dshape))**2)*grad_D |
1130 | + C(:,i) = ele_val_at_quad(weight(i), ele)*sum(grad_D,1) |
1131 | + end do |
1132 | + else |
1133 | + C = 0.0 |
1134 | + end if |
1135 | + |
1136 | + |
1137 | + !! gb nov-2012--- |
1138 | + ! initialize dqmom source term to zero |
1139 | + S_rhs = 0.0 |
1140 | + |
1141 | + ! construct S vector (rhs pt.3) for GROWTH term |
1142 | + if (have_growth) then |
1143 | + if (growth_type=='power_law_growth') then |
1144 | + do i = 1, 2*N |
1145 | + do j = 1, N |
1146 | + S_rhs(:,i) = S_rhs(:,i) + (i-1)*ele_val_at_quad(weight(j), ele)*(ele_val_at_quad(abscissa(j), ele)**(i-2))*(ele_val_at_quad(abscissa(j), ele)**growth_r) |
1147 | + end do |
1148 | + end do |
1149 | + end if |
1150 | + end if |
1151 | + |
1152 | + if (have_internal_dispersion) then |
1153 | + do i = 1, 2*N |
1154 | + do j = 1, N |
1155 | + ! S_rhs(:,i) = S_rhs(:,i) + (i-1)*(i-2)*ele_val_at_quad(weight(j), ele)*(ele_val_at_quad(abscissa(j), ele)**(i-3))*Diffusion_internal(j) |
1156 | + ! abscissa_val_at_quad() takes care of the perturbed abscissas |
1157 | + S_rhs(:,i) = S_rhs(:,i) + (i-1)*(i-2)*ele_val_at_quad(weight(j), ele)*(abscissa_val_at_quad(:,j)**(i-3))*internal_dispersion_coeff |
1158 | + end do |
1159 | + end do |
1160 | + end if |
1161 | + |
1162 | + !!! construct S vector for BREAKAGE |
1163 | +! do i = 1, N |
1164 | +! break_freq(:,i) = 0.02*abscissa_val_at_quad(:,i)**3 |
1165 | +! end do |
1166 | + |
1167 | + if (have_breakage) then |
1168 | + if (breakage_freq_type=='constant_breakage') then |
1169 | + break_freq = breakage_freq_const |
1170 | + else if (breakage_freq_type=='power_law_breakage') then |
1171 | + do i = 1, N |
1172 | + break_freq(:,i) = breakage_freq_const*abscissa_val_at_quad(:,i)**breakage_freq_degree |
1173 | + end do |
1174 | + end if |
1175 | + |
1176 | + if (breakage_dist_type=='symmetric_fragmentation') then |
1177 | + do i = 1, 2*N |
1178 | + do j = 1, N |
1179 | + moment_daughter_dist_func(:,i,j) = (2.0**(((3-(i-1))/3.0)))*(abscissa_val_at_quad(:,j)**(i-1)) |
1180 | +! moment_daughter_dist_func(:,i,j) = (2.0**(((3-(i-1))/3.0)))*(ele_val_at_quad(abscissa(j), ele)**(i-1)) |
1181 | + end do |
1182 | + end do |
1183 | + else if (breakage_dist_type=='mcCoy_madras_2003') then |
1184 | + do i = 1, 2*N |
1185 | + do j = 1, N |
1186 | + moment_daughter_dist_func(:,i,j) = (6.0/((i-1)+3.0))*(abscissa_val_at_quad(:,j)**(i-1)) |
1187 | +! moment_daughter_dist_func(:,i,j) = (6.0/((i-1)+3.0))*(ele_val_at_quad(abscissa(j), ele)**(i-1)) |
1188 | + end do |
1189 | + end do |
1190 | + end if |
1191 | + |
1192 | + do i = 1, 2*N |
1193 | + do j = 1, N |
1194 | + ! birth term due to breakage |
1195 | + S_rhs(:,i) = S_rhs(:,i) + break_freq(:,j)*ele_val_at_quad(weight(j), ele)*moment_daughter_dist_func(:,i,j) ! daughter distribution function already includes the factor for number of particles formed after breakage |
1196 | + ! death term due to breakage |
1197 | + S_rhs(:,i) = S_rhs(:,i) - break_freq(:,j)*ele_val_at_quad(weight(j), ele)*(abscissa_val_at_quad(:,j)**(i-1)) |
1198 | +! S_rhs(:,i) = S_rhs(:,i) - break_freq(:,j)*ele_val_at_quad(weight(j), ele)*(ele_val_at_quad(abscissa(j), ele)**(i-1)) |
1199 | + end do |
1200 | + end do |
1201 | + endif |
1202 | + |
1203 | + |
1204 | + !!! construct S vector for AGGREGATION |
1205 | + if (have_aggregation) then |
1206 | + if (aggregation_freq_type=='constant_aggregation') then |
1207 | + aggregation_freq = aggregation_freq_const |
1208 | + else if (aggregation_freq_type=='hydrodynamic_aggregation') then |
1209 | + do i = 1, N |
1210 | + do j = 1, N |
1211 | + aggregation_freq(:,i,j) = abscissa_val_at_quad(:,i)**3 + abscissa_val_at_quad(:,j)**3 |
1212 | + end do |
1213 | + end do |
1214 | + else if (aggregation_freq_type=='sum_aggregation') then |
1215 | + do i = 1, N |
1216 | + do j = 1, N |
1217 | + aggregation_freq(:,i,j) = (abscissa_val_at_quad(:,i) + abscissa_val_at_quad(:,j))*aggregation_freq_const |
1218 | + end do |
1219 | + end do |
1220 | + end if |
1221 | + |
1222 | + do i = 1, 2*N |
1223 | + do j = 1, N |
1224 | + do k = 1, N |
1225 | + ! birth term due to aggregation |
1226 | + S_rhs(:,i) = S_rhs(:,i) + 0.5 * aggregation_freq(:,j,k) * ele_val_at_quad(weight(j), ele) * ele_val_at_quad(weight(k), ele) * & |
1227 | + ((abs(abscissa_val_at_quad(:,j)**3 + abscissa_val_at_quad(:,k)**3)**(1.0/3.0)) * & |
1228 | + sign(1.0,(abscissa_val_at_quad(:,j)**3 + abscissa_val_at_quad(:,k)**3)))**(i-1) |
1229 | +! S_rhs(:,i) = S_rhs(:,i) + 0.5 * aggregation_freq(:,j,k) * ele_val_at_quad(weight(j), ele) * ele_val_at_quad(weight(k), ele) * & |
1230 | +! &(ele_val_at_quad(abscissa(j), ele)**3 + ele_val_at_quad(abscissa(k), ele)**3)**((i-1)/3.0) |
1231 | + ! death term due to aggregation |
1232 | + S_rhs(:,i) = S_rhs(:,i) - aggregation_freq(:,j,k) * ele_val_at_quad(weight(j), ele) * ele_val_at_quad(weight(k), ele) * abscissa_val_at_quad(:,j)**(i-1) |
1233 | +! S_rhs(:,i) = S_rhs(:,i) - aggregation_freq(:,j,k) * ele_val_at_quad(weight(j), ele)*ele_val_at_quad(weight(k), ele)*ele_val_at_quad(abscissa(j), ele)**(i-1) |
1234 | + end do |
1235 | + end do |
1236 | + end do |
1237 | + endif |
1238 | + |
1239 | + !! ---------------- |
1240 | + |
1241 | +! perturb(1) = 0.00 |
1242 | +! perturb(2) = 0.01 |
1243 | +! perturb(3) = -0.01 |
1244 | + ! check for ill-conditioned matrices |
1245 | + if (singular_option=='perturbate') then |
1246 | + do i = 1, ele_ngi(abscissa(1), ele) |
1247 | + call svd(A(i,:,:), svd_tmp1, SV, svd_tmp2) |
1248 | + p_num=1 |
1249 | + do while (SV(size(SV))/SV(1) < cond) |
1250 | + !if (SV(size(SV))/SV(1) < cond) then |
1251 | + print*, "SINGULAR MATRIX" |
1252 | + print*, "condition number=", (SV(size(SV))/SV(1)) |
1253 | + do j = 1, N |
1254 | + !! perturbation coefficient should be taken from diamond options with a check for default value |
1255 | + call random_number(perturb(1)) |
1256 | + perturb(1)=-1.0+2.0*perturb(1) |
1257 | + print*, "perturb(1)=", N, perturb(1) |
1258 | + abscissa_val_at_quad(i,j) = abscissa_val_at_quad(i,j)*(1.0+perturb(1)*perturb_val) |
1259 | + print*, "abscissa", j, " = ", abscissa_val_at_quad(i,j) |
1260 | + end do |
1261 | + A = A_matrix(abscissa_val_at_quad) |
1262 | + call svd(A(i,:,:), svd_tmp1, SV, svd_tmp2) |
1263 | + print*, "perturbed condition number=", (SV(size(SV))/SV(1)) |
1264 | + p_num=p_num+1 |
1265 | + print*, "p_num=", p_num |
1266 | +! if (SV(size(SV))/SV(1) < cond) then |
1267 | +! print*, "perturbing does not help" |
1268 | +! end if |
1269 | +! end if |
1270 | + end do |
1271 | + end do |
1272 | + else if (singular_option=='set_source_to_zero') then |
1273 | + do i = 1, ele_ngi(abscissa(1), ele) |
1274 | + call svd(A(i,:,:), svd_tmp1, SV, svd_tmp2) |
1275 | + if (SV(size(SV))/SV(1) < cond) then |
1276 | + ewrite(2,*) 'ill-conditioned matrix found', SV(size(SV))/SV(1) |
1277 | + A(i,:,:) = 0.0 |
1278 | + A_3(i,:,:) = 0.0 |
1279 | + C(i,:) = 0.0 |
1280 | + do j = 1, 2*N |
1281 | + A(i,j,j) = 1.0 |
1282 | + end do |
1283 | + end if |
1284 | + end do |
1285 | + end if |
1286 | +!! p_num = 1 |
1287 | + |
1288 | + |
1289 | +!! do j = 1, N |
1290 | +!! absc_init(j) = abscissa_val_at_quad(i,j) |
1291 | +!! end do |
1292 | + |
1293 | +!! do while (SV(size(SV))/SV(1) < cond) |
1294 | +! call get_option("/timestepping/current_time", curr_time) ! get the current simulation time |
1295 | + !! a better check for the first timestep instead of small value of the current time |
1296 | + ! if (curr_time < 1e-7) then ! this block perturbates the abscissas in A matrix if current time is 0 |
1297 | +!! print*, "perturbing %g \n", p_num |
1298 | +!! do j = 1, N |
1299 | + !! perturbation coefficient should be taken from diamond options with a check for default value |
1300 | +!! call random_number(perturb(1)) |
1301 | +!! abscissa_val_at_quad(i,j) = absc_init(j) + perturb(1) |
1302 | +! abscissa_val_at_quad(:,j) = abscissa_val_at_quad(:,j) + (2-j)*(0.1) |
1303 | +!! print*, "abscissa", j, " = ", abscissa_val_at_quad(i,j) |
1304 | +!! end do |
1305 | +!! A = A_matrix(abscissa_val_at_quad) |
1306 | +!! call svd(A(i,:,:), svd_tmp1, SV, svd_tmp2) |
1307 | +!! print*, "condition number=", (SV(size(SV))/SV(1)) |
1308 | +!! p_num = p_num+1 |
1309 | +! print*, "perturbed condition number=", (SV(size(SV))/SV(1)) |
1310 | +! if (SV(size(SV))/SV(1) < cond) then |
1311 | +! print*, "perturbing does not help" |
1312 | +! end if |
1313 | + |
1314 | +! else |
1315 | +! ewrite(2,*) 'ill-conditioned matrix found' |
1316 | +! A(i,:,:) = 0.0 |
1317 | +! A_3(i,:,:) = 0.0 |
1318 | +! C(i,:) = 0.0 |
1319 | +! do j = 1, 2*N |
1320 | +! A(i,j,j) = 1.0 |
1321 | +! end do |
1322 | +! end if |
1323 | +! end if |
1324 | +!! end do |
1325 | +! end do |
1326 | + |
1327 | + |
1328 | + |
1329 | + |
1330 | + ! solve linear system to find source values |
1331 | + do i = 1, ele_ngi(abscissa(1), ele) |
1332 | + b(:,1) = matmul(A_3(i,:,:), C(i,:)) + S_rhs(i,:) !! gb 15-11-2012! added S_rhs term |
1333 | + call dqmom_solve(A(i,:,:), b, stat) |
1334 | + weight_S_at_quad(i,:) = b(:N,1) |
1335 | + abscissa_S_at_quad(i,:) = b(N+1:,1) |
1336 | + end do |
1337 | + |
1338 | + ! In the DG case we apply the inverse mass locally. |
1339 | + invmass = inverse(shape_shape(shape, shape, detwei)) |
1340 | + |
1341 | + ! integrate and add to source fields |
1342 | + do i = 1, N |
1343 | + weight_S_at_nodes = shape_rhs(shape, detwei* weight_S_at_quad(:,i)) |
1344 | + abscissa_S_at_nodes = shape_rhs(shape, detwei* abscissa_S_at_quad(:,i)) |
1345 | + if(continuity(abscissa(1))<0) then |
1346 | + weight_S_at_nodes = matmul(weight_S_at_nodes, invmass) |
1347 | + abscissa_S_at_nodes = matmul(abscissa_S_at_nodes, invmass) |
1348 | + end if |
1349 | + call addto(s_weight(i)%ptr, nodes, weight_S_at_nodes) |
1350 | + call addto(s_weighted_abscissa(i)%ptr, nodes, abscissa_S_at_nodes) |
1351 | + end do |
1352 | + |
1353 | + end subroutine dqmom_calculate_source_term_ele |
1354 | + |
1355 | + function A_matrix(abscissa) |
1356 | + |
1357 | + real, dimension(:,:), intent(in) :: abscissa |
1358 | + |
1359 | + real, dimension(size(abscissa,1), size(abscissa,2)*2, size(abscissa,2)*2) :: A_matrix |
1360 | + integer :: i, j, N |
1361 | + |
1362 | + N = size(abscissa,2) |
1363 | + do i = 1, 2*N |
1364 | + do j = 1, N |
1365 | + A_matrix(:,i,j) = (2-i)*abscissa(:,j)**(i-1) |
1366 | + A_matrix(:,i,j+N) = (i-1)*abscissa(:,j)**(i-2) |
1367 | + end do |
1368 | + end do |
1369 | + |
1370 | + end function A_matrix |
1371 | + |
1372 | + subroutine dqmom_solve(A, b, stat) |
1373 | + !!< Solve Ax=b for right hand sides b putting the result in b. |
1374 | + !!< |
1375 | + !!< This is simply a wrapper for lapack. |
1376 | + real, dimension(:,:), intent(in) :: A |
1377 | + real, dimension(:,:), intent(inout) :: b |
1378 | + integer, optional, intent(out) :: stat |
1379 | + |
1380 | + real, dimension(size(A,1), size(A,2)) :: Atmp |
1381 | + integer, dimension(size(A,1)) :: ipiv |
1382 | + integer :: info |
1383 | + |
1384 | + interface |
1385 | +#ifdef DOUBLEP |
1386 | + SUBROUTINE DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO ) |
1387 | + INTEGER :: INFO, LDA, LDB, N, NRHS |
1388 | + INTEGER :: IPIV( * ) |
1389 | + REAL :: A( LDA, * ), B( LDB, * ) |
1390 | + END SUBROUTINE DGESV |
1391 | +#else |
1392 | + SUBROUTINE SGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO ) |
1393 | + INTEGER :: INFO, LDA, LDB, N, NRHS |
1394 | + INTEGER :: IPIV( * ) |
1395 | + REAL :: A( LDA, * ), B( LDB, * ) |
1396 | + END SUBROUTINE SGESV |
1397 | +#endif |
1398 | + end interface |
1399 | + |
1400 | + if (present(stat)) stat = 0 |
1401 | + |
1402 | + Atmp=A |
1403 | + |
1404 | +#ifdef DOUBLEP |
1405 | + call dgesv(& |
1406 | +#else |
1407 | + call sgesv(& |
1408 | +#endif |
1409 | + size(A,1), size(b,2), Atmp, size(A,1), ipiv, b, size(b,1), info) |
1410 | + |
1411 | + if (present(stat)) then |
1412 | + stat = info |
1413 | + end if |
1414 | + |
1415 | + end subroutine dqmom_solve |
1416 | + |
1417 | + subroutine dqmom_calculate_moments(state) |
1418 | + |
1419 | + type(state_type), intent(in) :: state |
1420 | + |
1421 | + type(scalar_field), pointer :: abscissa, weight, moment |
1422 | + type(scalar_field) :: work |
1423 | + integer :: i_pop, N, i_moment, i_abscissa, i |
1424 | + character(len=OPTION_PATH_LEN) :: option_path |
1425 | + character(len=FIELD_NAME_LEN) :: type |
1426 | + |
1427 | + ewrite(1, *) "In dqmom_calculate_moments" |
1428 | + do i_pop = 1, option_count(trim(state%option_path)//'/population_balance') |
1429 | + call get_pop_option_path(state, i_pop, option_path) |
1430 | + N = option_count(trim(option_path)//'/abscissa/scalar_field') |
1431 | + do i_moment = 1, 2*N |
1432 | + type = 'moments' |
1433 | + call get_pop_field(state, i_pop, i_moment, type, moment) |
1434 | + call zero(moment) |
1435 | + call allocate(work, moment%mesh, 'work') |
1436 | + do i_abscissa = 1, N |
1437 | + ! get required fields |
1438 | + type = 'abscissa' |
1439 | + call get_pop_field(state, i_pop, i_abscissa, type, abscissa) |
1440 | + type = 'weights' |
1441 | + call get_pop_field(state, i_pop, i_abscissa, type, weight) |
1442 | + |
1443 | + ! calculate moment -> m(i) = sum_j(w(j)*q(j)**i) |
1444 | + call zero(work) |
1445 | + call set(work, 1.0) |
1446 | + do i = 1, i_moment - 1 |
1447 | + call scale(work, abscissa) |
1448 | + end do |
1449 | + call scale(work, weight) |
1450 | + call addto(moment, work) |
1451 | + end do |
1452 | + call deallocate(work) |
1453 | + end do |
1454 | + end do |
1455 | + ewrite(1, *) "Exiting dqmom_calculate_moments" |
1456 | + end subroutine dqmom_calculate_moments |
1457 | + |
1458 | + subroutine dqmom_calculate_statistics(state) |
1459 | + |
1460 | + type(state_type), intent(in) :: state |
1461 | + |
1462 | + type(scalar_field_pointer), dimension(:), allocatable :: moments |
1463 | + type(scalar_field), pointer :: stats |
1464 | + integer :: i_pop, N, i, j, i_stat |
1465 | + real :: mean, std, scaling_factor_Dia |
1466 | + character(len=OPTION_PATH_LEN) :: option_path |
1467 | + character(len=FIELD_NAME_LEN) :: type |
1468 | + |
1469 | + ewrite(1, *) "In dqmom_calculate_statistics" |
1470 | + do i_pop = 1, option_count(trim(state%option_path)//'/population_balance') |
1471 | + call get_pop_option_path(state, i_pop, option_path) |
1472 | + |
1473 | + if (option_count(trim(option_path)//'/statistics/scalar_field') > 0) then |
1474 | + |
1475 | + N = option_count(trim(option_path)//'/moments/scalar_field') |
1476 | + allocate(moments(N)) |
1477 | + do i = 1, N |
1478 | + ! get required fields |
1479 | + type = 'moments' |
1480 | + call get_pop_field(state, i_pop, i, type, moments(i)%ptr) |
1481 | + end do |
1482 | + |
1483 | + type = 'statistics' |
1484 | + do i_stat = 1, option_count(trim(option_path)//'/statistics/scalar_field') |
1485 | + call get_pop_field(state, i_pop, i_stat, type, stats) |
1486 | + if (trim(stats%name) == "Mean") then |
1487 | + call zero(stats) |
1488 | + do j = 1, node_count(stats) |
1489 | + call set(stats, j, node_val(moments(2)%ptr,j)/node_val(moments(1)%ptr,j)) |
1490 | + end do |
1491 | + end if |
1492 | + if (trim(stats%name) == "StandardDeviation") then |
1493 | + call zero(stats) |
1494 | + do j = 1, node_count(stats) |
1495 | + mean = node_val(moments(2)%ptr,j)/node_val(moments(1)%ptr,j) |
1496 | + call set(stats, j, (node_val(moments(3)%ptr,j)/node_val(moments(1)%ptr,j) -& |
1497 | + mean**2)**0.5) |
1498 | + end do |
1499 | + end if |
1500 | + if (trim(stats%name) == "Skew") then |
1501 | + call zero(stats) |
1502 | + do j = 1, node_count(stats) |
1503 | + mean = node_val(moments(2)%ptr,j)/node_val(moments(1)%ptr,j) |
1504 | + std = (node_val(moments(3)%ptr,j)/node_val(moments(1)%ptr,j) - mean**2)**0.5 |
1505 | + call set(stats, j, & |
1506 | + (node_val(moments(4)%ptr,j)/node_val(moments(1)%ptr,j) - & |
1507 | + 3*mean*std**2.0 - mean**3.0) / std**3.0) |
1508 | + end do |
1509 | + end if |
1510 | + if (trim(stats%name) == "SauterMeanDia") then |
1511 | + call zero(stats) |
1512 | + if (have_option(trim(option_path)//'/scaling_factor_Dia')) then |
1513 | + call get_option(trim(option_path)//'/scaling_factor_Dia', scaling_factor_Dia) |
1514 | + else |
1515 | + scaling_factor_Dia=1.0 |
1516 | + end if |
1517 | + do j = 1, node_count(stats) |
1518 | + call set(stats, j, scaling_factor_Dia*(node_val(moments(4)%ptr,j)/node_val(moments(3)%ptr,j)) ) |
1519 | + end do |
1520 | + end if |
1521 | + if (trim(stats%name) == "MeanDia10") then |
1522 | + call zero(stats) |
1523 | + if (have_option(trim(option_path)//'/scaling_factor_Dia')) then |
1524 | + call get_option(trim(option_path)//'/scaling_factor_Dia', scaling_factor_Dia) |
1525 | + else |
1526 | + scaling_factor_Dia=1.0 |
1527 | + end if |
1528 | + do j = 1, node_count(stats) |
1529 | + call set(stats, j, scaling_factor_Dia*(node_val(moments(2)%ptr,j)/node_val(moments(1)%ptr,j)) ) |
1530 | + end do |
1531 | + end if |
1532 | + |
1533 | + end do |
1534 | + |
1535 | + deallocate(moments) |
1536 | + |
1537 | + end if |
1538 | + end do |
1539 | + ewrite(1, *) "Exiting dqmom_calculate_statistics" |
1540 | + |
1541 | + |
1542 | + end subroutine dqmom_calculate_statistics |
1543 | + |
1544 | + subroutine dqmom_check_options(state) |
1545 | + |
1546 | + type(state_type), intent(in) :: state |
1547 | + |
1548 | + integer :: i_pop |
1549 | + integer :: n_abscissa, n_weights, n_weighted_abscissa, n_moments |
1550 | + character(len=OPTION_PATH_LEN) :: option_path |
1551 | + |
1552 | + write(*,*) 'in dqmom_check_options' |
1553 | + |
1554 | + do i_pop = 1, option_count(trim(state%option_path)//'/population_balance') |
1555 | + option_path = trim(state%option_path)//'/population_balance['//int2str(i_pop)//']' |
1556 | + |
1557 | + ! Check there are the same number of abscissa, weight and weighted abscissa fields |
1558 | + n_abscissa = option_count(trim(option_path)//'/abscissa/scalar_field') |
1559 | + n_weights = option_count(trim(option_path)//'/weights/scalar_field') |
1560 | + n_weighted_abscissa = option_count(trim(option_path)// & |
1561 | + '/weighted_abscissa/scalar_field') |
1562 | + assert(n_weights == n_abscissa) |
1563 | + assert(n_weights == n_weighted_abscissa) |
1564 | + |
1565 | + ! Check there are sufficient abscissa to calculate requested moments |
1566 | + n_moments = option_count(trim(option_path)//'/moments/scalar_field') |
1567 | + assert((n_moments / 2) == n_abscissa) |
1568 | + |
1569 | + ! Need to check that all fields are on the same mesh |
1570 | + end do |
1571 | + |
1572 | + end subroutine dqmom_check_options |
1573 | + |
1574 | +end module dqmom |
1575 | |
1576 | === added file 'population_balance/Makefile.dependencies' |
1577 | --- population_balance/Makefile.dependencies 1970-01-01 00:00:00 +0000 |
1578 | +++ population_balance/Makefile.dependencies 2013-12-12 22:35:40 +0000 |
1579 | @@ -0,0 +1,10 @@ |
1580 | +# Dependencies generated by create_makefile.py. DO NOT EDIT |
1581 | +../include/dqmom.mod: DQMOM.o |
1582 | + @true |
1583 | + |
1584 | +DQMOM.o ../include/dqmom.mod: DQMOM.F90 ../include/fdebug.h \ |
1585 | + ../include/fields.mod ../include/global_parameters.mod \ |
1586 | + ../include/initialise_fields_module.mod ../include/spud.mod \ |
1587 | + ../include/state_fields_module.mod ../include/state_module.mod \ |
1588 | + ../include/vector_tools.mod |
1589 | + |
1590 | |
1591 | === added file 'population_balance/Makefile.in' |
1592 | --- population_balance/Makefile.in 1970-01-01 00:00:00 +0000 |
1593 | +++ population_balance/Makefile.in 2013-12-12 22:35:40 +0000 |
1594 | @@ -0,0 +1,66 @@ |
1595 | +# Copyright (C) 2006 Imperial College London and others. |
1596 | +# |
1597 | +# Please see the AUTHORS file in the main source directory for a full list |
1598 | +# of copyright holders. |
1599 | +# |
1600 | +# Prof. C Pain |
1601 | +# Applied Modelling and Computation Group |
1602 | +# Department of Earth Science and Engineering |
1603 | +# Imperial College London |
1604 | +# |
1605 | +# amcgsoftware@imperial.ac.uk |
1606 | +# |
1607 | +# This library is free software; you can redistribute it and/or |
1608 | +# modify it under the terms of the GNU Lesser General Public |
1609 | +# License as published by the Free Software Foundation, |
1610 | +# version 2.1 of the License. |
1611 | +# |
1612 | +# This library is distributed in the hope that it will be useful, |
1613 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1614 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1615 | +# Lesser General Public License for more details. |
1616 | +# |
1617 | +# You should have received a copy of the GNU Lesser General Public |
1618 | +# License along with this library; if not, write to the Free Software |
1619 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
1620 | +# USA |
1621 | +SHELL = @SHELL@ |
1622 | + |
1623 | +PACKAGE_NAME = @PACKAGE_NAME@ |
1624 | +FLUIDITY = $(PACKAGE_NAME) |
1625 | + |
1626 | +FC = @FC@ |
1627 | +FCFLAGS = -I../include @MOD_FLAG@../include @FCFLAGS@ -I/usr/local/include -I./ |
1628 | + |
1629 | +CC = @CC@ |
1630 | +CFLAGS = @CFLAGS@ -I../include -I/usr/local/include |
1631 | + |
1632 | +CXX = @CXX@ |
1633 | +CXXFLAGS= @CXXFLAGS@ -I../include -I/usr/local/include |
1634 | + |
1635 | +MAKE = @MAKE@ |
1636 | +AR = @AR@ |
1637 | +ARFLAGS = @ARFLAGS@ |
1638 | + |
1639 | +LIB = ../lib/lib$(FLUIDITY).a |
1640 | + |
1641 | +OBJS = DQMOM.o \ |
1642 | + |
1643 | +.SUFFIXES: .f90 .F90 .c .o .a |
1644 | + |
1645 | +.f90.o: |
1646 | + @echo " FC $<" |
1647 | + $(FC) $(FCFLAGS) -c $< |
1648 | +.F90.o: |
1649 | + @echo " FC $<" |
1650 | + $(FC) $(FCFLAGS) $(GENFLAGS) -c $< |
1651 | + |
1652 | +$(LIB): $(OBJS) |
1653 | + @mkdir -p ../lib |
1654 | + |
1655 | +default: $(LIB) |
1656 | + |
1657 | +clean: |
1658 | + rm -f *.o *.d *.mod |
1659 | + |
1660 | +include Makefile.dependencies |
1661 | |
1662 | === modified file 'preprocessor/Field_Priority_Lists.F90' |
1663 | --- preprocessor/Field_Priority_Lists.F90 2013-02-01 17:50:12 +0000 |
1664 | +++ preprocessor/Field_Priority_Lists.F90 2013-12-12 22:35:40 +0000 |
1665 | @@ -133,6 +133,37 @@ |
1666 | end do |
1667 | end if |
1668 | |
1669 | + ! added as hack for now - but this whole set up of fields could be way better! |
1670 | + ! prognostic pop balance fields - very limited applicability |
1671 | + if (have_option('/material_phase['//int2str(p)//']/population_balance/')) then |
1672 | + do f = 0, option_count('/material_phase['//int2str(p)//& |
1673 | + ']/population_balance/weights/scalar_field') - 1 |
1674 | + nsol=nsol+1 |
1675 | + temp_field_optionpath_list(nsol)='/material_phase['//int2str(p)// & |
1676 | + ']/population_balance/weights/scalar_field['//int2str(f)//']' |
1677 | + call get_option('/material_phase['//int2str(p)//& |
1678 | + ']/population_balance/weights/scalar_field['//int2str(f)//& |
1679 | + ']/name',temp_field_name_list(nsol)) |
1680 | + call get_option('/material_phase['//int2str(p)//& |
1681 | + ']/population_balance/weights/scalar_field['//int2str(f)//& |
1682 | + ']/prognostic/priority', priority(nsol), default=0) |
1683 | + temp_field_state_list(nsol) = p+1 |
1684 | + end do |
1685 | + do f = 0, option_count('/material_phase['//int2str(p)//& |
1686 | + ']/population_balance/weighted_abscissa/scalar_field') - 1 |
1687 | + nsol=nsol+1 |
1688 | + temp_field_optionpath_list(nsol)='/material_phase['//int2str(p)// & |
1689 | + ']/population_balance/weighted_abscissa/scalar_field['//int2str(f)//']' |
1690 | + call get_option('/material_phase['//int2str(p)//& |
1691 | + ']/population_balance/weighted_abscissa/scalar_field['//int2str(f)//& |
1692 | + ']/name',temp_field_name_list(nsol)) |
1693 | + call get_option('/material_phase['//int2str(p)//& |
1694 | + ']/population_balance/weighted_abscissa/scalar_field['//int2str(f)//& |
1695 | + ']/prognostic/priority', priority(nsol), default=0) |
1696 | + temp_field_state_list(nsol) = p+1 |
1697 | + end do |
1698 | + end if |
1699 | + |
1700 | ! prognostic Mellor Yamada fields: |
1701 | if (have_option('/material_phase[' & |
1702 | //int2str(p)//']/subgridscale_parameterisations/Mellor_Yamada/scalar_field::KineticEnergy/prognostic')) then |
1703 | @@ -315,6 +346,17 @@ |
1704 | ntsol = ntsol + 1 |
1705 | end if |
1706 | end do |
1707 | + |
1708 | + ! added as hack for now - but this whole set up of fields could be way better! |
1709 | + ! prognostic pop balance fields - very limited applicability |
1710 | + if (have_option('/material_phase['//int2str(p)//']/population_balance/')) then |
1711 | + ntsol = ntsol + & |
1712 | + option_count('/material_phase['//int2str(p)//& |
1713 | + ']/population_balance/weights/scalar_field') + & |
1714 | + option_count('/material_phase['//int2str(p)//& |
1715 | + ']/population_balance/weighted_abscissa/scalar_field') |
1716 | + end if |
1717 | + |
1718 | ! prognostic scalar fields for Mellor Yamada: |
1719 | if (have_option('/material_phase[' & |
1720 | //int2str(p)//']/subgridscale_parameterisations/Mellor_Yamada/scalar_field::KineticEnergy/prognostic')) then |
1721 | |
1722 | === modified file 'preprocessor/Populate_State.F90' |
1723 | --- preprocessor/Populate_State.F90 2013-10-28 06:46:48 +0000 |
1724 | +++ preprocessor/Populate_State.F90 2013-12-12 22:35:40 +0000 |
1725 | @@ -97,7 +97,7 @@ |
1726 | |
1727 | !! A list of relative paths under /material_phase[i] |
1728 | !! that are searched for additional fields to be added. |
1729 | - character(len=OPTION_PATH_LEN), dimension(13) :: additional_fields_relative=& |
1730 | + character(len=OPTION_PATH_LEN), dimension(18) :: additional_fields_relative=& |
1731 | (/ & |
1732 | "/subgridscale_parameterisations/Mellor_Yamada ", & |
1733 | "/subgridscale_parameterisations/prescribed_diffusivity ", & |
1734 | @@ -111,7 +111,12 @@ |
1735 | "/vector_field::Velocity/prognostic/spatial_discretisation/continuous_galerkin/les_model/dynamic_les ", & |
1736 | "/vector_field::Velocity/prognostic/equation::ShallowWater ", & |
1737 | "/vector_field::Velocity/prognostic/equation::ShallowWater/bottom_drag ", & |
1738 | - "/vector_field::BedShearStress/diagnostic/calculation_method/velocity_gradient " & |
1739 | + "/vector_field::BedShearStress/diagnostic/calculation_method/velocity_gradient ", & |
1740 | + "/population_balance[#]/abscissa/ ", & |
1741 | + "/population_balance[#]/weights/ ", & |
1742 | + "/population_balance[#]/weighted_abscissa/ ", & |
1743 | + "/population_balance[#]/moments/ ", & |
1744 | + "/population_balance[#]/statistics/ " & |
1745 | /) |
1746 | |
1747 | !! Relative paths under a field that are searched for grandchildren |
1748 | @@ -121,6 +126,22 @@ |
1749 | & "/spatial_discretisation/inner_element" & |
1750 | /) |
1751 | |
1752 | + |
1753 | + !! Dynamic paths that are searched for fields |
1754 | + !! This allows for searching for field within paths that may branch several times |
1755 | + !! The index of any particular path should be replaced with # |
1756 | + character(len=OPTION_PATH_LEN), dimension(6):: & |
1757 | + dynamic_paths = (/& |
1758 | + & "/material_phase[#]/equation_of_state/fluids/linear/ ", & |
1759 | + & "/material_phase[#]/population_balance[#]/abscissa/ ", & |
1760 | + & "/material_phase[#]/population_balance[#]/weights/ ", & |
1761 | + & "/material_phase[#]/population_balance[#]/weighted_abscissa/", & |
1762 | + & "/material_phase[#]/population_balance[#]/moments/ ", & |
1763 | + & "/material_phase[#]/population_balance[#]/statistics/ " & |
1764 | + /) |
1765 | + |
1766 | + character(len=OPTION_PATH_LEN), dimension(:), allocatable :: field_locations |
1767 | + |
1768 | contains |
1769 | |
1770 | |
1771 | |
1772 | === modified file 'schemas/diagnostic_algorithms.rnc' |
1773 | --- schemas/diagnostic_algorithms.rnc 2013-02-21 15:25:41 +0000 |
1774 | +++ schemas/diagnostic_algorithms.rnc 2013-12-12 22:35:40 +0000 |
1775 | @@ -1289,7 +1289,8 @@ |
1776 | }, |
1777 | ## The particle diameter |
1778 | element particle_diameter { |
1779 | - real |
1780 | + element constant { real }| |
1781 | + element use_scalar_field { anystring } |
1782 | }, |
1783 | ## The name of the state representing the continuous phase |
1784 | element continuous_phase_name { |
1785 | |
1786 | === modified file 'schemas/diagnostic_algorithms.rng' |
1787 | --- schemas/diagnostic_algorithms.rng 2013-02-21 15:25:41 +0000 |
1788 | +++ schemas/diagnostic_algorithms.rng 2013-12-12 22:35:40 +0000 |
1789 | @@ -1754,7 +1754,14 @@ |
1790 | </element> |
1791 | <element name="particle_diameter"> |
1792 | <a:documentation>The particle diameter</a:documentation> |
1793 | - <ref name="real"/> |
1794 | + <choice> |
1795 | + <element name="constant"> |
1796 | + <ref name="real"/> |
1797 | + </element> |
1798 | + <element name="use_scalar_field"> |
1799 | + <ref name="anystring"/> |
1800 | + </element> |
1801 | + </choice> |
1802 | </element> |
1803 | <element name="continuous_phase_name"> |
1804 | <a:documentation>The name of the state representing the continuous phase</a:documentation> |
1805 | |
1806 | === modified file 'schemas/fluidity_options.rnc' |
1807 | --- schemas/fluidity_options.rnc 2013-10-11 10:48:07 +0000 |
1808 | +++ schemas/fluidity_options.rnc 2013-12-12 22:35:40 +0000 |
1809 | @@ -1472,6 +1472,7 @@ |
1810 | scalar_field_choice*, |
1811 | vector_field_choice*, |
1812 | tensor_field_choice*, |
1813 | + population_balance*, |
1814 | ## Parameters required to model spontaneous electrical potentials in porous media. |
1815 | element electrical_properties { |
1816 | ( |
1817 | @@ -1613,8 +1614,9 @@ |
1818 | ## Phase interaction options for Fluidity's multiphase flow model |
1819 | element multiphase_properties { |
1820 | comment, |
1821 | - element particle_diameter { |
1822 | - real |
1823 | + element particle_diameter { |
1824 | + element constant { real }| |
1825 | + element use_scalar_field { anystring } |
1826 | }?, |
1827 | ## If this is the fluid phase, |
1828 | ## the effective conductivity is required |
1829 | @@ -1814,6 +1816,450 @@ |
1830 | } |
1831 | ) |
1832 | |
1833 | +population_balance = |
1834 | + ( |
1835 | + ## |
1836 | + element population_balance { |
1837 | + ( |
1838 | + ## Determine initial weighted_abscissa and weights using the PD algorithm and the |
1839 | + ## initial conditions set in the diagnostic moment fields. |
1840 | + ## |
1841 | + ## In this case it does not matter what is set in the weighted_abscissa and weights |
1842 | + ## fields initial conditions option |
1843 | + element calculate_initial_conditions_from_moments { |
1844 | + empty |
1845 | + }| |
1846 | + ## Use initial conditions set in the weighted_abscissa and weights prognostic |
1847 | + ## fields |
1848 | + ## |
1849 | + ## In this case it does not matter what is set in the moment field initial conditions |
1850 | + ## options |
1851 | + element use_prognostic_field_initial_conditions { |
1852 | + empty |
1853 | + } |
1854 | + ), |
1855 | + attribute name { xsd:string }, |
1856 | + element abscissa { |
1857 | + element scalar_field { |
1858 | + attribute rank { "0" }, |
1859 | + attribute name { "Abscissa_0" }, |
1860 | + ## Field type |
1861 | + element diagnostic { |
1862 | + internal_algorithm, |
1863 | + velocity_mesh_choice, |
1864 | + diagnostic_scalar_field |
1865 | + } |
1866 | + }, |
1867 | + element scalar_field { |
1868 | + attribute rank { "0" }, |
1869 | + attribute name { "Abscissa_1" }, |
1870 | + ## Field type |
1871 | + element diagnostic { |
1872 | + internal_algorithm, |
1873 | + velocity_mesh_choice, |
1874 | + diagnostic_scalar_field |
1875 | + } |
1876 | + }, |
1877 | + element scalar_field { |
1878 | + attribute rank { "0" }, |
1879 | + attribute name { xsd:string }, |
1880 | + ## Field type |
1881 | + element diagnostic { |
1882 | + internal_algorithm, |
1883 | + velocity_mesh_choice, |
1884 | + diagnostic_scalar_field |
1885 | + } |
1886 | + }* |
1887 | + }, |
1888 | + element weights { |
1889 | + element scalar_field { |
1890 | + attribute rank { "0" }, |
1891 | + attribute name { "Weight_0" }, |
1892 | + ## Field type |
1893 | + element prognostic { |
1894 | + velocity_mesh_choice, |
1895 | + prognostic_scalar_field |
1896 | + } |
1897 | + }, |
1898 | + element scalar_field { |
1899 | + attribute rank { "0" }, |
1900 | + attribute name { "Weight_1" }, |
1901 | + ## Field type |
1902 | + element prognostic { |
1903 | + velocity_mesh_choice, |
1904 | + prognostic_scalar_field |
1905 | + } |
1906 | + }, |
1907 | + element scalar_field { |
1908 | + attribute rank { "0" }, |
1909 | + attribute name { xsd:string }, |
1910 | + ## Field type |
1911 | + element prognostic { |
1912 | + velocity_mesh_choice, |
1913 | + prognostic_scalar_field |
1914 | + } |
1915 | + }* |
1916 | + }, |
1917 | + element weighted_abscissa { |
1918 | + element scalar_field { |
1919 | + attribute rank { "0" }, |
1920 | + attribute name { "WeightedAbscissa_0" }, |
1921 | + ## Field type |
1922 | + element prognostic { |
1923 | + velocity_mesh_choice, |
1924 | + prognostic_scalar_field |
1925 | + } |
1926 | + }, |
1927 | + element scalar_field { |
1928 | + attribute rank { "0" }, |
1929 | + attribute name { "WeightedAbscissa_1" }, |
1930 | + ## Field type |
1931 | + element prognostic { |
1932 | + velocity_mesh_choice, |
1933 | + prognostic_scalar_field |
1934 | + } |
1935 | + }, |
1936 | + element scalar_field { |
1937 | + attribute rank { "0" }, |
1938 | + attribute name { xsd:string }, |
1939 | + ## Field type |
1940 | + element prognostic { |
1941 | + velocity_mesh_choice, |
1942 | + prognostic_scalar_field |
1943 | + } |
1944 | + }* |
1945 | + }, |
1946 | + ## This option only works if you are using a continuous mesh for the population balance scalar fields. |
1947 | + ## A DG mesh will use inverse mass calculated at element level. |
1948 | + ## In the population balance DQMOM algorithm all sources for the |
1949 | + ## advection-diffusion equations are calculated at the quadrature points first |
1950 | + ## and then interpolated back to the nodal points. |
1951 | + ## For a continuous mesh, this interpolation is made by inverting the mass matrix. |
1952 | + ## Mass lumping is fairly quick and can be used with 1st order continuous meshes. |
1953 | + ## But the error is high for higher order continuous meshes and full mass matrix should be used. |
1954 | + element adv_diff_source_term_interpolation { |
1955 | + ## The mass matrix is lumped to obtain source fields at nodal points. |
1956 | + element use_mass_lumping { empty } | |
1957 | + ## Full mass marix is used and the linear system is solved iteratively to obtain source fields at nodal points. |
1958 | + element use_full_mass_matrix { |
1959 | + ## This block specifies the solver options for solving the linear system to interpolate advection-diffusion source terms at nodal points. |
1960 | + element solver { |
1961 | + linear_solver_options_asym_scalar |
1962 | + } |
1963 | + } |
1964 | + }, |
1965 | + element moments { |
1966 | + element scalar_field { |
1967 | + attribute rank { "0" }, |
1968 | + attribute name { "Moment_0" }, |
1969 | + element diagnostic { |
1970 | + internal_algorithm, |
1971 | + velocity_mesh_choice, |
1972 | + ( |
1973 | + ## Initial condition for WholeMesh |
1974 | + ## |
1975 | + ## Only specify one condition if not using mesh regions. |
1976 | + ## Otherwise select other initial_condition option, specify region_ids |
1977 | + ## and distinct names. Then add extra intial conditions for other regions. |
1978 | + element initial_condition { |
1979 | + attribute name { "WholeMesh" }, |
1980 | + input_choice_initial_condition_real |
1981 | + }| |
1982 | + ## Multiple initial_conditions are allowed if specifying |
1983 | + ## different values in different |
1984 | + ## regions of the mesh (defined by region_ids). In this case |
1985 | + ## each initial_condition |
1986 | + ## requires a distinct name for the options dictionary. |
1987 | + element initial_condition { |
1988 | + attribute name { string }, |
1989 | + region_ids?, |
1990 | + input_choice_initial_condition_real |
1991 | + } |
1992 | + )+, |
1993 | + diagnostic_scalar_field |
1994 | + } |
1995 | + }, |
1996 | + element scalar_field { |
1997 | + attribute rank { "0" }, |
1998 | + attribute name { "Moment_1" }, |
1999 | + element diagnostic { |
2000 | + internal_algorithm, |
2001 | + velocity_mesh_choice, |
2002 | + ( |
2003 | + ## Initial condition for WholeMesh |
2004 | + ## |
2005 | + ## Only specify one condition if not using mesh regions. |
2006 | + ## Otherwise select other initial_condition option, specify region_ids |
2007 | + ## and distinct names. Then add extra intial conditions for other regions. |
2008 | + element initial_condition { |
2009 | + attribute name { "WholeMesh" }, |
2010 | + input_choice_initial_condition_real |
2011 | + }| |
2012 | + ## Multiple initial_conditions are allowed if specifying |
2013 | + ## different values in different |
2014 | + ## regions of the mesh (defined by region_ids). In this case |
2015 | + ## each initial_condition |
2016 | + ## requires a distinct name for the options dictionary. |
2017 | + element initial_condition { |
2018 | + attribute name { string }, |
2019 | + region_ids?, |
2020 | + input_choice_initial_condition_real |
2021 | + } |
2022 | + )+, |
2023 | + diagnostic_scalar_field |
2024 | + } |
2025 | + }, |
2026 | + element scalar_field { |
2027 | + attribute rank { "0" }, |
2028 | + attribute name { "Moment_2" }, |
2029 | + element diagnostic { |
2030 | + internal_algorithm, |
2031 | + velocity_mesh_choice, |
2032 | + ( |
2033 | + ## Initial condition for WholeMesh |
2034 | + ## |
2035 | + ## Only specify one condition if not using mesh regions. |
2036 | + ## Otherwise select other initial_condition option, specify region_ids |
2037 | + ## and distinct names. Then add extra intial conditions for other regions. |
2038 | + element initial_condition { |
2039 | + attribute name { "WholeMesh" }, |
2040 | + input_choice_initial_condition_real |
2041 | + }| |
2042 | + ## Multiple initial_conditions are allowed if specifying |
2043 | + ## different values in different |
2044 | + ## regions of the mesh (defined by region_ids). In this case |
2045 | + ## each initial_condition |
2046 | + ## requires a distinct name for the options dictionary. |
2047 | + element initial_condition { |
2048 | + attribute name { string }, |
2049 | + region_ids?, |
2050 | + input_choice_initial_condition_real |
2051 | + } |
2052 | + )+, |
2053 | + diagnostic_scalar_field |
2054 | + } |
2055 | + }, |
2056 | + element scalar_field { |
2057 | + attribute rank { "0" }, |
2058 | + attribute name { "Moment_3" }, |
2059 | + element diagnostic { |
2060 | + internal_algorithm, |
2061 | + velocity_mesh_choice, |
2062 | + ( |
2063 | + ## Initial condition for WholeMesh |
2064 | + ## |
2065 | + ## Only specify one condition if not using mesh regions. |
2066 | + ## Otherwise select other initial_condition option, specify region_ids |
2067 | + ## and distinct names. Then add extra intial conditions for other regions. |
2068 | + element initial_condition { |
2069 | + attribute name { "WholeMesh" }, |
2070 | + input_choice_initial_condition_real |
2071 | + }| |
2072 | + ## Multiple initial_conditions are allowed if specifying |
2073 | + ## different values in different |
2074 | + ## regions of the mesh (defined by region_ids). In this case |
2075 | + ## each initial_condition |
2076 | + ## requires a distinct name for the options dictionary. |
2077 | + element initial_condition { |
2078 | + attribute name { string }, |
2079 | + region_ids?, |
2080 | + input_choice_initial_condition_real |
2081 | + } |
2082 | + )+, |
2083 | + diagnostic_scalar_field |
2084 | + } |
2085 | + }, |
2086 | + element scalar_field { |
2087 | + attribute rank { "0" }, |
2088 | + attribute name { xsd:string }, |
2089 | + element diagnostic { |
2090 | + internal_algorithm, |
2091 | + velocity_mesh_choice, |
2092 | + ( |
2093 | + ## Initial condition for WholeMesh |
2094 | + ## |
2095 | + ## Only specify one condition if not using mesh regions. |
2096 | + ## Otherwise select other initial_condition option, specify region_ids |
2097 | + ## and distinct names. Then add extra intial conditions for other regions. |
2098 | + element initial_condition { |
2099 | + attribute name { "WholeMesh" }, |
2100 | + input_choice_initial_condition_real |
2101 | + }| |
2102 | + ## Multiple initial_conditions are allowed if specifying |
2103 | + ## different values in different |
2104 | + ## regions of the mesh (defined by region_ids). In this case |
2105 | + ## each initial_condition |
2106 | + ## requires a distinct name for the options dictionary. |
2107 | + element initial_condition { |
2108 | + attribute name { string }, |
2109 | + region_ids?, |
2110 | + input_choice_initial_condition_real |
2111 | + } |
2112 | + )+, |
2113 | + diagnostic_scalar_field |
2114 | + } |
2115 | + }* |
2116 | + }, |
2117 | + element statistics { |
2118 | + element scalar_field { |
2119 | + attribute rank { "0" }, |
2120 | + attribute name { "Mean" }, |
2121 | + ## Field type |
2122 | + element diagnostic { |
2123 | + internal_algorithm, |
2124 | + velocity_mesh_choice, |
2125 | + diagnostic_scalar_field |
2126 | + } |
2127 | + }?, |
2128 | + element scalar_field { |
2129 | + attribute rank { "0" }, |
2130 | + attribute name { "StandardDeviation" }, |
2131 | + ## Field type |
2132 | + element diagnostic { |
2133 | + internal_algorithm, |
2134 | + velocity_mesh_choice, |
2135 | + diagnostic_scalar_field |
2136 | + } |
2137 | + }?, |
2138 | + element scalar_field { |
2139 | + attribute rank { "0" }, |
2140 | + attribute name { "Skew" }, |
2141 | + ## Field type |
2142 | + element diagnostic { |
2143 | + internal_algorithm, |
2144 | + velocity_mesh_choice, |
2145 | + diagnostic_scalar_field |
2146 | + } |
2147 | + }?, |
2148 | + element scalar_field { |
2149 | + attribute rank { "0" }, |
2150 | + attribute name { "SauterMeanDia" }, |
2151 | + ## Field type |
2152 | + element diagnostic { |
2153 | + internal_algorithm, |
2154 | + velocity_mesh_choice, |
2155 | + diagnostic_scalar_field |
2156 | + } |
2157 | + }?, |
2158 | + element scalar_field { |
2159 | + attribute rank { "0" }, |
2160 | + attribute name { "MeanDia10" }, |
2161 | + ## Field type |
2162 | + element diagnostic { |
2163 | + internal_algorithm, |
2164 | + velocity_mesh_choice, |
2165 | + diagnostic_scalar_field |
2166 | + } |
2167 | + }? |
2168 | + }, |
2169 | + |
2170 | + ## Source terms for the population balance equation like growth, |
2171 | + ## breakage, aggegation and internal dispersion |
2172 | + element population_balance_source_terms { |
2173 | + ## Growth term in the internal coordinate space |
2174 | + element growth{ |
2175 | + ## Enter the growth degree (r) for the power-law growth G(\xi)=\xi^{r} |
2176 | + element power_law_growth{ real } |
2177 | + }?, |
2178 | + ## Dispersion coefficient D. Currently it only works for constant dispersion and can't handle dispersion varying with internal coordinate |
2179 | + element internal_dispersion{ real }?, |
2180 | + ## |
2181 | + element aggregation{ |
2182 | + ## |
2183 | + element aggregation_frequency{ |
2184 | + ## |
2185 | + element constant_aggregation{ real }| |
2186 | + ## aggregation frequency is given by \beta_{alpha gamma} = \xi_{alpha}^3 + \xi_{gamma}^3 |
2187 | + element hydrodynamic_aggregation{ empty }| |
2188 | + ## aggregation frequency is given by \beta_{alpha gamma} = \beta_o (\xi_{alpha} + \xi_{gamma}). Enter the value of constant \beta_o below |
2189 | + element sum_aggregation{ real } |
2190 | + } |
2191 | + }?, |
2192 | + ## |
2193 | + element breakage{ |
2194 | + ## |
2195 | + element breakage_frequency{ |
2196 | + ## |
2197 | + element constant_breakage{ real }| |
2198 | + ## breakage frequency is given by a_{alpha} = p * \xi_{alpha}^r |
2199 | + element power_law_breakage{ |
2200 | + ## coefficient p in breakage frequency a_{alpha} = p * \xi_{alpha}^r |
2201 | + element coefficient{ real }, |
2202 | + ## degree r in breakage frequency a_{alpha} = p * \xi_{alpha}^r |
2203 | + element degree{ real } |
2204 | + } |
2205 | + }, |
2206 | + element distribution_function{ |
2207 | + ## |
2208 | + element symmetric_fragmentation{ empty }| |
2209 | + ## McCoy and Madras (2003) used P(v|v') = 2/v' for v<v' and 0 otherwise, where v stands for volume. |
2210 | + ## When written in terms of particle diameter, this converts to P(x|x')=(6x^2)/x'^3 for x<x' and 0 otherwise. |
2211 | + element mcCoy_madras_2003{ empty } |
2212 | + } |
2213 | + }? |
2214 | + }, |
2215 | + |
2216 | + ## At each vertex a linear system is solved to determine source terms |
2217 | + ## for the abscissa and weight transport equations. This requires inversion |
2218 | + ## of a matrix that has terms that are a function of the weighted abscissa. |
2219 | + ## If any two abscissa happen to lie very close to one another this can cause |
2220 | + ## this matrix to be ill-conditioned which can cause large errors or solver |
2221 | + ## failures when attempting to invert the matrix. There several options for |
2222 | + ## evading this problem: |
2223 | + ## |
2224 | + ## (a) Set the abscissa and weight source terms to zero at the offending vertex. |
2225 | + ## (b) Perturbate the weighted absciss used to construct the matrix until the |
2226 | + ## matrix is no longer ill conditioned and can be inverted. |
2227 | + ## (c) Use the source terms of neighbouring cells (not implemented) |
2228 | + element ill_conditioned_matrices { |
2229 | + ## The required condition number of the matrix. Recommended value of 1e-12 |
2230 | + element required_condition_number{ real }, |
2231 | + ( |
2232 | + ## This is a better option when much of the domain has a minimum 0'th moment |
2233 | + element set_source_to_zero { empty }| |
2234 | + element perturbate{ |
2235 | + ## The amount to perturbate the weighted abscissa. The values are |
2236 | + ## iteratively perturbated by rand(-1,1)*perturbation until the matrix |
2237 | + ## exceeds the required condition number. Too low a value can cause |
2238 | + ## very long run times but a higher value will lead to larger errors. |
2239 | + ## After every ten perturbations at any one grid location a message is |
2240 | + ## printed to the log file noting the difficulties in solving the linear |
2241 | + ## system. |
2242 | + ## Recommended value of 1e-7 |
2243 | + element perturbation{ real } |
2244 | + }| |
2245 | + ## Do not check for ill-conditioning of matrix A |
2246 | + element do_nothing{ empty } |
2247 | + ) |
2248 | + }, |
2249 | + ## weights of zero can cause instabilities. It is recommended that a minimum |
2250 | + ## weight of approx 1e-10 is used. |
2251 | + element minimum_weight{ real }, |
2252 | + ## Scaling factor to be used for the Sauter Mean Diameter / Mean Diameter calculated in the |
2253 | + ## statistics. It is useful in a non-dimensional implementation of the PBE. |
2254 | + element scaling_factor_Dia{ real }?, |
2255 | + ## This is the submerged specific gravity, R, of this population balance |
2256 | + ## as a function of internal coordinate, Z. |
2257 | + ## It will be used in the equation of state. |
2258 | + ## |
2259 | + ## R(Z) = (rho_c(Z) - rho_a)/(rho_a) |
2260 | + ## |
2261 | + ## Where: rho_c(Z) is the density of the dispersed phase and rho_a is |
2262 | + ## the ambient fluid density |
2263 | + ## |
2264 | + ## Must be given as a python function in the form: |
2265 | + ## |
2266 | + ## def R(Z): |
2267 | + ## # Function code |
2268 | + ## return # Return value of R |
2269 | + element submerged_specific_gravity { |
2270 | + python_code |
2271 | + }?, |
2272 | + element output_abscissa_and_weights{ empty }?, |
2273 | + element output_sources{ empty }? |
2274 | + } |
2275 | + ) |
2276 | + |
2277 | sediment = |
2278 | ( |
2279 | ## A sediment model. See the manual for details on how to use this model. |
2280 | |
2281 | === modified file 'schemas/fluidity_options.rng' |
2282 | --- schemas/fluidity_options.rng 2013-11-06 21:30:29 +0000 |
2283 | +++ schemas/fluidity_options.rng 2013-12-12 22:35:40 +0000 |
2284 | @@ -1957,6 +1957,9 @@ |
2285 | <zeroOrMore> |
2286 | <ref name="tensor_field_choice"/> |
2287 | </zeroOrMore> |
2288 | + <zeroOrMore> |
2289 | + <ref name="population_balance"/> |
2290 | + </zeroOrMore> |
2291 | <optional> |
2292 | <element name="electrical_properties"> |
2293 | <a:documentation>Parameters required to model spontaneous electrical potentials in porous media.</a:documentation> |
2294 | @@ -2191,7 +2194,14 @@ |
2295 | <ref name="comment"/> |
2296 | <optional> |
2297 | <element name="particle_diameter"> |
2298 | - <ref name="real"/> |
2299 | + <choice> |
2300 | + <element name="constant"> |
2301 | + <ref name="real"/> |
2302 | + </element> |
2303 | + <element name="use_scalar_field"> |
2304 | + <ref name="anystring"/> |
2305 | + </element> |
2306 | + </choice> |
2307 | </element> |
2308 | </optional> |
2309 | <optional> |
2310 | @@ -2547,6 +2557,644 @@ |
2311 | </optional> |
2312 | </element> |
2313 | </start> |
2314 | + <define name="population_balance"> |
2315 | + <element name="population_balance"> |
2316 | + <a:documentation/> |
2317 | + <choice> |
2318 | + <element name="calculate_initial_conditions_from_moments"> |
2319 | + <a:documentation>Determine initial weighted_abscissa and weights using the PD algorithm and the |
2320 | +initial conditions set in the diagnostic moment fields. |
2321 | + |
2322 | +In this case it does not matter what is set in the weighted_abscissa and weights |
2323 | +fields initial conditions option</a:documentation> |
2324 | + <empty/> |
2325 | + </element> |
2326 | + <element name="use_prognostic_field_initial_conditions"> |
2327 | + <a:documentation>Use initial conditions set in the weighted_abscissa and weights prognostic |
2328 | +fields |
2329 | + |
2330 | +In this case it does not matter what is set in the moment field initial conditions |
2331 | +options</a:documentation> |
2332 | + <empty/> |
2333 | + </element> |
2334 | + </choice> |
2335 | + <attribute name="name"> |
2336 | + <data type="string"/> |
2337 | + </attribute> |
2338 | + <element name="abscissa"> |
2339 | + <element name="scalar_field"> |
2340 | + <attribute name="rank"> |
2341 | + <value>0</value> |
2342 | + </attribute> |
2343 | + <attribute name="name"> |
2344 | + <value>Abscissa_0</value> |
2345 | + </attribute> |
2346 | + <element name="diagnostic"> |
2347 | + <a:documentation>Field type</a:documentation> |
2348 | + <ref name="internal_algorithm"/> |
2349 | + <ref name="velocity_mesh_choice"/> |
2350 | + <ref name="diagnostic_scalar_field"/> |
2351 | + </element> |
2352 | + </element> |
2353 | + <element name="scalar_field"> |
2354 | + <attribute name="rank"> |
2355 | + <value>0</value> |
2356 | + </attribute> |
2357 | + <attribute name="name"> |
2358 | + <value>Abscissa_1</value> |
2359 | + </attribute> |
2360 | + <element name="diagnostic"> |
2361 | + <a:documentation>Field type</a:documentation> |
2362 | + <ref name="internal_algorithm"/> |
2363 | + <ref name="velocity_mesh_choice"/> |
2364 | + <ref name="diagnostic_scalar_field"/> |
2365 | + </element> |
2366 | + </element> |
2367 | + <zeroOrMore> |
2368 | + <element name="scalar_field"> |
2369 | + <attribute name="rank"> |
2370 | + <value>0</value> |
2371 | + </attribute> |
2372 | + <attribute name="name"> |
2373 | + <data type="string"/> |
2374 | + </attribute> |
2375 | + <element name="diagnostic"> |
2376 | + <a:documentation>Field type</a:documentation> |
2377 | + <ref name="internal_algorithm"/> |
2378 | + <ref name="velocity_mesh_choice"/> |
2379 | + <ref name="diagnostic_scalar_field"/> |
2380 | + </element> |
2381 | + </element> |
2382 | + </zeroOrMore> |
2383 | + </element> |
2384 | + <element name="weights"> |
2385 | + <element name="scalar_field"> |
2386 | + <attribute name="rank"> |
2387 | + <value>0</value> |
2388 | + </attribute> |
2389 | + <attribute name="name"> |
2390 | + <value>Weight_0</value> |
2391 | + </attribute> |
2392 | + <element name="prognostic"> |
2393 | + <a:documentation>Field type</a:documentation> |
2394 | + <ref name="velocity_mesh_choice"/> |
2395 | + <ref name="prognostic_scalar_field"/> |
2396 | + </element> |
2397 | + </element> |
2398 | + <element name="scalar_field"> |
2399 | + <attribute name="rank"> |
2400 | + <value>0</value> |
2401 | + </attribute> |
2402 | + <attribute name="name"> |
2403 | + <value>Weight_1</value> |
2404 | + </attribute> |
2405 | + <element name="prognostic"> |
2406 | + <a:documentation>Field type</a:documentation> |
2407 | + <ref name="velocity_mesh_choice"/> |
2408 | + <ref name="prognostic_scalar_field"/> |
2409 | + </element> |
2410 | + </element> |
2411 | + <zeroOrMore> |
2412 | + <element name="scalar_field"> |
2413 | + <attribute name="rank"> |
2414 | + <value>0</value> |
2415 | + </attribute> |
2416 | + <attribute name="name"> |
2417 | + <data type="string"/> |
2418 | + </attribute> |
2419 | + <element name="prognostic"> |
2420 | + <a:documentation>Field type</a:documentation> |
2421 | + <ref name="velocity_mesh_choice"/> |
2422 | + <ref name="prognostic_scalar_field"/> |
2423 | + </element> |
2424 | + </element> |
2425 | + </zeroOrMore> |
2426 | + </element> |
2427 | + <element name="weighted_abscissa"> |
2428 | + <element name="scalar_field"> |
2429 | + <attribute name="rank"> |
2430 | + <value>0</value> |
2431 | + </attribute> |
2432 | + <attribute name="name"> |
2433 | + <value>WeightedAbscissa_0</value> |
2434 | + </attribute> |
2435 | + <element name="prognostic"> |
2436 | + <a:documentation>Field type</a:documentation> |
2437 | + <ref name="velocity_mesh_choice"/> |
2438 | + <ref name="prognostic_scalar_field"/> |
2439 | + </element> |
2440 | + </element> |
2441 | + <element name="scalar_field"> |
2442 | + <attribute name="rank"> |
2443 | + <value>0</value> |
2444 | + </attribute> |
2445 | + <attribute name="name"> |
2446 | + <value>WeightedAbscissa_1</value> |
2447 | + </attribute> |
2448 | + <element name="prognostic"> |
2449 | + <a:documentation>Field type</a:documentation> |
2450 | + <ref name="velocity_mesh_choice"/> |
2451 | + <ref name="prognostic_scalar_field"/> |
2452 | + </element> |
2453 | + </element> |
2454 | + <zeroOrMore> |
2455 | + <element name="scalar_field"> |
2456 | + <attribute name="rank"> |
2457 | + <value>0</value> |
2458 | + </attribute> |
2459 | + <attribute name="name"> |
2460 | + <data type="string"/> |
2461 | + </attribute> |
2462 | + <element name="prognostic"> |
2463 | + <a:documentation>Field type</a:documentation> |
2464 | + <ref name="velocity_mesh_choice"/> |
2465 | + <ref name="prognostic_scalar_field"/> |
2466 | + </element> |
2467 | + </element> |
2468 | + </zeroOrMore> |
2469 | + </element> |
2470 | + <element name="adv_diff_source_term_interpolation"> |
2471 | + <a:documentation>This option only works if you are using a continuous mesh for the population balance scalar fields. |
2472 | +A DG mesh will use inverse mass calculated at element level. |
2473 | +In the population balance DQMOM algorithm all sources for the |
2474 | +advection-diffusion equations are calculated at the quadrature points first |
2475 | +and then interpolated back to the nodal points. |
2476 | +For a continuous mesh, this interpolation is made by inverting the mass matrix. |
2477 | +Mass lumping is fairly quick and can be used with 1st order continuous meshes. |
2478 | +But the error is high for higher order continuous meshes and full mass matrix should be used.</a:documentation> |
2479 | + <choice> |
2480 | + <element name="use_mass_lumping"> |
2481 | + <a:documentation>The mass matrix is lumped to obtain source fields at nodal points.</a:documentation> |
2482 | + <empty/> |
2483 | + </element> |
2484 | + <element name="use_full_mass_matrix"> |
2485 | + <a:documentation>Full mass marix is used and the linear system is solved iteratively to obtain source fields at nodal points.</a:documentation> |
2486 | + <element name="solver"> |
2487 | + <a:documentation>This block specifies the solver options for solving the linear system to interpolate advection-diffusion source terms at nodal points.</a:documentation> |
2488 | + <ref name="linear_solver_options_asym_scalar"/> |
2489 | + </element> |
2490 | + </element> |
2491 | + </choice> |
2492 | + </element> |
2493 | + <element name="moments"> |
2494 | + <element name="scalar_field"> |
2495 | + <attribute name="rank"> |
2496 | + <value>0</value> |
2497 | + </attribute> |
2498 | + <attribute name="name"> |
2499 | + <value>Moment_0</value> |
2500 | + </attribute> |
2501 | + <element name="diagnostic"> |
2502 | + <ref name="internal_algorithm"/> |
2503 | + <ref name="velocity_mesh_choice"/> |
2504 | + <oneOrMore> |
2505 | + <choice> |
2506 | + <element name="initial_condition"> |
2507 | + <a:documentation>Initial condition for WholeMesh |
2508 | + |
2509 | +Only specify one condition if not using mesh regions. |
2510 | +Otherwise select other initial_condition option, specify region_ids |
2511 | +and distinct names. Then add extra intial conditions for other regions.</a:documentation> |
2512 | + <attribute name="name"> |
2513 | + <value>WholeMesh</value> |
2514 | + </attribute> |
2515 | + <ref name="input_choice_initial_condition_real"/> |
2516 | + </element> |
2517 | + <element name="initial_condition"> |
2518 | + <a:documentation>Multiple initial_conditions are allowed if specifying |
2519 | +different values in different |
2520 | +regions of the mesh (defined by region_ids). In this case |
2521 | +each initial_condition |
2522 | +requires a distinct name for the options dictionary.</a:documentation> |
2523 | + <attribute name="name"> |
2524 | + <data type="string" datatypeLibrary=""/> |
2525 | + </attribute> |
2526 | + <optional> |
2527 | + <ref name="region_ids"/> |
2528 | + </optional> |
2529 | + <ref name="input_choice_initial_condition_real"/> |
2530 | + </element> |
2531 | + </choice> |
2532 | + </oneOrMore> |
2533 | + <ref name="diagnostic_scalar_field"/> |
2534 | + </element> |
2535 | + </element> |
2536 | + <element name="scalar_field"> |
2537 | + <attribute name="rank"> |
2538 | + <value>0</value> |
2539 | + </attribute> |
2540 | + <attribute name="name"> |
2541 | + <value>Moment_1</value> |
2542 | + </attribute> |
2543 | + <element name="diagnostic"> |
2544 | + <ref name="internal_algorithm"/> |
2545 | + <ref name="velocity_mesh_choice"/> |
2546 | + <oneOrMore> |
2547 | + <choice> |
2548 | + <element name="initial_condition"> |
2549 | + <a:documentation>Initial condition for WholeMesh |
2550 | + |
2551 | +Only specify one condition if not using mesh regions. |
2552 | +Otherwise select other initial_condition option, specify region_ids |
2553 | +and distinct names. Then add extra intial conditions for other regions.</a:documentation> |
2554 | + <attribute name="name"> |
2555 | + <value>WholeMesh</value> |
2556 | + </attribute> |
2557 | + <ref name="input_choice_initial_condition_real"/> |
2558 | + </element> |
2559 | + <element name="initial_condition"> |
2560 | + <a:documentation>Multiple initial_conditions are allowed if specifying |
2561 | +different values in different |
2562 | +regions of the mesh (defined by region_ids). In this case |
2563 | +each initial_condition |
2564 | +requires a distinct name for the options dictionary.</a:documentation> |
2565 | + <attribute name="name"> |
2566 | + <data type="string" datatypeLibrary=""/> |
2567 | + </attribute> |
2568 | + <optional> |
2569 | + <ref name="region_ids"/> |
2570 | + </optional> |
2571 | + <ref name="input_choice_initial_condition_real"/> |
2572 | + </element> |
2573 | + </choice> |
2574 | + </oneOrMore> |
2575 | + <ref name="diagnostic_scalar_field"/> |
2576 | + </element> |
2577 | + </element> |
2578 | + <element name="scalar_field"> |
2579 | + <attribute name="rank"> |
2580 | + <value>0</value> |
2581 | + </attribute> |
2582 | + <attribute name="name"> |
2583 | + <value>Moment_2</value> |
2584 | + </attribute> |
2585 | + <element name="diagnostic"> |
2586 | + <ref name="internal_algorithm"/> |
2587 | + <ref name="velocity_mesh_choice"/> |
2588 | + <oneOrMore> |
2589 | + <choice> |
2590 | + <element name="initial_condition"> |
2591 | + <a:documentation>Initial condition for WholeMesh |
2592 | + |
2593 | +Only specify one condition if not using mesh regions. |
2594 | +Otherwise select other initial_condition option, specify region_ids |
2595 | +and distinct names. Then add extra intial conditions for other regions.</a:documentation> |
2596 | + <attribute name="name"> |
2597 | + <value>WholeMesh</value> |
2598 | + </attribute> |
2599 | + <ref name="input_choice_initial_condition_real"/> |
2600 | + </element> |
2601 | + <element name="initial_condition"> |
2602 | + <a:documentation>Multiple initial_conditions are allowed if specifying |
2603 | +different values in different |
2604 | +regions of the mesh (defined by region_ids). In this case |
2605 | +each initial_condition |
2606 | +requires a distinct name for the options dictionary.</a:documentation> |
2607 | + <attribute name="name"> |
2608 | + <data type="string" datatypeLibrary=""/> |
2609 | + </attribute> |
2610 | + <optional> |
2611 | + <ref name="region_ids"/> |
2612 | + </optional> |
2613 | + <ref name="input_choice_initial_condition_real"/> |
2614 | + </element> |
2615 | + </choice> |
2616 | + </oneOrMore> |
2617 | + <ref name="diagnostic_scalar_field"/> |
2618 | + </element> |
2619 | + </element> |
2620 | + <element name="scalar_field"> |
2621 | + <attribute name="rank"> |
2622 | + <value>0</value> |
2623 | + </attribute> |
2624 | + <attribute name="name"> |
2625 | + <value>Moment_3</value> |
2626 | + </attribute> |
2627 | + <element name="diagnostic"> |
2628 | + <ref name="internal_algorithm"/> |
2629 | + <ref name="velocity_mesh_choice"/> |
2630 | + <oneOrMore> |
2631 | + <choice> |
2632 | + <element name="initial_condition"> |
2633 | + <a:documentation>Initial condition for WholeMesh |
2634 | + |
2635 | +Only specify one condition if not using mesh regions. |
2636 | +Otherwise select other initial_condition option, specify region_ids |
2637 | +and distinct names. Then add extra intial conditions for other regions.</a:documentation> |
2638 | + <attribute name="name"> |
2639 | + <value>WholeMesh</value> |
2640 | + </attribute> |
2641 | + <ref name="input_choice_initial_condition_real"/> |
2642 | + </element> |
2643 | + <element name="initial_condition"> |
2644 | + <a:documentation>Multiple initial_conditions are allowed if specifying |
2645 | +different values in different |
2646 | +regions of the mesh (defined by region_ids). In this case |
2647 | +each initial_condition |
2648 | +requires a distinct name for the options dictionary.</a:documentation> |
2649 | + <attribute name="name"> |
2650 | + <data type="string" datatypeLibrary=""/> |
2651 | + </attribute> |
2652 | + <optional> |
2653 | + <ref name="region_ids"/> |
2654 | + </optional> |
2655 | + <ref name="input_choice_initial_condition_real"/> |
2656 | + </element> |
2657 | + </choice> |
2658 | + </oneOrMore> |
2659 | + <ref name="diagnostic_scalar_field"/> |
2660 | + </element> |
2661 | + </element> |
2662 | + <zeroOrMore> |
2663 | + <element name="scalar_field"> |
2664 | + <attribute name="rank"> |
2665 | + <value>0</value> |
2666 | + </attribute> |
2667 | + <attribute name="name"> |
2668 | + <data type="string"/> |
2669 | + </attribute> |
2670 | + <element name="diagnostic"> |
2671 | + <ref name="internal_algorithm"/> |
2672 | + <ref name="velocity_mesh_choice"/> |
2673 | + <oneOrMore> |
2674 | + <choice> |
2675 | + <element name="initial_condition"> |
2676 | + <a:documentation>Initial condition for WholeMesh |
2677 | + |
2678 | +Only specify one condition if not using mesh regions. |
2679 | +Otherwise select other initial_condition option, specify region_ids |
2680 | +and distinct names. Then add extra intial conditions for other regions.</a:documentation> |
2681 | + <attribute name="name"> |
2682 | + <value>WholeMesh</value> |
2683 | + </attribute> |
2684 | + <ref name="input_choice_initial_condition_real"/> |
2685 | + </element> |
2686 | + <element name="initial_condition"> |
2687 | + <a:documentation>Multiple initial_conditions are allowed if specifying |
2688 | +different values in different |
2689 | +regions of the mesh (defined by region_ids). In this case |
2690 | +each initial_condition |
2691 | +requires a distinct name for the options dictionary.</a:documentation> |
2692 | + <attribute name="name"> |
2693 | + <data type="string" datatypeLibrary=""/> |
2694 | + </attribute> |
2695 | + <optional> |
2696 | + <ref name="region_ids"/> |
2697 | + </optional> |
2698 | + <ref name="input_choice_initial_condition_real"/> |
2699 | + </element> |
2700 | + </choice> |
2701 | + </oneOrMore> |
2702 | + <ref name="diagnostic_scalar_field"/> |
2703 | + </element> |
2704 | + </element> |
2705 | + </zeroOrMore> |
2706 | + </element> |
2707 | + <element name="statistics"> |
2708 | + <optional> |
2709 | + <element name="scalar_field"> |
2710 | + <attribute name="rank"> |
2711 | + <value>0</value> |
2712 | + </attribute> |
2713 | + <attribute name="name"> |
2714 | + <value>Mean</value> |
2715 | + </attribute> |
2716 | + <element name="diagnostic"> |
2717 | + <a:documentation>Field type</a:documentation> |
2718 | + <ref name="internal_algorithm"/> |
2719 | + <ref name="velocity_mesh_choice"/> |
2720 | + <ref name="diagnostic_scalar_field"/> |
2721 | + </element> |
2722 | + </element> |
2723 | + </optional> |
2724 | + <optional> |
2725 | + <element name="scalar_field"> |
2726 | + <attribute name="rank"> |
2727 | + <value>0</value> |
2728 | + </attribute> |
2729 | + <attribute name="name"> |
2730 | + <value>StandardDeviation</value> |
2731 | + </attribute> |
2732 | + <element name="diagnostic"> |
2733 | + <a:documentation>Field type</a:documentation> |
2734 | + <ref name="internal_algorithm"/> |
2735 | + <ref name="velocity_mesh_choice"/> |
2736 | + <ref name="diagnostic_scalar_field"/> |
2737 | + </element> |
2738 | + </element> |
2739 | + </optional> |
2740 | + <optional> |
2741 | + <element name="scalar_field"> |
2742 | + <attribute name="rank"> |
2743 | + <value>0</value> |
2744 | + </attribute> |
2745 | + <attribute name="name"> |
2746 | + <value>Skew</value> |
2747 | + </attribute> |
2748 | + <element name="diagnostic"> |
2749 | + <a:documentation>Field type</a:documentation> |
2750 | + <ref name="internal_algorithm"/> |
2751 | + <ref name="velocity_mesh_choice"/> |
2752 | + <ref name="diagnostic_scalar_field"/> |
2753 | + </element> |
2754 | + </element> |
2755 | + </optional> |
2756 | + <optional> |
2757 | + <element name="scalar_field"> |
2758 | + <attribute name="rank"> |
2759 | + <value>0</value> |
2760 | + </attribute> |
2761 | + <attribute name="name"> |
2762 | + <value>SauterMeanDia</value> |
2763 | + </attribute> |
2764 | + <element name="diagnostic"> |
2765 | + <a:documentation>Field type</a:documentation> |
2766 | + <ref name="internal_algorithm"/> |
2767 | + <ref name="velocity_mesh_choice"/> |
2768 | + <ref name="diagnostic_scalar_field"/> |
2769 | + </element> |
2770 | + </element> |
2771 | + </optional> |
2772 | + <optional> |
2773 | + <element name="scalar_field"> |
2774 | + <attribute name="rank"> |
2775 | + <value>0</value> |
2776 | + </attribute> |
2777 | + <attribute name="name"> |
2778 | + <value>MeanDia10</value> |
2779 | + </attribute> |
2780 | + <element name="diagnostic"> |
2781 | + <a:documentation>Field type</a:documentation> |
2782 | + <ref name="internal_algorithm"/> |
2783 | + <ref name="velocity_mesh_choice"/> |
2784 | + <ref name="diagnostic_scalar_field"/> |
2785 | + </element> |
2786 | + </element> |
2787 | + </optional> |
2788 | + </element> |
2789 | + <element name="population_balance_source_terms"> |
2790 | + <a:documentation>Source terms for the population balance equation like growth, |
2791 | +breakage, aggegation and internal dispersion</a:documentation> |
2792 | + <optional> |
2793 | + <element name="growth"> |
2794 | + <a:documentation>Growth term in the internal coordinate space</a:documentation> |
2795 | + <element name="power_law_growth"> |
2796 | + <a:documentation>Enter the growth degree (r) for the power-law growth G(\xi)=\xi^{r}</a:documentation> |
2797 | + <ref name="real"/> |
2798 | + </element> |
2799 | + </element> |
2800 | + </optional> |
2801 | + <optional> |
2802 | + <element name="internal_dispersion"> |
2803 | + <a:documentation>Dispersion coefficient D. Currently it only works for constant dispersion and can't handle dispersion varying with internal coordinate</a:documentation> |
2804 | + <ref name="real"/> |
2805 | + </element> |
2806 | + </optional> |
2807 | + <optional> |
2808 | + <element name="aggregation"> |
2809 | + <a:documentation/> |
2810 | + <element name="aggregation_frequency"> |
2811 | + <a:documentation/> |
2812 | + <choice> |
2813 | + <element name="constant_aggregation"> |
2814 | + <a:documentation/> |
2815 | + <ref name="real"/> |
2816 | + </element> |
2817 | + <element name="hydrodynamic_aggregation"> |
2818 | + <a:documentation>aggregation frequency is given by \beta_{alpha gamma} = \xi_{alpha}^3 + \xi_{gamma}^3</a:documentation> |
2819 | + <empty/> |
2820 | + </element> |
2821 | + <element name="sum_aggregation"> |
2822 | + <a:documentation>aggregation frequency is given by \beta_{alpha gamma} = \beta_o (\xi_{alpha} + \xi_{gamma})</a:documentation> |
2823 | + <ref name="real"/> |
2824 | + </element> |
2825 | + </choice> |
2826 | + </element> |
2827 | + </element> |
2828 | + </optional> |
2829 | + <optional> |
2830 | + <element name="breakage"> |
2831 | + <a:documentation/> |
2832 | + <element name="breakage_frequency"> |
2833 | + <a:documentation/> |
2834 | + <choice> |
2835 | + <element name="constant_breakage"> |
2836 | + <a:documentation/> |
2837 | + <ref name="real"/> |
2838 | + </element> |
2839 | + <element name="power_law_breakage"> |
2840 | + <a:documentation>breakage frequency is given by a_{alpha} = p * \xi_{alpha}^r</a:documentation> |
2841 | + <element name="coefficient"> |
2842 | + <a:documentation>coefficient p in breakage frequency a_{alpha} = p * \xi_{alpha}^r</a:documentation> |
2843 | + <ref name="real"/> |
2844 | + </element> |
2845 | + <element name="degree"> |
2846 | + <a:documentation>degree r in breakage frequency a_{alpha} = p * \xi_{alpha}^r</a:documentation> |
2847 | + <ref name="real"/> |
2848 | + </element> |
2849 | + </element> |
2850 | + </choice> |
2851 | + </element> |
2852 | + <element name="distribution_function"> |
2853 | + <choice> |
2854 | + <element name="symmetric_fragmentation"> |
2855 | + <a:documentation/> |
2856 | + <empty/> |
2857 | + </element> |
2858 | + <element name="mcCoy_madras_2003"> |
2859 | + <a:documentation>McCoy and Madras (2003) used P(v|v') = 2/v' for v<v' and 0 otherwise, where v stands for volume. |
2860 | +When written in terms of particle diameter, this converts to P(x|x')=(6x^2)/x'^3 for x<x' and 0 otherwise.</a:documentation> |
2861 | + <empty/> |
2862 | + </element> |
2863 | + </choice> |
2864 | + </element> |
2865 | + </element> |
2866 | + </optional> |
2867 | + </element> |
2868 | + <element name="ill_conditioned_matrices"> |
2869 | + <a:documentation>At each vertex a linear system is solved to determine source terms |
2870 | +for the abscissa and weight transport equations. This requires inversion |
2871 | +of a matrix that has terms that are a function of the weighted abscissa. |
2872 | +If any two abscissa happen to lie very close to one another this can cause |
2873 | +this matrix to be ill-conditioned which can cause large errors or solver |
2874 | +failures when attempting to invert the matrix. There several options for |
2875 | +evading this problem: |
2876 | + |
2877 | +(a) Set the abscissa and weight source terms to zero at the offending vertex. |
2878 | +(b) Perturbate the weighted absciss used to construct the matrix until the |
2879 | +matrix is no longer ill conditioned and can be inverted. |
2880 | +(c) Use the source terms of neighbouring cells (not implemented)</a:documentation> |
2881 | + <element name="required_condition_number"> |
2882 | + <a:documentation>The required condition number of the matrix. Recommended value of 1e-12</a:documentation> |
2883 | + <ref name="real"/> |
2884 | + </element> |
2885 | + <choice> |
2886 | + <element name="set_source_to_zero"> |
2887 | + <a:documentation>This is a better option when much of the domain has a minimum 0'th moment</a:documentation> |
2888 | + <empty/> |
2889 | + </element> |
2890 | + <element name="perturbate"> |
2891 | + <element name="perturbation"> |
2892 | + <a:documentation>The amount to perturbate the weighted abscissa. The values are |
2893 | +iteratively perturbated by rand(-1,1)*perturbation until the matrix |
2894 | +exceeds the required condition number. Too low a value can cause |
2895 | +very long run times but a higher value will lead to larger errors. |
2896 | +After every ten perturbations at any one grid location a message is |
2897 | +printed to the log file noting the difficulties in solving the linear |
2898 | +system. |
2899 | +Recommended value of 1e-7</a:documentation> |
2900 | + <ref name="real"/> |
2901 | + </element> |
2902 | + </element> |
2903 | + <element name="do_nothing"> |
2904 | + <a:documentation>Do not check for ill-conditioning of matrix A</a:documentation> |
2905 | + <empty/> |
2906 | + </element> |
2907 | + </choice> |
2908 | + </element> |
2909 | + <element name="minimum_weight"> |
2910 | + <a:documentation>weights of zero can cause instabilities. It is recommended that a minimum |
2911 | +weight of approx 1e-10 is used.</a:documentation> |
2912 | + <ref name="real"/> |
2913 | + </element> |
2914 | + <optional> |
2915 | + <element name="scaling_factor_Dia"> |
2916 | + <a:documentation>Scaling factor to be used for the Sauter Mean Diameter / Mean Diameter calculated in the |
2917 | +statistics. It is useful in a non-dimensional implementation of the PBE.</a:documentation> |
2918 | + <ref name="real"/> |
2919 | + </element> |
2920 | + </optional> |
2921 | + <optional> |
2922 | + <element name="submerged_specific_gravity"> |
2923 | + <a:documentation>This is the submerged specific gravity, R, of this population balance |
2924 | +as a function of internal coordinate, Z. |
2925 | +It will be used in the equation of state. |
2926 | + |
2927 | +R(Z) = (rho_c(Z) - rho_a)/(rho_a) |
2928 | + |
2929 | +Where: rho_c(Z) is the density of the dispersed phase and rho_a is |
2930 | +the ambient fluid density |
2931 | + |
2932 | +Must be given as a python function in the form: |
2933 | + |
2934 | + def R(Z): |
2935 | + # Function code |
2936 | + return # Return value of R</a:documentation> |
2937 | + <ref name="python_code"/> |
2938 | + </element> |
2939 | + </optional> |
2940 | + <optional> |
2941 | + <element name="output_abscissa_and_weights"> |
2942 | + <empty/> |
2943 | + </element> |
2944 | + </optional> |
2945 | + <optional> |
2946 | + <element name="output_sources"> |
2947 | + <empty/> |
2948 | + </element> |
2949 | + </optional> |
2950 | + </element> |
2951 | + </define> |
2952 | <define name="sediment"> |
2953 | <element name="sediment"> |
2954 | <a:documentation>A sediment model. See the manual for details on how to use this model.</a:documentation> |
2955 | |
2956 | === modified file 'schemas/multiphase_interaction.rnc' |
2957 | --- schemas/multiphase_interaction.rnc 2012-06-15 19:32:03 +0000 |
2958 | +++ schemas/multiphase_interaction.rnc 2013-12-12 22:35:40 +0000 |
2959 | @@ -35,6 +35,11 @@ |
2960 | element drag_correlation { |
2961 | attribute name { "ergun" }, |
2962 | comment |
2963 | + }| |
2964 | + ## Fluid-particle drag term by Schiller-Naumann (1933). |
2965 | + element drag_correlation { |
2966 | + attribute name { "schiller_naumann" }, |
2967 | + comment |
2968 | } |
2969 | ) |
2970 | |
2971 | @@ -55,4 +60,4 @@ |
2972 | attribute name { "gunn" }, |
2973 | comment |
2974 | } |
2975 | - ) |
2976 | \ No newline at end of file |
2977 | + ) |
2978 | |
2979 | === modified file 'schemas/multiphase_interaction.rng' |
2980 | --- schemas/multiphase_interaction.rng 2012-06-15 19:32:03 +0000 |
2981 | +++ schemas/multiphase_interaction.rng 2013-12-12 22:35:40 +0000 |
2982 | @@ -43,6 +43,13 @@ |
2983 | </attribute> |
2984 | <ref name="comment"/> |
2985 | </element> |
2986 | + <element name="drag_correlation"> |
2987 | + <a:documentation>Fluid-particle drag term by Schiller-Naumann (1933).</a:documentation> |
2988 | + <attribute name="name"> |
2989 | + <value>schiller_naumann</value> |
2990 | + </attribute> |
2991 | + <ref name="comment"/> |
2992 | + </element> |
2993 | </choice> |
2994 | </define> |
2995 | <define name="heat_transfer"> |
2996 | |
2997 | === modified file 'tests/mphase_dusty_gas_shock_tube/mphase_dusty_gas_shock_tube.flml' |
2998 | --- tests/mphase_dusty_gas_shock_tube/mphase_dusty_gas_shock_tube.flml 2013-10-28 06:46:48 +0000 |
2999 | +++ tests/mphase_dusty_gas_shock_tube/mphase_dusty_gas_shock_tube.flml 2013-12-12 22:35:40 +0000 |
3000 | @@ -624,7 +624,9 @@ |
3001 | <string_value lines="1">Dust::Velocity,Air::Velocity,Air::PhaseVolumeFraction,Air::Density</string_value> |
3002 | </depends> |
3003 | <particle_diameter> |
3004 | - <real_value rank="0">10e-6</real_value> |
3005 | + <constant> |
3006 | + <real_value rank="0">10e-6</real_value> |
3007 | + </constant> |
3008 | </particle_diameter> |
3009 | <continuous_phase_name>Air</continuous_phase_name> |
3010 | </algorithm> |
3011 | @@ -726,7 +728,9 @@ |
3012 | </scalar_field> |
3013 | <multiphase_properties> |
3014 | <particle_diameter> |
3015 | - <real_value rank="0">10e-6</real_value> |
3016 | + <constant> |
3017 | + <real_value rank="0">10e-6</real_value> |
3018 | + </constant> |
3019 | </particle_diameter> |
3020 | <specific_heat> |
3021 | <real_value rank="0">758</real_value> |
3022 | |
3023 | === modified file 'tests/mphase_inlet_velocity_bc_compressible/mphase_inlet_velocity_bc_compressible.flml' |
3024 | --- tests/mphase_inlet_velocity_bc_compressible/mphase_inlet_velocity_bc_compressible.flml 2013-10-28 06:46:48 +0000 |
3025 | +++ tests/mphase_inlet_velocity_bc_compressible/mphase_inlet_velocity_bc_compressible.flml 2013-12-12 22:35:40 +0000 |
3026 | @@ -845,7 +845,9 @@ |
3027 | </scalar_field> |
3028 | <multiphase_properties> |
3029 | <particle_diameter> |
3030 | - <real_value rank="0">2e-4</real_value> |
3031 | + <constant> |
3032 | + <real_value rank="0">2e-4</real_value> |
3033 | + </constant> |
3034 | </particle_diameter> |
3035 | <specific_heat> |
3036 | <real_value rank="0">954</real_value> |
3037 | |
3038 | === modified file 'tests/mphase_rogue_shock_tube_dense_bed_glass/mphase_rogue_shock_tube_dense_bed_glass.flml' |
3039 | --- tests/mphase_rogue_shock_tube_dense_bed_glass/mphase_rogue_shock_tube_dense_bed_glass.flml 2013-10-28 06:46:48 +0000 |
3040 | +++ tests/mphase_rogue_shock_tube_dense_bed_glass/mphase_rogue_shock_tube_dense_bed_glass.flml 2013-12-12 22:35:40 +0000 |
3041 | @@ -842,7 +842,9 @@ |
3042 | </scalar_field> |
3043 | <multiphase_properties> |
3044 | <particle_diameter> |
3045 | - <real_value rank="0">1.5e-3</real_value> |
3046 | + <constant> |
3047 | + <real_value rank="0">1.5e-3</real_value> |
3048 | + </constant> |
3049 | </particle_diameter> |
3050 | <specific_heat> |
3051 | <real_value rank="0">758</real_value> |
3052 | |
3053 | === modified file 'tests/mphase_rogue_shock_tube_dense_bed_nylon/mphase_rogue_shock_tube_dense_bed_nylon.flml' |
3054 | --- tests/mphase_rogue_shock_tube_dense_bed_nylon/mphase_rogue_shock_tube_dense_bed_nylon.flml 2013-10-28 06:46:48 +0000 |
3055 | +++ tests/mphase_rogue_shock_tube_dense_bed_nylon/mphase_rogue_shock_tube_dense_bed_nylon.flml 2013-12-12 22:35:40 +0000 |
3056 | @@ -842,7 +842,9 @@ |
3057 | </scalar_field> |
3058 | <multiphase_properties> |
3059 | <particle_diameter> |
3060 | - <real_value rank="0">2.0e-3</real_value> |
3061 | + <constant> |
3062 | + <real_value rank="0">2.0e-3</real_value> |
3063 | + </constant> |
3064 | </particle_diameter> |
3065 | <specific_heat> |
3066 | <real_value rank="0">758</real_value> |
3067 | |
3068 | === modified file 'tests/mphase_stokes_law/mphase_stokes_law.flml' |
3069 | --- tests/mphase_stokes_law/mphase_stokes_law.flml 2012-05-19 22:54:15 +0000 |
3070 | +++ tests/mphase_stokes_law/mphase_stokes_law.flml 2013-12-12 22:35:40 +0000 |
3071 | @@ -502,7 +502,9 @@ |
3072 | <string_value lines="1">Water::Velocity,Tephra::Velocity,Water::Density</string_value> |
3073 | </depends> |
3074 | <particle_diameter> |
3075 | - <real_value rank="0">48e-6</real_value> |
3076 | + <constant> |
3077 | + <real_value rank="0">48e-6</real_value> |
3078 | + </constant> |
3079 | </particle_diameter> |
3080 | <continuous_phase_name>Water</continuous_phase_name> |
3081 | </algorithm> |
3082 | @@ -676,7 +678,9 @@ |
3083 | </vector_field> |
3084 | <multiphase_properties> |
3085 | <particle_diameter> |
3086 | - <real_value rank="0">48e-6</real_value> |
3087 | + <constant> |
3088 | + <real_value rank="0">48e-6</real_value> |
3089 | + </constant> |
3090 | </particle_diameter> |
3091 | </multiphase_properties> |
3092 | </material_phase> |
3093 | |
3094 | === modified file 'tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p0p1.flml' |
3095 | --- tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p0p1.flml 2013-10-28 06:46:48 +0000 |
3096 | +++ tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p0p1.flml 2013-12-12 22:35:40 +0000 |
3097 | @@ -725,7 +725,9 @@ |
3098 | </scalar_field> |
3099 | <multiphase_properties> |
3100 | <particle_diameter> |
3101 | - <real_value rank="0">2e-4</real_value> |
3102 | + <constant> |
3103 | + <real_value rank="0">2.0e-4</real_value> |
3104 | + </constant> |
3105 | </particle_diameter> |
3106 | <specific_heat> |
3107 | <real_value rank="0">954</real_value> |
3108 | |
3109 | === modified file 'tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p2p1.flml' |
3110 | --- tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p2p1.flml 2013-10-28 06:46:48 +0000 |
3111 | +++ tests/mphase_strong_pressure_bc_compressible/mphase_strong_pressure_bc_compressible_p2p1.flml 2013-12-12 22:35:40 +0000 |
3112 | @@ -732,7 +732,9 @@ |
3113 | </scalar_field> |
3114 | <multiphase_properties> |
3115 | <particle_diameter> |
3116 | - <real_value rank="0">2e-4</real_value> |
3117 | + <constant> |
3118 | + <real_value rank="0">2.0e-4</real_value> |
3119 | + </constant> |
3120 | </particle_diameter> |
3121 | <specific_heat> |
3122 | <real_value rank="0">954</real_value> |
3123 | |
3124 | === modified file 'tests/mphase_subtract_out_reference_profile/mphase_subtract_out_reference_profile_1d.flml' |
3125 | --- tests/mphase_subtract_out_reference_profile/mphase_subtract_out_reference_profile_1d.flml 2013-10-28 06:46:48 +0000 |
3126 | +++ tests/mphase_subtract_out_reference_profile/mphase_subtract_out_reference_profile_1d.flml 2013-12-12 22:35:40 +0000 |
3127 | @@ -811,7 +811,9 @@ |
3128 | </scalar_field> |
3129 | <multiphase_properties> |
3130 | <particle_diameter> |
3131 | - <real_value rank="0">2e-4</real_value> |
3132 | + <constant> |
3133 | + <real_value rank="0">2e-4</real_value> |
3134 | + </constant> |
3135 | </particle_diameter> |
3136 | <specific_heat> |
3137 | <real_value rank="0">954</real_value> |
3138 | |
3139 | === modified file 'tests/mphase_tephra_settling/mphase_tephra_settling.flml' |
3140 | --- tests/mphase_tephra_settling/mphase_tephra_settling.flml 2013-05-30 11:47:42 +0000 |
3141 | +++ tests/mphase_tephra_settling/mphase_tephra_settling.flml 2013-12-12 22:35:40 +0000 |
3142 | @@ -636,7 +636,9 @@ |
3143 | <string_value lines="1">Water::Density, Water::Velocity, Water::PhaseVolumeFraction, Tephra::Velocity</string_value> |
3144 | </depends> |
3145 | <particle_diameter> |
3146 | - <real_value rank="0">48e-6</real_value> |
3147 | + <constant> |
3148 | + <real_value rank="0">48e-6</real_value> |
3149 | + </constant> |
3150 | </particle_diameter> |
3151 | <continuous_phase_name>Water</continuous_phase_name> |
3152 | </algorithm> |
3153 | @@ -656,7 +658,9 @@ |
3154 | </scalar_field> |
3155 | <multiphase_properties> |
3156 | <particle_diameter> |
3157 | - <real_value rank="0">48e-6</real_value> |
3158 | + <constant> |
3159 | + <real_value rank="0">48e-6</real_value> |
3160 | + </constant> |
3161 | </particle_diameter> |
3162 | </multiphase_properties> |
3163 | </material_phase> |
3164 | |
3165 | === modified file 'tests/mphase_wen_yu_drag_correlation/mphase_wen_yu_drag_correlation.flml' |
3166 | --- tests/mphase_wen_yu_drag_correlation/mphase_wen_yu_drag_correlation.flml 2012-10-17 05:47:11 +0000 |
3167 | +++ tests/mphase_wen_yu_drag_correlation/mphase_wen_yu_drag_correlation.flml 2013-12-12 22:35:40 +0000 |
3168 | @@ -499,7 +499,9 @@ |
3169 | <string_value lines="1">Water::Velocity,Tephra::Velocity,Water::Density</string_value> |
3170 | </depends> |
3171 | <particle_diameter> |
3172 | - <real_value rank="0">1e-3</real_value> |
3173 | + <constant> |
3174 | + <real_value rank="0">1e-3</real_value> |
3175 | + </constant> |
3176 | </particle_diameter> |
3177 | <continuous_phase_name>Water</continuous_phase_name> |
3178 | </algorithm> |
3179 | @@ -781,7 +783,9 @@ |
3180 | </vector_field> |
3181 | <multiphase_properties> |
3182 | <particle_diameter> |
3183 | - <real_value rank="0">1e-3</real_value> |
3184 | + <constant> |
3185 | + <real_value rank="0">1e-3</real_value> |
3186 | + </constant> |
3187 | </particle_diameter> |
3188 | </multiphase_properties> |
3189 | </material_phase> |
3190 | |
3191 | === added directory 'tests/popbal_homog_brk_aggr' |
3192 | === added file 'tests/popbal_homog_brk_aggr/Makefile' |
3193 | --- tests/popbal_homog_brk_aggr/Makefile 1970-01-01 00:00:00 +0000 |
3194 | +++ tests/popbal_homog_brk_aggr/Makefile 2013-12-12 22:35:40 +0000 |
3195 | @@ -0,0 +1,5 @@ |
3196 | +input: clean |
3197 | + gmsh -2 src/minimal.geo -optimize -bin |
3198 | + |
3199 | +clean: |
3200 | + rm -f *.vtu *.pvtu fluidity.* *.s *.d.1 *.stat src/minimal.msh |
3201 | |
3202 | === added file 'tests/popbal_homog_brk_aggr/popbal_homog_N2.flml' |
3203 | --- tests/popbal_homog_brk_aggr/popbal_homog_N2.flml 1970-01-01 00:00:00 +0000 |
3204 | +++ tests/popbal_homog_brk_aggr/popbal_homog_N2.flml 2013-12-12 22:35:40 +0000 |
3205 | @@ -0,0 +1,723 @@ |
3206 | +<?xml version='1.0' encoding='utf-8'?> |
3207 | +<fluidity_options> |
3208 | + <simulation_name> |
3209 | + <string_value lines="1">popbal_homog_N2_brk_aggr</string_value> |
3210 | + </simulation_name> |
3211 | + <problem_type> |
3212 | + <string_value lines="1">fluids</string_value> |
3213 | + </problem_type> |
3214 | + <geometry> |
3215 | + <dimension> |
3216 | + <integer_value rank="0">2</integer_value> |
3217 | + </dimension> |
3218 | + <mesh name="CoordinateMesh"> |
3219 | + <from_file file_name="src/minimal"> |
3220 | + <format name="gmsh"/> |
3221 | + <stat> |
3222 | + <include_in_stat/> |
3223 | + </stat> |
3224 | + </from_file> |
3225 | + </mesh> |
3226 | + <mesh name="VelocityMesh"> |
3227 | + <from_mesh> |
3228 | + <mesh name="CoordinateMesh"/> |
3229 | + <stat> |
3230 | + <exclude_from_stat/> |
3231 | + </stat> |
3232 | + </from_mesh> |
3233 | + </mesh> |
3234 | + <quadrature> |
3235 | + <degree> |
3236 | + <integer_value rank="0">3</integer_value> |
3237 | + </degree> |
3238 | + </quadrature> |
3239 | + </geometry> |
3240 | + <io> |
3241 | + <dump_format> |
3242 | + <string_value>vtk</string_value> |
3243 | + </dump_format> |
3244 | + <dump_period> |
3245 | + <constant> |
3246 | + <real_value rank="0">5</real_value> |
3247 | + </constant> |
3248 | + </dump_period> |
3249 | + <output_mesh name="VelocityMesh"/> |
3250 | + <stat/> |
3251 | + </io> |
3252 | + <timestepping> |
3253 | + <current_time> |
3254 | + <real_value rank="0">0.0</real_value> |
3255 | + </current_time> |
3256 | + <timestep> |
3257 | + <real_value rank="0">0.001</real_value> |
3258 | + </timestep> |
3259 | + <finish_time> |
3260 | + <real_value rank="0">5</real_value> |
3261 | + </finish_time> |
3262 | + </timestepping> |
3263 | + <material_phase name="fluid"> |
3264 | + <vector_field name="Velocity" rank="1"> |
3265 | + <prescribed> |
3266 | + <mesh name="VelocityMesh"/> |
3267 | + <value name="WholeMesh"> |
3268 | + <constant> |
3269 | + <real_value shape="2" dim1="dim" rank="1">0 0</real_value> |
3270 | + </constant> |
3271 | + </value> |
3272 | + <output/> |
3273 | + <stat> |
3274 | + <include_in_stat/> |
3275 | + </stat> |
3276 | + <detectors> |
3277 | + <exclude_from_detectors/> |
3278 | + </detectors> |
3279 | + </prescribed> |
3280 | + </vector_field> |
3281 | + <scalar_field name="m0_anal" rank="0"> |
3282 | + <prescribed> |
3283 | + <mesh name="VelocityMesh"/> |
3284 | + <value name="WholeMesh"> |
3285 | + <python> |
3286 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3287 | + from math import tanh |
3288 | + phi_inf=10.0 |
3289 | + phi_t = phi_inf*( (1.0+phi_inf*tanh(phi_inf*(t/2.0)))/(phi_inf+tanh(phi_inf*(t/2.0))) ) |
3290 | + return phi_t</string_value> |
3291 | + </python> |
3292 | + </value> |
3293 | + <output/> |
3294 | + <stat/> |
3295 | + <detectors> |
3296 | + <exclude_from_detectors/> |
3297 | + </detectors> |
3298 | + </prescribed> |
3299 | + </scalar_field> |
3300 | + <scalar_field name="m1_anal" rank="0"> |
3301 | + <prescribed> |
3302 | + <mesh name="VelocityMesh"/> |
3303 | + <value name="WholeMesh"> |
3304 | + <python> |
3305 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3306 | + from math import tanh, gamma, pi |
3307 | + phi_inf=10.0 |
3308 | + phi_t = phi_inf*( (1.0+phi_inf*tanh(phi_inf*(t/2.0)))/(phi_inf+tanh(phi_inf*(t/2.0))) ) |
3309 | + k1 = (pi/2.)*phi_t**2 |
3310 | + k2 = (pi/6.)*phi_t |
3311 | + mom1 = (k1/(3.0*k2**(4./3.)))*gamma(4./3.) |
3312 | + return mom1</string_value> |
3313 | + </python> |
3314 | + </value> |
3315 | + <output/> |
3316 | + <stat/> |
3317 | + <detectors> |
3318 | + <exclude_from_detectors/> |
3319 | + </detectors> |
3320 | + </prescribed> |
3321 | + </scalar_field> |
3322 | + <scalar_field name="m2_anal" rank="0"> |
3323 | + <prescribed> |
3324 | + <mesh name="VelocityMesh"/> |
3325 | + <value name="WholeMesh"> |
3326 | + <python> |
3327 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3328 | + from math import tanh, gamma, pi |
3329 | + phi_inf=10.0 |
3330 | + phi_t = phi_inf*( (1.0+phi_inf*tanh(phi_inf*(t/2.0)))/(phi_inf+tanh(phi_inf*(t/2.0))) ) |
3331 | + k1 = (pi/2.)*phi_t**2 |
3332 | + k2 = (pi/6.)*phi_t |
3333 | + mom2 = (k1/(3.0*k2**(5./3.)))*gamma(5./3.) |
3334 | + return mom2</string_value> |
3335 | + </python> |
3336 | + </value> |
3337 | + <output/> |
3338 | + <stat/> |
3339 | + <detectors> |
3340 | + <exclude_from_detectors/> |
3341 | + </detectors> |
3342 | + </prescribed> |
3343 | + </scalar_field> |
3344 | + <scalar_field name="m3_anal" rank="0"> |
3345 | + <prescribed> |
3346 | + <mesh name="VelocityMesh"/> |
3347 | + <value name="WholeMesh"> |
3348 | + <python> |
3349 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3350 | + from math import tanh, gamma, pi |
3351 | + phi_inf=10.0 |
3352 | + phi_t = phi_inf*( (1.0+phi_inf*tanh(phi_inf*(t/2.0)))/(phi_inf+tanh(phi_inf*(t/2.0))) ) |
3353 | + k1 = (pi/2.)*phi_t**2 |
3354 | + k2 = (pi/6.)*phi_t |
3355 | + mom3 = k1/(3.*k2**2) |
3356 | + return mom3</string_value> |
3357 | + </python> |
3358 | + </value> |
3359 | + <output/> |
3360 | + <stat/> |
3361 | + <detectors> |
3362 | + <exclude_from_detectors/> |
3363 | + </detectors> |
3364 | + </prescribed> |
3365 | + </scalar_field> |
3366 | + <scalar_field name="diff_m0" rank="0"> |
3367 | + <diagnostic> |
3368 | + <algorithm name="scalar_python_diagnostic" material_phase_support="single"> |
3369 | + <string_value lines="20" type="code" language="python">mom0_anal=state.scalar_fields["m0_anal"] |
3370 | +mom0_dqmom=state.scalar_fields["Moment_0"] |
3371 | +for i in range(field.node_count): |
3372 | + field.set(i, abs(mom0_dqmom.node_val(i)-mom0_anal.node_val(i))/abs(mom0_anal.node_val(i)))</string_value> |
3373 | + <depends> |
3374 | + <string_value lines="1">fluid::m0_anal</string_value> |
3375 | + </depends> |
3376 | + </algorithm> |
3377 | + <mesh name="VelocityMesh"/> |
3378 | + <output/> |
3379 | + <stat/> |
3380 | + <convergence> |
3381 | + <exclude_from_convergence/> |
3382 | + </convergence> |
3383 | + <detectors> |
3384 | + <include_in_detectors/> |
3385 | + </detectors> |
3386 | + <steady_state> |
3387 | + <exclude_from_steady_state/> |
3388 | + </steady_state> |
3389 | + </diagnostic> |
3390 | + </scalar_field> |
3391 | + <scalar_field name="diff_m1" rank="0"> |
3392 | + <diagnostic> |
3393 | + <algorithm name="scalar_python_diagnostic" material_phase_support="single"> |
3394 | + <string_value lines="20" type="code" language="python">mom1_anal=state.scalar_fields["m1_anal"] |
3395 | +mom1_dqmom=state.scalar_fields["Moment_1"] |
3396 | +for i in range(field.node_count): |
3397 | + field.set(i, abs(mom1_dqmom.node_val(i)-mom1_anal.node_val(i))/abs(mom1_anal.node_val(i)))</string_value> |
3398 | + <depends> |
3399 | + <string_value lines="1">fluid::m1_anal</string_value> |
3400 | + </depends> |
3401 | + </algorithm> |
3402 | + <mesh name="VelocityMesh"/> |
3403 | + <output/> |
3404 | + <stat/> |
3405 | + <convergence> |
3406 | + <exclude_from_convergence/> |
3407 | + </convergence> |
3408 | + <detectors> |
3409 | + <include_in_detectors/> |
3410 | + </detectors> |
3411 | + <steady_state> |
3412 | + <exclude_from_steady_state/> |
3413 | + </steady_state> |
3414 | + </diagnostic> |
3415 | + </scalar_field> |
3416 | + <scalar_field name="diff_m2" rank="0"> |
3417 | + <diagnostic> |
3418 | + <algorithm name="scalar_python_diagnostic" material_phase_support="single"> |
3419 | + <string_value lines="20" type="code" language="python">mom2_anal=state.scalar_fields["m2_anal"] |
3420 | +mom2_dqmom=state.scalar_fields["Moment_2"] |
3421 | +for i in range(field.node_count): |
3422 | + field.set(i, abs(mom2_dqmom.node_val(i)-mom2_anal.node_val(i))/abs(mom2_anal.node_val(i)))</string_value> |
3423 | + <depends> |
3424 | + <string_value lines="1">fluid::m2_anal</string_value> |
3425 | + </depends> |
3426 | + </algorithm> |
3427 | + <mesh name="VelocityMesh"/> |
3428 | + <output/> |
3429 | + <stat/> |
3430 | + <convergence> |
3431 | + <exclude_from_convergence/> |
3432 | + </convergence> |
3433 | + <detectors> |
3434 | + <include_in_detectors/> |
3435 | + </detectors> |
3436 | + <steady_state> |
3437 | + <exclude_from_steady_state/> |
3438 | + </steady_state> |
3439 | + </diagnostic> |
3440 | + </scalar_field> |
3441 | + <scalar_field name="diff_m3" rank="0"> |
3442 | + <diagnostic> |
3443 | + <algorithm name="scalar_python_diagnostic" material_phase_support="single"> |
3444 | + <string_value lines="20" type="code" language="python">mom3_anal=state.scalar_fields["m3_anal"] |
3445 | +mom3_dqmom=state.scalar_fields["Moment_3"] |
3446 | +for i in range(field.node_count): |
3447 | + field.set(i, abs(mom3_dqmom.node_val(i)-mom3_anal.node_val(i))/abs(mom3_anal.node_val(i)))</string_value> |
3448 | + <depends> |
3449 | + <string_value lines="1">fluid::m3_anal</string_value> |
3450 | + </depends> |
3451 | + </algorithm> |
3452 | + <mesh name="VelocityMesh"/> |
3453 | + <output/> |
3454 | + <stat/> |
3455 | + <convergence> |
3456 | + <exclude_from_convergence/> |
3457 | + </convergence> |
3458 | + <detectors> |
3459 | + <include_in_detectors/> |
3460 | + </detectors> |
3461 | + <steady_state> |
3462 | + <exclude_from_steady_state/> |
3463 | + </steady_state> |
3464 | + </diagnostic> |
3465 | + </scalar_field> |
3466 | + <population_balance name="DQMOM"> |
3467 | + <calculate_initial_conditions_from_moments/> |
3468 | + <abscissa> |
3469 | + <scalar_field name="Abscissa_0" rank="0"> |
3470 | + <diagnostic> |
3471 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3472 | + <mesh name="VelocityMesh"/> |
3473 | + <output/> |
3474 | + <stat/> |
3475 | + <convergence> |
3476 | + <include_in_convergence/> |
3477 | + </convergence> |
3478 | + <detectors> |
3479 | + <include_in_detectors/> |
3480 | + </detectors> |
3481 | + <steady_state> |
3482 | + <include_in_steady_state/> |
3483 | + </steady_state> |
3484 | + </diagnostic> |
3485 | + </scalar_field> |
3486 | + <scalar_field name="Abscissa_1" rank="0"> |
3487 | + <diagnostic> |
3488 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3489 | + <mesh name="VelocityMesh"/> |
3490 | + <output/> |
3491 | + <stat/> |
3492 | + <convergence> |
3493 | + <include_in_convergence/> |
3494 | + </convergence> |
3495 | + <detectors> |
3496 | + <include_in_detectors/> |
3497 | + </detectors> |
3498 | + <steady_state> |
3499 | + <include_in_steady_state/> |
3500 | + </steady_state> |
3501 | + </diagnostic> |
3502 | + </scalar_field> |
3503 | + </abscissa> |
3504 | + <weights> |
3505 | + <scalar_field name="Weight_0" rank="0"> |
3506 | + <prognostic> |
3507 | + <mesh name="VelocityMesh"/> |
3508 | + <equation name="AdvectionDiffusion"/> |
3509 | + <spatial_discretisation> |
3510 | + <continuous_galerkin> |
3511 | + <stabilisation> |
3512 | + <no_stabilisation/> |
3513 | + </stabilisation> |
3514 | + <advection_terms> |
3515 | + <exclude_advection_terms/> |
3516 | + </advection_terms> |
3517 | + <mass_terms/> |
3518 | + </continuous_galerkin> |
3519 | + <conservative_advection> |
3520 | + <real_value rank="0">0.0</real_value> |
3521 | + </conservative_advection> |
3522 | + </spatial_discretisation> |
3523 | + <temporal_discretisation> |
3524 | + <theta> |
3525 | + <real_value rank="0">0.5</real_value> |
3526 | + </theta> |
3527 | + </temporal_discretisation> |
3528 | + <solver> |
3529 | + <iterative_method name="gmres"> |
3530 | + <restart> |
3531 | + <integer_value rank="0">30</integer_value> |
3532 | + </restart> |
3533 | + </iterative_method> |
3534 | + <preconditioner name="sor"/> |
3535 | + <relative_error> |
3536 | + <real_value rank="0">1e-7</real_value> |
3537 | + </relative_error> |
3538 | + <max_iterations> |
3539 | + <integer_value rank="0">1000</integer_value> |
3540 | + </max_iterations> |
3541 | + <never_ignore_solver_failures/> |
3542 | + <diagnostics> |
3543 | + <monitors/> |
3544 | + </diagnostics> |
3545 | + </solver> |
3546 | + <initial_condition name="WholeMesh"> |
3547 | + <constant> |
3548 | + <real_value rank="0">0.99480625</real_value> |
3549 | + </constant> |
3550 | + </initial_condition> |
3551 | + <scalar_field name="Source" rank="0"> |
3552 | + <diagnostic> |
3553 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3554 | + <output/> |
3555 | + <stat/> |
3556 | + <detectors> |
3557 | + <include_in_detectors/> |
3558 | + </detectors> |
3559 | + </diagnostic> |
3560 | + </scalar_field> |
3561 | + <output/> |
3562 | + <stat/> |
3563 | + <convergence> |
3564 | + <include_in_convergence/> |
3565 | + </convergence> |
3566 | + <detectors> |
3567 | + <include_in_detectors/> |
3568 | + </detectors> |
3569 | + <steady_state> |
3570 | + <include_in_steady_state/> |
3571 | + </steady_state> |
3572 | + <consistent_interpolation/> |
3573 | + </prognostic> |
3574 | + </scalar_field> |
3575 | + <scalar_field name="Weight_1" rank="0"> |
3576 | + <prognostic> |
3577 | + <mesh name="VelocityMesh"/> |
3578 | + <equation name="AdvectionDiffusion"/> |
3579 | + <spatial_discretisation> |
3580 | + <continuous_galerkin> |
3581 | + <stabilisation> |
3582 | + <no_stabilisation/> |
3583 | + </stabilisation> |
3584 | + <advection_terms> |
3585 | + <exclude_advection_terms/> |
3586 | + </advection_terms> |
3587 | + <mass_terms/> |
3588 | + </continuous_galerkin> |
3589 | + <conservative_advection> |
3590 | + <real_value rank="0">0.0</real_value> |
3591 | + </conservative_advection> |
3592 | + </spatial_discretisation> |
3593 | + <temporal_discretisation> |
3594 | + <theta> |
3595 | + <real_value rank="0">0.5</real_value> |
3596 | + </theta> |
3597 | + </temporal_discretisation> |
3598 | + <solver> |
3599 | + <iterative_method name="gmres"> |
3600 | + <restart> |
3601 | + <integer_value rank="0">30</integer_value> |
3602 | + </restart> |
3603 | + </iterative_method> |
3604 | + <preconditioner name="sor"/> |
3605 | + <relative_error> |
3606 | + <real_value rank="0">1e-7</real_value> |
3607 | + </relative_error> |
3608 | + <max_iterations> |
3609 | + <integer_value rank="0">1000</integer_value> |
3610 | + </max_iterations> |
3611 | + <never_ignore_solver_failures/> |
3612 | + <diagnostics> |
3613 | + <monitors/> |
3614 | + </diagnostics> |
3615 | + </solver> |
3616 | + <initial_condition name="WholeMesh"> |
3617 | + <constant> |
3618 | + <real_value rank="0">0.00519377</real_value> |
3619 | + </constant> |
3620 | + </initial_condition> |
3621 | + <scalar_field name="Source" rank="0"> |
3622 | + <diagnostic> |
3623 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3624 | + <output/> |
3625 | + <stat/> |
3626 | + <detectors> |
3627 | + <include_in_detectors/> |
3628 | + </detectors> |
3629 | + </diagnostic> |
3630 | + </scalar_field> |
3631 | + <output/> |
3632 | + <stat/> |
3633 | + <convergence> |
3634 | + <include_in_convergence/> |
3635 | + </convergence> |
3636 | + <detectors> |
3637 | + <include_in_detectors/> |
3638 | + </detectors> |
3639 | + <steady_state> |
3640 | + <include_in_steady_state/> |
3641 | + </steady_state> |
3642 | + <consistent_interpolation/> |
3643 | + </prognostic> |
3644 | + </scalar_field> |
3645 | + </weights> |
3646 | + <weighted_abscissa> |
3647 | + <scalar_field name="WeightedAbscissa_0" rank="0"> |
3648 | + <prognostic> |
3649 | + <mesh name="VelocityMesh"/> |
3650 | + <equation name="AdvectionDiffusion"/> |
3651 | + <spatial_discretisation> |
3652 | + <continuous_galerkin> |
3653 | + <stabilisation> |
3654 | + <no_stabilisation/> |
3655 | + </stabilisation> |
3656 | + <advection_terms> |
3657 | + <exclude_advection_terms/> |
3658 | + </advection_terms> |
3659 | + <mass_terms/> |
3660 | + </continuous_galerkin> |
3661 | + <conservative_advection> |
3662 | + <real_value rank="0">0.0</real_value> |
3663 | + </conservative_advection> |
3664 | + </spatial_discretisation> |
3665 | + <temporal_discretisation> |
3666 | + <theta> |
3667 | + <real_value rank="0">0.5</real_value> |
3668 | + </theta> |
3669 | + </temporal_discretisation> |
3670 | + <solver> |
3671 | + <iterative_method name="gmres"> |
3672 | + <restart> |
3673 | + <integer_value rank="0">30</integer_value> |
3674 | + </restart> |
3675 | + </iterative_method> |
3676 | + <preconditioner name="sor"/> |
3677 | + <relative_error> |
3678 | + <real_value rank="0">1e-7</real_value> |
3679 | + </relative_error> |
3680 | + <max_iterations> |
3681 | + <integer_value rank="0">1000</integer_value> |
3682 | + </max_iterations> |
3683 | + <never_ignore_solver_failures/> |
3684 | + <diagnostics> |
3685 | + <monitors/> |
3686 | + </diagnostics> |
3687 | + </solver> |
3688 | + <initial_condition name="WholeMesh"> |
3689 | + <python> |
3690 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3691 | + return (0.99480625*1.13701522)</string_value> |
3692 | + </python> |
3693 | + </initial_condition> |
3694 | + <scalar_field name="Source" rank="0"> |
3695 | + <diagnostic> |
3696 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3697 | + <output/> |
3698 | + <stat/> |
3699 | + <detectors> |
3700 | + <include_in_detectors/> |
3701 | + </detectors> |
3702 | + </diagnostic> |
3703 | + </scalar_field> |
3704 | + <output/> |
3705 | + <stat/> |
3706 | + <convergence> |
3707 | + <include_in_convergence/> |
3708 | + </convergence> |
3709 | + <detectors> |
3710 | + <include_in_detectors/> |
3711 | + </detectors> |
3712 | + <steady_state> |
3713 | + <include_in_steady_state/> |
3714 | + </steady_state> |
3715 | + <consistent_interpolation/> |
3716 | + </prognostic> |
3717 | + </scalar_field> |
3718 | + <scalar_field name="WeightedAbscissa_1" rank="0"> |
3719 | + <prognostic> |
3720 | + <mesh name="VelocityMesh"/> |
3721 | + <equation name="AdvectionDiffusion"/> |
3722 | + <spatial_discretisation> |
3723 | + <continuous_galerkin> |
3724 | + <stabilisation> |
3725 | + <no_stabilisation/> |
3726 | + </stabilisation> |
3727 | + <advection_terms> |
3728 | + <exclude_advection_terms/> |
3729 | + </advection_terms> |
3730 | + <mass_terms/> |
3731 | + </continuous_galerkin> |
3732 | + <conservative_advection> |
3733 | + <real_value rank="0">0.0</real_value> |
3734 | + </conservative_advection> |
3735 | + </spatial_discretisation> |
3736 | + <temporal_discretisation> |
3737 | + <theta> |
3738 | + <real_value rank="0">0.5</real_value> |
3739 | + </theta> |
3740 | + </temporal_discretisation> |
3741 | + <solver> |
3742 | + <iterative_method name="gmres"> |
3743 | + <restart> |
3744 | + <integer_value rank="0">30</integer_value> |
3745 | + </restart> |
3746 | + </iterative_method> |
3747 | + <preconditioner name="sor"/> |
3748 | + <relative_error> |
3749 | + <real_value rank="0">1e-7</real_value> |
3750 | + </relative_error> |
3751 | + <max_iterations> |
3752 | + <integer_value rank="0">1000</integer_value> |
3753 | + </max_iterations> |
3754 | + <never_ignore_solver_failures/> |
3755 | + <diagnostics> |
3756 | + <monitors/> |
3757 | + </diagnostics> |
3758 | + </solver> |
3759 | + <initial_condition name="WholeMesh"> |
3760 | + <python> |
3761 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3762 | + return (0.00519377*-4.46492922)</string_value> |
3763 | + </python> |
3764 | + </initial_condition> |
3765 | + <scalar_field name="Source" rank="0"> |
3766 | + <diagnostic> |
3767 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3768 | + <output/> |
3769 | + <stat/> |
3770 | + <detectors> |
3771 | + <include_in_detectors/> |
3772 | + </detectors> |
3773 | + </diagnostic> |
3774 | + </scalar_field> |
3775 | + <output/> |
3776 | + <stat/> |
3777 | + <convergence> |
3778 | + <include_in_convergence/> |
3779 | + </convergence> |
3780 | + <detectors> |
3781 | + <include_in_detectors/> |
3782 | + </detectors> |
3783 | + <steady_state> |
3784 | + <include_in_steady_state/> |
3785 | + </steady_state> |
3786 | + <consistent_interpolation/> |
3787 | + </prognostic> |
3788 | + </scalar_field> |
3789 | + </weighted_abscissa> |
3790 | + <adv_diff_source_term_interpolation> |
3791 | + <use_mass_lumping/> |
3792 | + </adv_diff_source_term_interpolation> |
3793 | + <moments> |
3794 | + <scalar_field name="Moment_0" rank="0"> |
3795 | + <diagnostic> |
3796 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3797 | + <mesh name="VelocityMesh"/> |
3798 | + <initial_condition name="WholeMesh"> |
3799 | + <constant> |
3800 | + <real_value rank="0">1.0</real_value> |
3801 | + </constant> |
3802 | + </initial_condition> |
3803 | + <output/> |
3804 | + <stat/> |
3805 | + <convergence> |
3806 | + <include_in_convergence/> |
3807 | + </convergence> |
3808 | + <detectors> |
3809 | + <include_in_detectors/> |
3810 | + </detectors> |
3811 | + <steady_state> |
3812 | + <include_in_steady_state/> |
3813 | + </steady_state> |
3814 | + </diagnostic> |
3815 | + </scalar_field> |
3816 | + <scalar_field name="Moment_1" rank="0"> |
3817 | + <diagnostic> |
3818 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3819 | + <mesh name="VelocityMesh"/> |
3820 | + <initial_condition name="WholeMesh"> |
3821 | + <python> |
3822 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3823 | + from math import gamma, pi |
3824 | + mom1 = (6./pi)**(1./3.) * gamma(4./3.) |
3825 | + return mom1</string_value> |
3826 | + </python> |
3827 | + </initial_condition> |
3828 | + <output/> |
3829 | + <stat/> |
3830 | + <convergence> |
3831 | + <include_in_convergence/> |
3832 | + </convergence> |
3833 | + <detectors> |
3834 | + <include_in_detectors/> |
3835 | + </detectors> |
3836 | + <steady_state> |
3837 | + <include_in_steady_state/> |
3838 | + </steady_state> |
3839 | + </diagnostic> |
3840 | + </scalar_field> |
3841 | + <scalar_field name="Moment_2" rank="0"> |
3842 | + <diagnostic> |
3843 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3844 | + <mesh name="VelocityMesh"/> |
3845 | + <initial_condition name="WholeMesh"> |
3846 | + <python> |
3847 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3848 | + from math import gamma, pi |
3849 | + mom2 = (6./pi)**(2./3.) * gamma(5./3.) |
3850 | + return mom2</string_value> |
3851 | + </python> |
3852 | + </initial_condition> |
3853 | + <output/> |
3854 | + <stat/> |
3855 | + <convergence> |
3856 | + <include_in_convergence/> |
3857 | + </convergence> |
3858 | + <detectors> |
3859 | + <include_in_detectors/> |
3860 | + </detectors> |
3861 | + <steady_state> |
3862 | + <include_in_steady_state/> |
3863 | + </steady_state> |
3864 | + </diagnostic> |
3865 | + </scalar_field> |
3866 | + <scalar_field name="Moment_3" rank="0"> |
3867 | + <diagnostic> |
3868 | + <algorithm name="Internal" material_phase_support="multiple"/> |
3869 | + <mesh name="VelocityMesh"/> |
3870 | + <initial_condition name="WholeMesh"> |
3871 | + <python> |
3872 | + <string_value lines="20" type="code" language="python">def val(X,t): |
3873 | + from math import pi |
3874 | + mom3 = (6./pi) |
3875 | + return mom3</string_value> |
3876 | + </python> |
3877 | + </initial_condition> |
3878 | + <output/> |
3879 | + <stat/> |
3880 | + <convergence> |
3881 | + <include_in_convergence/> |
3882 | + </convergence> |
3883 | + <detectors> |
3884 | + <include_in_detectors/> |
3885 | + </detectors> |
3886 | + <steady_state> |
3887 | + <include_in_steady_state/> |
3888 | + </steady_state> |
3889 | + </diagnostic> |
3890 | + </scalar_field> |
3891 | + </moments> |
3892 | + <statistics/> |
3893 | + <population_balance_source_terms> |
3894 | + <aggregation> |
3895 | + <aggregation_frequency> |
3896 | + <constant_aggregation> |
3897 | + <real_value rank="0">1.0</real_value> |
3898 | + </constant_aggregation> |
3899 | + </aggregation_frequency> |
3900 | + </aggregation> |
3901 | + <breakage> |
3902 | + <breakage_frequency> |
3903 | + <power_law_breakage> |
3904 | + <coefficient> |
3905 | + <real_value rank="0">26.17993878</real_value> |
3906 | + </coefficient> |
3907 | + <degree> |
3908 | + <real_value rank="0">3</real_value> |
3909 | + </degree> |
3910 | + </power_law_breakage> |
3911 | + </breakage_frequency> |
3912 | + <distribution_function> |
3913 | + <mcCoy_madras_2003/> |
3914 | + </distribution_function> |
3915 | + </breakage> |
3916 | + </population_balance_source_terms> |
3917 | + <ill_conditioned_matrices> |
3918 | + <required_condition_number> |
3919 | + <real_value rank="0">1.0e-12</real_value> |
3920 | + </required_condition_number> |
3921 | + <set_source_to_zero/> |
3922 | + </ill_conditioned_matrices> |
3923 | + <minimum_weight> |
3924 | + <real_value rank="0">1e-10</real_value> |
3925 | + </minimum_weight> |
3926 | + </population_balance> |
3927 | + </material_phase> |
3928 | +</fluidity_options> |
3929 | |
3930 | === added file 'tests/popbal_homog_brk_aggr/popbal_homog_N2_brk_aggr.xml' |
3931 | --- tests/popbal_homog_brk_aggr/popbal_homog_N2_brk_aggr.xml 1970-01-01 00:00:00 +0000 |
3932 | +++ tests/popbal_homog_brk_aggr/popbal_homog_N2_brk_aggr.xml 2013-12-12 22:35:40 +0000 |
3933 | @@ -0,0 +1,34 @@ |
3934 | +<?xml version='1.0' encoding='utf-8'?> |
3935 | +<testproblem> |
3936 | + <name>Transient population balance using direct quadrature method of moments (N=2) for a homogeneous case with breakage and aggregation (McCoy and Madras (2003))</name> |
3937 | + <owner userid="gb812"/> |
3938 | + <tags>flml</tags> |
3939 | + <problem_definition length="medium" nprocs="1"> |
3940 | + <command_line>fluidity popbal_homog_N2.flml</command_line> |
3941 | + </problem_definition> |
3942 | + <variables> |
3943 | + <variable name="solvers_converged" language="python">import os |
3944 | +files = os.listdir("./") |
3945 | +solvers_converged = not "matrixdump" in files and not "matrixdump.info" in files</variable> |
3946 | + <variable name="moment0_maxerror_t_5s" language="python">from fluidity_tools import stat_parser |
3947 | +s = stat_parser("popbal_homog_N2_brk_aggr.stat") |
3948 | +moment0_maxerror_t_5s = s["fluid"]["diff_m0"]["max"][-1]</variable> |
3949 | + <variable name="moment1_maxerror_t_5s" language="python">from fluidity_tools import stat_parser |
3950 | +s = stat_parser("popbal_homog_N2_brk_aggr.stat") |
3951 | +moment1_maxerror_t_5s = s["fluid"]["diff_m1"]["max"][-1]</variable> |
3952 | + <variable name="moment2_maxerror_t_5s" language="python">from fluidity_tools import stat_parser |
3953 | +s = stat_parser("popbal_homog_N2_brk_aggr.stat") |
3954 | +moment2_maxerror_t_5s = s["fluid"]["diff_m2"]["max"][-1]</variable> |
3955 | + <variable name="moment3_maxerror_t_5s" language="python">from fluidity_tools import stat_parser |
3956 | +s = stat_parser("popbal_homog_N2_brk_aggr.stat") |
3957 | +moment3_maxerror_t_5s = s["fluid"]["diff_m3"]["max"][-1]</variable> |
3958 | + </variables> |
3959 | + <pass_tests> |
3960 | + <test name="Solvers converged" language="python">assert(solvers_converged)</test> |
3961 | + <test name="moment0 max percent error at 5s less than 0.006" language="python">assert moment0_maxerror_t_5s < 0.006</test> |
3962 | + <test name="moment1 max percent error at 5s less than 0.003" language="python">assert moment1_maxerror_t_5s < 0.003</test> |
3963 | + <test name="moment2 max percent error at 5s less than 0.003" language="python">assert moment2_maxerror_t_5s < 0.003</test> |
3964 | + <test name="moment3 max percent error at 5s less than 0.01" language="python">assert moment3_maxerror_t_5s < 0.01</test> |
3965 | + </pass_tests> |
3966 | + <warn_tests/> |
3967 | +</testproblem> |
3968 | |
3969 | === added directory 'tests/popbal_homog_brk_aggr/src' |
3970 | === added file 'tests/popbal_homog_brk_aggr/src/minimal.geo' |
3971 | --- tests/popbal_homog_brk_aggr/src/minimal.geo 1970-01-01 00:00:00 +0000 |
3972 | +++ tests/popbal_homog_brk_aggr/src/minimal.geo 2013-12-12 22:35:40 +0000 |
3973 | @@ -0,0 +1,28 @@ |
3974 | +$MeshFormat |
3975 | +2.2 0 8 |
3976 | +$EndMeshFormat |
3977 | +$Nodes |
3978 | +7 |
3979 | +1 0 0 0 |
3980 | +2 1 0 0 |
3981 | +3 1 1 0 |
3982 | +4 0.4999999999990216 0 0 |
3983 | +5 1 0.4999999999990216 0 |
3984 | +6 0.5000000000013878 0.5000000000013878 0 |
3985 | +7 0.7499999999999051 0.2499999999999052 0 |
3986 | +$EndNodes |
3987 | +$Elements |
3988 | +12 |
3989 | +1 1 2 6 1 1 4 |
3990 | +2 1 2 6 1 4 2 |
3991 | +3 1 2 6 2 2 5 |
3992 | +4 1 2 6 2 5 3 |
3993 | +5 1 2 6 3 3 6 |
3994 | +6 1 2 6 3 6 1 |
3995 | +7 2 2 7 5 4 7 6 |
3996 | +8 2 2 7 5 2 7 4 |
3997 | +9 2 2 7 5 2 5 7 |
3998 | +10 2 2 7 5 5 6 7 |
3999 | +11 2 2 7 5 5 3 6 |
4000 | +12 2 2 7 5 4 6 1 |
4001 | +$EndElements |
4002 | |
4003 | === added directory 'tests/popbal_nonhomog2_2d_adapt' |
4004 | === added file 'tests/popbal_nonhomog2_2d_adapt/Makefile' |
4005 | --- tests/popbal_nonhomog2_2d_adapt/Makefile 1970-01-01 00:00:00 +0000 |
4006 | +++ tests/popbal_nonhomog2_2d_adapt/Makefile 2013-12-12 22:35:40 +0000 |
4007 | @@ -0,0 +1,5 @@ |
4008 | +input: clean |
4009 | + gmsh -2 src/channel.geo -optimize |
4010 | + |
4011 | +clean: |
4012 | + rm -f *.vtu *.pvtu fluidity.* *.s *.d.1 *.stat src/channel.msh |
4013 | |
4014 | === added file 'tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.flml' |
4015 | --- tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.flml 1970-01-01 00:00:00 +0000 |
4016 | +++ tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.flml 2013-12-12 22:35:40 +0000 |
4017 | @@ -0,0 +1,670 @@ |
4018 | +<?xml version='1.0' encoding='utf-8'?> |
4019 | +<fluidity_options> |
4020 | + <simulation_name> |
4021 | + <string_value lines="1">popbal_nonhomog2_2d</string_value> |
4022 | + </simulation_name> |
4023 | + <problem_type> |
4024 | + <string_value lines="1">fluids</string_value> |
4025 | + </problem_type> |
4026 | + <geometry> |
4027 | + <dimension> |
4028 | + <integer_value rank="0">2</integer_value> |
4029 | + </dimension> |
4030 | + <mesh name="CoordinateMesh"> |
4031 | + <from_file file_name="./src/channel"> |
4032 | + <format name="gmsh"/> |
4033 | + <stat> |
4034 | + <include_in_stat/> |
4035 | + </stat> |
4036 | + </from_file> |
4037 | + </mesh> |
4038 | + <mesh name="VelocityMesh"> |
4039 | + <from_mesh> |
4040 | + <mesh name="CoordinateMesh"/> |
4041 | + <mesh_shape> |
4042 | + <polynomial_degree> |
4043 | + <integer_value rank="0">1</integer_value> |
4044 | + </polynomial_degree> |
4045 | + </mesh_shape> |
4046 | + <mesh_continuity> |
4047 | + <string_value>continuous</string_value> |
4048 | + </mesh_continuity> |
4049 | + <stat> |
4050 | + <exclude_from_stat/> |
4051 | + </stat> |
4052 | + </from_mesh> |
4053 | + </mesh> |
4054 | + <quadrature> |
4055 | + <degree> |
4056 | + <integer_value rank="0">3</integer_value> |
4057 | + </degree> |
4058 | + </quadrature> |
4059 | + </geometry> |
4060 | + <io> |
4061 | + <dump_format> |
4062 | + <string_value>vtk</string_value> |
4063 | + </dump_format> |
4064 | + <dump_period> |
4065 | + <constant> |
4066 | + <real_value rank="0">1</real_value> |
4067 | + </constant> |
4068 | + </dump_period> |
4069 | + <output_mesh name="VelocityMesh"/> |
4070 | + <stat/> |
4071 | + </io> |
4072 | + <timestepping> |
4073 | + <current_time> |
4074 | + <real_value rank="0">0.0</real_value> |
4075 | + </current_time> |
4076 | + <timestep> |
4077 | + <real_value rank="0">0.005</real_value> |
4078 | + </timestep> |
4079 | + <finish_time> |
4080 | + <real_value rank="0">20</real_value> |
4081 | + </finish_time> |
4082 | + </timestepping> |
4083 | + <material_phase name="fluid"> |
4084 | + <vector_field name="Velocity" rank="1"> |
4085 | + <prescribed> |
4086 | + <mesh name="VelocityMesh"/> |
4087 | + <value name="WholeMesh"> |
4088 | + <constant> |
4089 | + <real_value shape="2" dim1="dim" rank="1">0 0</real_value> |
4090 | + </constant> |
4091 | + </value> |
4092 | + <output/> |
4093 | + <stat> |
4094 | + <include_in_stat/> |
4095 | + </stat> |
4096 | + <detectors> |
4097 | + <exclude_from_detectors/> |
4098 | + </detectors> |
4099 | + </prescribed> |
4100 | + </vector_field> |
4101 | + <scalar_field name="m3_analytical" rank="0"> |
4102 | + <prescribed> |
4103 | + <mesh name="VelocityMesh"/> |
4104 | + <value name="WholeMesh"> |
4105 | + <python> |
4106 | + <string_value lines="20" type="code" language="python">def val(X,t): |
4107 | + from math import exp, pi, cos |
4108 | + if (abs(t-round(t))<=0.01): |
4109 | + nu=0.001 |
4110 | + L=1.0 |
4111 | + n=100 |
4112 | + phi_n=0.0 |
4113 | + i=1 |
4114 | + while i<=n: |
4115 | + j=2*i |
4116 | + val = (1.0/j**2)*exp(-(nu*j**2*pi**2*t)/(L**2))*cos((j*pi*X[0])/L) |
4117 | + phi_n = phi_n + val |
4118 | + i=i+1 |
4119 | + phi_n = phi_n*(-4.0/pi**2) + 1.0/6.0 |
4120 | + return phi_n |
4121 | + else: |
4122 | + return 0.0</string_value> |
4123 | + </python> |
4124 | + </value> |
4125 | + <output/> |
4126 | + <stat/> |
4127 | + <detectors> |
4128 | + <exclude_from_detectors/> |
4129 | + </detectors> |
4130 | + </prescribed> |
4131 | + </scalar_field> |
4132 | + <scalar_field name="ScalarAbsoluteDifference" rank="0"> |
4133 | + <diagnostic field_name_b="m3_analytical" field_name_a="Moment_3"> |
4134 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4135 | + <mesh name="VelocityMesh"/> |
4136 | + <output/> |
4137 | + <stat/> |
4138 | + <convergence> |
4139 | + <exclude_from_convergence/> |
4140 | + </convergence> |
4141 | + <detectors> |
4142 | + <exclude_from_detectors/> |
4143 | + </detectors> |
4144 | + <steady_state> |
4145 | + <exclude_from_steady_state/> |
4146 | + </steady_state> |
4147 | + </diagnostic> |
4148 | + </scalar_field> |
4149 | + <population_balance name="DQMOM"> |
4150 | + <use_prognostic_field_initial_conditions/> |
4151 | + <abscissa> |
4152 | + <scalar_field name="Abscissa_0" rank="0"> |
4153 | + <diagnostic> |
4154 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4155 | + <mesh name="VelocityMesh"/> |
4156 | + <output/> |
4157 | + <stat/> |
4158 | + <convergence> |
4159 | + <include_in_convergence/> |
4160 | + </convergence> |
4161 | + <detectors> |
4162 | + <include_in_detectors/> |
4163 | + </detectors> |
4164 | + <steady_state> |
4165 | + <include_in_steady_state/> |
4166 | + </steady_state> |
4167 | + <consistent_interpolation/> |
4168 | + </diagnostic> |
4169 | + </scalar_field> |
4170 | + <scalar_field name="Abscissa_1" rank="0"> |
4171 | + <diagnostic> |
4172 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4173 | + <mesh name="VelocityMesh"/> |
4174 | + <output/> |
4175 | + <stat/> |
4176 | + <convergence> |
4177 | + <include_in_convergence/> |
4178 | + </convergence> |
4179 | + <detectors> |
4180 | + <include_in_detectors/> |
4181 | + </detectors> |
4182 | + <steady_state> |
4183 | + <include_in_steady_state/> |
4184 | + </steady_state> |
4185 | + <consistent_interpolation/> |
4186 | + </diagnostic> |
4187 | + </scalar_field> |
4188 | + </abscissa> |
4189 | + <weights> |
4190 | + <scalar_field name="Weight_0" rank="0"> |
4191 | + <prognostic> |
4192 | + <mesh name="VelocityMesh"/> |
4193 | + <equation name="AdvectionDiffusion"/> |
4194 | + <spatial_discretisation> |
4195 | + <continuous_galerkin> |
4196 | + <stabilisation> |
4197 | + <no_stabilisation/> |
4198 | + </stabilisation> |
4199 | + <advection_terms/> |
4200 | + <mass_terms/> |
4201 | + </continuous_galerkin> |
4202 | + <conservative_advection> |
4203 | + <real_value rank="0">0.0</real_value> |
4204 | + </conservative_advection> |
4205 | + </spatial_discretisation> |
4206 | + <temporal_discretisation> |
4207 | + <theta> |
4208 | + <real_value rank="0">0.5</real_value> |
4209 | + </theta> |
4210 | + </temporal_discretisation> |
4211 | + <solver> |
4212 | + <iterative_method name="gmres"> |
4213 | + <restart> |
4214 | + <integer_value rank="0">30</integer_value> |
4215 | + </restart> |
4216 | + </iterative_method> |
4217 | + <preconditioner name="sor"/> |
4218 | + <relative_error> |
4219 | + <real_value rank="0">1e-7</real_value> |
4220 | + </relative_error> |
4221 | + <max_iterations> |
4222 | + <integer_value rank="0">1000</integer_value> |
4223 | + </max_iterations> |
4224 | + <never_ignore_solver_failures/> |
4225 | + <diagnostics> |
4226 | + <monitors/> |
4227 | + </diagnostics> |
4228 | + </solver> |
4229 | + <initial_condition name="WholeMesh"> |
4230 | + <constant> |
4231 | + <real_value rank="0">0.5</real_value> |
4232 | + </constant> |
4233 | + </initial_condition> |
4234 | + <tensor_field name="Diffusivity" rank="2"> |
4235 | + <prescribed> |
4236 | + <value name="WholeMesh"> |
4237 | + <isotropic> |
4238 | + <constant> |
4239 | + <real_value rank="0">1e-3</real_value> |
4240 | + </constant> |
4241 | + </isotropic> |
4242 | + </value> |
4243 | + <output/> |
4244 | + </prescribed> |
4245 | + </tensor_field> |
4246 | + <scalar_field name="Source" rank="0"> |
4247 | + <diagnostic> |
4248 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4249 | + <output/> |
4250 | + <stat/> |
4251 | + <detectors> |
4252 | + <include_in_detectors/> |
4253 | + </detectors> |
4254 | + </diagnostic> |
4255 | + </scalar_field> |
4256 | + <output/> |
4257 | + <stat/> |
4258 | + <convergence> |
4259 | + <include_in_convergence/> |
4260 | + </convergence> |
4261 | + <detectors> |
4262 | + <include_in_detectors/> |
4263 | + </detectors> |
4264 | + <steady_state> |
4265 | + <include_in_steady_state/> |
4266 | + </steady_state> |
4267 | + <consistent_interpolation/> |
4268 | + </prognostic> |
4269 | + </scalar_field> |
4270 | + <scalar_field name="Weight_1" rank="0"> |
4271 | + <prognostic> |
4272 | + <mesh name="VelocityMesh"/> |
4273 | + <equation name="AdvectionDiffusion"/> |
4274 | + <spatial_discretisation> |
4275 | + <continuous_galerkin> |
4276 | + <stabilisation> |
4277 | + <no_stabilisation/> |
4278 | + </stabilisation> |
4279 | + <advection_terms/> |
4280 | + <mass_terms/> |
4281 | + </continuous_galerkin> |
4282 | + <conservative_advection> |
4283 | + <real_value rank="0">0.0</real_value> |
4284 | + </conservative_advection> |
4285 | + </spatial_discretisation> |
4286 | + <temporal_discretisation> |
4287 | + <theta> |
4288 | + <real_value rank="0">0.5</real_value> |
4289 | + </theta> |
4290 | + </temporal_discretisation> |
4291 | + <solver> |
4292 | + <iterative_method name="gmres"> |
4293 | + <restart> |
4294 | + <integer_value rank="0">30</integer_value> |
4295 | + </restart> |
4296 | + </iterative_method> |
4297 | + <preconditioner name="sor"/> |
4298 | + <relative_error> |
4299 | + <real_value rank="0">1e-7</real_value> |
4300 | + </relative_error> |
4301 | + <max_iterations> |
4302 | + <integer_value rank="0">1000</integer_value> |
4303 | + </max_iterations> |
4304 | + <never_ignore_solver_failures/> |
4305 | + <diagnostics> |
4306 | + <monitors/> |
4307 | + </diagnostics> |
4308 | + </solver> |
4309 | + <initial_condition name="WholeMesh"> |
4310 | + <constant> |
4311 | + <real_value rank="0">0.5</real_value> |
4312 | + </constant> |
4313 | + </initial_condition> |
4314 | + <tensor_field name="Diffusivity" rank="2"> |
4315 | + <prescribed> |
4316 | + <value name="WholeMesh"> |
4317 | + <isotropic> |
4318 | + <constant> |
4319 | + <real_value rank="0">1e-3</real_value> |
4320 | + </constant> |
4321 | + </isotropic> |
4322 | + </value> |
4323 | + <output/> |
4324 | + </prescribed> |
4325 | + </tensor_field> |
4326 | + <scalar_field name="Source" rank="0"> |
4327 | + <diagnostic> |
4328 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4329 | + <output/> |
4330 | + <stat/> |
4331 | + <detectors> |
4332 | + <include_in_detectors/> |
4333 | + </detectors> |
4334 | + </diagnostic> |
4335 | + </scalar_field> |
4336 | + <output/> |
4337 | + <stat/> |
4338 | + <convergence> |
4339 | + <include_in_convergence/> |
4340 | + </convergence> |
4341 | + <detectors> |
4342 | + <include_in_detectors/> |
4343 | + </detectors> |
4344 | + <steady_state> |
4345 | + <include_in_steady_state/> |
4346 | + </steady_state> |
4347 | + <consistent_interpolation/> |
4348 | + </prognostic> |
4349 | + </scalar_field> |
4350 | + </weights> |
4351 | + <weighted_abscissa> |
4352 | + <scalar_field name="WeightedAbscissa_0" rank="0"> |
4353 | + <prognostic> |
4354 | + <mesh name="VelocityMesh"/> |
4355 | + <equation name="AdvectionDiffusion"/> |
4356 | + <spatial_discretisation> |
4357 | + <continuous_galerkin> |
4358 | + <stabilisation> |
4359 | + <no_stabilisation/> |
4360 | + </stabilisation> |
4361 | + <advection_terms/> |
4362 | + <mass_terms/> |
4363 | + </continuous_galerkin> |
4364 | + <conservative_advection> |
4365 | + <real_value rank="0">0.0</real_value> |
4366 | + </conservative_advection> |
4367 | + </spatial_discretisation> |
4368 | + <temporal_discretisation> |
4369 | + <theta> |
4370 | + <real_value rank="0">0.5</real_value> |
4371 | + </theta> |
4372 | + </temporal_discretisation> |
4373 | + <solver> |
4374 | + <iterative_method name="gmres"> |
4375 | + <restart> |
4376 | + <integer_value rank="0">30</integer_value> |
4377 | + </restart> |
4378 | + </iterative_method> |
4379 | + <preconditioner name="sor"/> |
4380 | + <relative_error> |
4381 | + <real_value rank="0">1e-7</real_value> |
4382 | + </relative_error> |
4383 | + <max_iterations> |
4384 | + <integer_value rank="0">1000</integer_value> |
4385 | + </max_iterations> |
4386 | + <never_ignore_solver_failures/> |
4387 | + <diagnostics> |
4388 | + <monitors/> |
4389 | + </diagnostics> |
4390 | + </solver> |
4391 | + <initial_condition name="WholeMesh"> |
4392 | + <python> |
4393 | + <string_value lines="20" type="code" language="python">def val(X, t): |
4394 | + zeta1=0.5* (1.0 + 2.0*X[0]*(1-X[0]))**(1.0/3.0) |
4395 | + return zeta1</string_value> |
4396 | + </python> |
4397 | + </initial_condition> |
4398 | + <tensor_field name="Diffusivity" rank="2"> |
4399 | + <prescribed> |
4400 | + <value name="WholeMesh"> |
4401 | + <isotropic> |
4402 | + <constant> |
4403 | + <real_value rank="0">1e-3</real_value> |
4404 | + </constant> |
4405 | + </isotropic> |
4406 | + </value> |
4407 | + <output/> |
4408 | + </prescribed> |
4409 | + </tensor_field> |
4410 | + <scalar_field name="Source" rank="0"> |
4411 | + <diagnostic> |
4412 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4413 | + <output/> |
4414 | + <stat/> |
4415 | + <detectors> |
4416 | + <include_in_detectors/> |
4417 | + </detectors> |
4418 | + </diagnostic> |
4419 | + </scalar_field> |
4420 | + <output/> |
4421 | + <stat/> |
4422 | + <convergence> |
4423 | + <include_in_convergence/> |
4424 | + </convergence> |
4425 | + <detectors> |
4426 | + <include_in_detectors/> |
4427 | + </detectors> |
4428 | + <steady_state> |
4429 | + <include_in_steady_state/> |
4430 | + </steady_state> |
4431 | + <consistent_interpolation/> |
4432 | + </prognostic> |
4433 | + </scalar_field> |
4434 | + <scalar_field name="WeightedAbscissa_1" rank="0"> |
4435 | + <prognostic> |
4436 | + <mesh name="VelocityMesh"/> |
4437 | + <equation name="AdvectionDiffusion"/> |
4438 | + <spatial_discretisation> |
4439 | + <continuous_galerkin> |
4440 | + <stabilisation> |
4441 | + <no_stabilisation/> |
4442 | + </stabilisation> |
4443 | + <advection_terms/> |
4444 | + <mass_terms/> |
4445 | + </continuous_galerkin> |
4446 | + <conservative_advection> |
4447 | + <real_value rank="0">0.0</real_value> |
4448 | + </conservative_advection> |
4449 | + </spatial_discretisation> |
4450 | + <temporal_discretisation> |
4451 | + <theta> |
4452 | + <real_value rank="0">0.5</real_value> |
4453 | + </theta> |
4454 | + </temporal_discretisation> |
4455 | + <solver> |
4456 | + <iterative_method name="gmres"> |
4457 | + <restart> |
4458 | + <integer_value rank="0">30</integer_value> |
4459 | + </restart> |
4460 | + </iterative_method> |
4461 | + <preconditioner name="sor"/> |
4462 | + <relative_error> |
4463 | + <real_value rank="0">1e-7</real_value> |
4464 | + </relative_error> |
4465 | + <max_iterations> |
4466 | + <integer_value rank="0">1000</integer_value> |
4467 | + </max_iterations> |
4468 | + <never_ignore_solver_failures/> |
4469 | + <diagnostics> |
4470 | + <monitors/> |
4471 | + </diagnostics> |
4472 | + </solver> |
4473 | + <initial_condition name="WholeMesh"> |
4474 | + <python> |
4475 | + <string_value lines="20" type="code" language="python">def val(X, t): |
4476 | + zeta2=0.5*(-1.0) |
4477 | + return zeta2</string_value> |
4478 | + </python> |
4479 | + </initial_condition> |
4480 | + <tensor_field name="Diffusivity" rank="2"> |
4481 | + <prescribed> |
4482 | + <value name="WholeMesh"> |
4483 | + <isotropic> |
4484 | + <constant> |
4485 | + <real_value rank="0">1e-3</real_value> |
4486 | + </constant> |
4487 | + </isotropic> |
4488 | + </value> |
4489 | + <output/> |
4490 | + </prescribed> |
4491 | + </tensor_field> |
4492 | + <scalar_field name="Source" rank="0"> |
4493 | + <diagnostic> |
4494 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4495 | + <output/> |
4496 | + <stat/> |
4497 | + <detectors> |
4498 | + <include_in_detectors/> |
4499 | + </detectors> |
4500 | + </diagnostic> |
4501 | + </scalar_field> |
4502 | + <output/> |
4503 | + <stat/> |
4504 | + <convergence> |
4505 | + <include_in_convergence/> |
4506 | + </convergence> |
4507 | + <detectors> |
4508 | + <include_in_detectors/> |
4509 | + </detectors> |
4510 | + <steady_state> |
4511 | + <include_in_steady_state/> |
4512 | + </steady_state> |
4513 | + <consistent_interpolation/> |
4514 | + </prognostic> |
4515 | + </scalar_field> |
4516 | + </weighted_abscissa> |
4517 | + <adv_diff_source_term_interpolation> |
4518 | + <use_mass_lumping/> |
4519 | + </adv_diff_source_term_interpolation> |
4520 | + <moments> |
4521 | + <scalar_field name="Moment_0" rank="0"> |
4522 | + <diagnostic> |
4523 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4524 | + <mesh name="VelocityMesh"/> |
4525 | + <initial_condition name="WholeMesh"> |
4526 | + <python> |
4527 | + <string_value lines="20" type="code" language="python">def val(X, t): |
4528 | + if X[0] < 0.5: |
4529 | + return 0.6 |
4530 | + else: |
4531 | + return 0.4</string_value> |
4532 | + </python> |
4533 | + </initial_condition> |
4534 | + <output/> |
4535 | + <stat/> |
4536 | + <convergence> |
4537 | + <include_in_convergence/> |
4538 | + </convergence> |
4539 | + <detectors> |
4540 | + <include_in_detectors/> |
4541 | + </detectors> |
4542 | + <steady_state> |
4543 | + <include_in_steady_state/> |
4544 | + </steady_state> |
4545 | + <consistent_interpolation/> |
4546 | + </diagnostic> |
4547 | + </scalar_field> |
4548 | + <scalar_field name="Moment_1" rank="0"> |
4549 | + <diagnostic> |
4550 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4551 | + <mesh name="VelocityMesh"/> |
4552 | + <initial_condition name="WholeMesh"> |
4553 | + <python> |
4554 | + <string_value lines="20" type="code" language="python">def val(X, t): |
4555 | + if X[0] < 0.5: |
4556 | + return 1.0 |
4557 | + else: |
4558 | + return 1.5</string_value> |
4559 | + </python> |
4560 | + </initial_condition> |
4561 | + <output/> |
4562 | + <stat/> |
4563 | + <convergence> |
4564 | + <include_in_convergence/> |
4565 | + </convergence> |
4566 | + <detectors> |
4567 | + <include_in_detectors/> |
4568 | + </detectors> |
4569 | + <steady_state> |
4570 | + <include_in_steady_state/> |
4571 | + </steady_state> |
4572 | + <consistent_interpolation/> |
4573 | + </diagnostic> |
4574 | + </scalar_field> |
4575 | + <scalar_field name="Moment_2" rank="0"> |
4576 | + <diagnostic> |
4577 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4578 | + <mesh name="VelocityMesh"/> |
4579 | + <initial_condition name="WholeMesh"> |
4580 | + <constant> |
4581 | + <real_value rank="0">4.0</real_value> |
4582 | + </constant> |
4583 | + </initial_condition> |
4584 | + <output/> |
4585 | + <stat/> |
4586 | + <convergence> |
4587 | + <include_in_convergence/> |
4588 | + </convergence> |
4589 | + <detectors> |
4590 | + <include_in_detectors/> |
4591 | + </detectors> |
4592 | + <steady_state> |
4593 | + <include_in_steady_state/> |
4594 | + </steady_state> |
4595 | + <consistent_interpolation/> |
4596 | + </diagnostic> |
4597 | + </scalar_field> |
4598 | + <scalar_field name="Moment_3" rank="0"> |
4599 | + <diagnostic> |
4600 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4601 | + <mesh name="VelocityMesh"/> |
4602 | + <initial_condition name="WholeMesh"> |
4603 | + <constant> |
4604 | + <real_value rank="0">12.0</real_value> |
4605 | + </constant> |
4606 | + </initial_condition> |
4607 | + <output/> |
4608 | + <stat/> |
4609 | + <convergence> |
4610 | + <include_in_convergence/> |
4611 | + </convergence> |
4612 | + <detectors> |
4613 | + <include_in_detectors/> |
4614 | + </detectors> |
4615 | + <steady_state> |
4616 | + <include_in_steady_state/> |
4617 | + </steady_state> |
4618 | + <adaptivity_options> |
4619 | + <absolute_measure> |
4620 | + <scalar_field name="InterpolationErrorBound" rank="0"> |
4621 | + <prescribed> |
4622 | + <value name="WholeMesh"> |
4623 | + <constant> |
4624 | + <real_value rank="0">0.001</real_value> |
4625 | + </constant> |
4626 | + </value> |
4627 | + <output/> |
4628 | + <stat/> |
4629 | + <detectors> |
4630 | + <exclude_from_detectors/> |
4631 | + </detectors> |
4632 | + </prescribed> |
4633 | + </scalar_field> |
4634 | + <p_norm> |
4635 | + <integer_value rank="0">2</integer_value> |
4636 | + </p_norm> |
4637 | + </absolute_measure> |
4638 | + </adaptivity_options> |
4639 | + <consistent_interpolation/> |
4640 | + </diagnostic> |
4641 | + </scalar_field> |
4642 | + </moments> |
4643 | + <statistics/> |
4644 | + <population_balance_source_terms/> |
4645 | + <ill_conditioned_matrices> |
4646 | + <required_condition_number> |
4647 | + <real_value rank="0">1e-12</real_value> |
4648 | + </required_condition_number> |
4649 | + <set_source_to_zero/> |
4650 | + </ill_conditioned_matrices> |
4651 | + <minimum_weight> |
4652 | + <real_value rank="0">1e-10</real_value> |
4653 | + </minimum_weight> |
4654 | + </population_balance> |
4655 | + </material_phase> |
4656 | + <mesh_adaptivity> |
4657 | + <hr_adaptivity> |
4658 | + <period_in_timesteps> |
4659 | + <integer_value rank="0">20</integer_value> |
4660 | + </period_in_timesteps> |
4661 | + <maximum_number_of_nodes> |
4662 | + <integer_value rank="0">20000</integer_value> |
4663 | + </maximum_number_of_nodes> |
4664 | + <enable_gradation/> |
4665 | + <tensor_field name="MinimumEdgeLengths"> |
4666 | + <anisotropic_symmetric> |
4667 | + <constant> |
4668 | + <real_value symmetric="true" dim2="dim" shape="2 2" dim1="dim" rank="2">0.001 0.00 0.00 0.001</real_value> |
4669 | + </constant> |
4670 | + </anisotropic_symmetric> |
4671 | + </tensor_field> |
4672 | + <tensor_field name="MaximumEdgeLengths"> |
4673 | + <anisotropic_symmetric> |
4674 | + <constant> |
4675 | + <real_value symmetric="true" dim2="dim" shape="2 2" dim1="dim" rank="2">0.1 0.0 0.0 0.1</real_value> |
4676 | + </constant> |
4677 | + </anisotropic_symmetric> |
4678 | + </tensor_field> |
4679 | + <adapt_at_first_timestep> |
4680 | + <number_of_adapts> |
4681 | + <integer_value rank="0">4</integer_value> |
4682 | + </number_of_adapts> |
4683 | + </adapt_at_first_timestep> |
4684 | + <debug/> |
4685 | + </hr_adaptivity> |
4686 | + </mesh_adaptivity> |
4687 | +</fluidity_options> |
4688 | |
4689 | === added file 'tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.xml' |
4690 | --- tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.xml 1970-01-01 00:00:00 +0000 |
4691 | +++ tests/popbal_nonhomog2_2d_adapt/popbal_nonhomog2_2d_adapt.xml 2013-12-12 22:35:40 +0000 |
4692 | @@ -0,0 +1,46 @@ |
4693 | +<?xml version='1.0' encoding='utf-8'?> |
4694 | +<testproblem> |
4695 | + <name>Transient population balance using direct quadrature method of moments (N=2) for 2d mesh using P1 CG using ADAPTIVITY</name> |
4696 | + <owner userid="gb812"/> |
4697 | + <tags>flml</tags> |
4698 | + <problem_definition length="medium" nprocs="1"> |
4699 | + <command_line>fluidity popbal_nonhomog2_2d_adapt.flml</command_line> |
4700 | + </problem_definition> |
4701 | + <variables> |
4702 | + <variable name="solvers_converged" language="python">import os |
4703 | +files = os.listdir("./") |
4704 | +solvers_converged = not "matrixdump" in files and not "matrixdump.info" in files</variable> |
4705 | + <variable name="moment3_L2error_t_5s" language="python">from fluidity_tools import stat_parser |
4706 | +s = stat_parser("popbal_nonhomog2_2d.stat") |
4707 | +timestep=0.005 |
4708 | +t=5.0 |
4709 | +index_time_for_norm=((1.0/timestep)*t)-1 |
4710 | +moment3_L2error_t_5s = s["fluid"]["ScalarAbsoluteDifference"]["l2norm"][index_time_for_norm]</variable> |
4711 | + <variable name="moment3_L2error_t_20s" language="python">from fluidity_tools import stat_parser |
4712 | +s = stat_parser("popbal_nonhomog2_2d.stat") |
4713 | +timestep=0.005 |
4714 | +t=20.0 |
4715 | +index_time_for_norm=((1.0/timestep)*t)-1 |
4716 | +moment3_L2error_t_20s = s["fluid"]["ScalarAbsoluteDifference"]["l2norm"][index_time_for_norm]</variable> |
4717 | + <variable name="moment3_maxerror_t_5s" language="python">from fluidity_tools import stat_parser |
4718 | +s = stat_parser("popbal_nonhomog2_2d.stat") |
4719 | +timestep=0.005 |
4720 | +t=5.0 |
4721 | +index_time_for_norm=((1.0/timestep)*t)-1 |
4722 | +moment3_maxerror_t_5s = s["fluid"]["ScalarAbsoluteDifference"]["max"][index_time_for_norm]</variable> |
4723 | + <variable name="moment3_maxerror_t_20s" language="python">from fluidity_tools import stat_parser |
4724 | +s = stat_parser("popbal_nonhomog2_2d.stat") |
4725 | +timestep=0.005 |
4726 | +t=20.0 |
4727 | +index_time_for_norm=((1.0/timestep)*t)-1 |
4728 | +moment3_maxerror_t_20s = s["fluid"]["ScalarAbsoluteDifference"]["max"][index_time_for_norm]</variable> |
4729 | + </variables> |
4730 | + <pass_tests> |
4731 | + <test name="Solvers converged" language="python">assert(solvers_converged)</test> |
4732 | + <test name="moment3 L2error at 5s less than 0.0001" language="python">assert moment3_L2error_t_5s < 0.0001</test> |
4733 | + <test name="moment3 L2error at 20s less than 0.0001" language="python">assert moment3_L2error_t_20s < 0.0001</test> |
4734 | + <test name="moment3 maxerror at 5s less than 0.001" language="python">assert moment3_maxerror_t_5s < 0.001</test> |
4735 | + <test name="moment3 maxerror at 20s less than 0.001" language="python">assert moment3_maxerror_t_20s < 0.001</test> |
4736 | + </pass_tests> |
4737 | + <warn_tests/> |
4738 | +</testproblem> |
4739 | |
4740 | === added file 'tests/popbal_nonhomog2_2d_adapt/readme' |
4741 | --- tests/popbal_nonhomog2_2d_adapt/readme 1970-01-01 00:00:00 +0000 |
4742 | +++ tests/popbal_nonhomog2_2d_adapt/readme 2013-12-12 22:35:40 +0000 |
4743 | @@ -0,0 +1,13 @@ |
4744 | +quad=3 |
4745 | +2d |
4746 | +CG |
4747 | +p1 |
4748 | +unstructured grid cl=1/25 |
4749 | +lumped mass |
4750 | +time=0:0.005:20 |
4751 | +vel=0, transient external diffusion only. Diffusion 2 with a parabolic initial condition |
4752 | +only moment 3 compared to the analytical case |
4753 | +analytical case derived using separation of variables |
4754 | +N=2 |
4755 | +tests for L2error and max error at 5s and 20s |
4756 | +adaptivity |
4757 | |
4758 | === added directory 'tests/popbal_nonhomog2_2d_adapt/src' |
4759 | === added file 'tests/popbal_nonhomog2_2d_adapt/src/channel.geo' |
4760 | --- tests/popbal_nonhomog2_2d_adapt/src/channel.geo 1970-01-01 00:00:00 +0000 |
4761 | +++ tests/popbal_nonhomog2_2d_adapt/src/channel.geo 2013-12-12 22:35:40 +0000 |
4762 | @@ -0,0 +1,16 @@ |
4763 | +cl1 = 1.0/25.0; |
4764 | +Point(1) = {0, 0, 0, cl1}; |
4765 | +Point(2) = {1, 0, 0, cl1}; |
4766 | +Point(3) = {0, 1, 0, cl1}; |
4767 | +Point(4) = {1, 1, 0, cl1}; |
4768 | +Line(1) = {1, 2}; |
4769 | +Line(2) = {3, 4}; |
4770 | +Line(3) = {1, 3}; |
4771 | +Line(4) = {2, 4}; |
4772 | +Line Loop(5) = {1, 4, -2, -3}; |
4773 | +Ruled Surface(5) = {5}; |
4774 | +Physical Line(1) = {1}; |
4775 | +Physical Line(2) = {2}; |
4776 | +Physical Line(3) = {3}; |
4777 | +Physical Line(4) = {4}; |
4778 | +Physical Surface(6) = {5}; |
4779 | |
4780 | === added directory 'tests/popbal_nonhomog2_2d_cg_p1' |
4781 | === added file 'tests/popbal_nonhomog2_2d_cg_p1/Makefile' |
4782 | --- tests/popbal_nonhomog2_2d_cg_p1/Makefile 1970-01-01 00:00:00 +0000 |
4783 | +++ tests/popbal_nonhomog2_2d_cg_p1/Makefile 2013-12-12 22:35:40 +0000 |
4784 | @@ -0,0 +1,5 @@ |
4785 | +input: clean |
4786 | + gmsh -2 src/channel.geo -optimize -bin |
4787 | + |
4788 | +clean: |
4789 | + rm -f *.vtu *.pvtu fluidity.* *.s *.d.1 *.stat src/channel.msh |
4790 | |
4791 | === added file 'tests/popbal_nonhomog2_2d_cg_p1/popbal_nonhomog2_2d.flml' |
4792 | --- tests/popbal_nonhomog2_2d_cg_p1/popbal_nonhomog2_2d.flml 1970-01-01 00:00:00 +0000 |
4793 | +++ tests/popbal_nonhomog2_2d_cg_p1/popbal_nonhomog2_2d.flml 2013-12-12 22:35:40 +0000 |
4794 | @@ -0,0 +1,614 @@ |
4795 | +<?xml version='1.0' encoding='utf-8'?> |
4796 | +<fluidity_options> |
4797 | + <simulation_name> |
4798 | + <string_value lines="1">popbal_nonhomog2_2d</string_value> |
4799 | + </simulation_name> |
4800 | + <problem_type> |
4801 | + <string_value lines="1">fluids</string_value> |
4802 | + </problem_type> |
4803 | + <geometry> |
4804 | + <dimension> |
4805 | + <integer_value rank="0">2</integer_value> |
4806 | + </dimension> |
4807 | + <mesh name="CoordinateMesh"> |
4808 | + <from_file file_name="./src/channel"> |
4809 | + <format name="gmsh"/> |
4810 | + <stat> |
4811 | + <include_in_stat/> |
4812 | + </stat> |
4813 | + </from_file> |
4814 | + </mesh> |
4815 | + <mesh name="VelocityMesh"> |
4816 | + <from_mesh> |
4817 | + <mesh name="CoordinateMesh"/> |
4818 | + <mesh_shape> |
4819 | + <polynomial_degree> |
4820 | + <integer_value rank="0">1</integer_value> |
4821 | + </polynomial_degree> |
4822 | + </mesh_shape> |
4823 | + <mesh_continuity> |
4824 | + <string_value>continuous</string_value> |
4825 | + </mesh_continuity> |
4826 | + <stat> |
4827 | + <exclude_from_stat/> |
4828 | + </stat> |
4829 | + </from_mesh> |
4830 | + </mesh> |
4831 | + <quadrature> |
4832 | + <degree> |
4833 | + <integer_value rank="0">3</integer_value> |
4834 | + </degree> |
4835 | + </quadrature> |
4836 | + </geometry> |
4837 | + <io> |
4838 | + <dump_format> |
4839 | + <string_value>vtk</string_value> |
4840 | + </dump_format> |
4841 | + <dump_period> |
4842 | + <constant> |
4843 | + <real_value rank="0">1</real_value> |
4844 | + </constant> |
4845 | + </dump_period> |
4846 | + <output_mesh name="VelocityMesh"/> |
4847 | + <stat/> |
4848 | + </io> |
4849 | + <timestepping> |
4850 | + <current_time> |
4851 | + <real_value rank="0">0.0</real_value> |
4852 | + </current_time> |
4853 | + <timestep> |
4854 | + <real_value rank="0">0.005</real_value> |
4855 | + </timestep> |
4856 | + <finish_time> |
4857 | + <real_value rank="0">20</real_value> |
4858 | + </finish_time> |
4859 | + </timestepping> |
4860 | + <material_phase name="fluid"> |
4861 | + <vector_field name="Velocity" rank="1"> |
4862 | + <prescribed> |
4863 | + <mesh name="VelocityMesh"/> |
4864 | + <value name="WholeMesh"> |
4865 | + <constant> |
4866 | + <real_value shape="2" dim1="dim" rank="1">0 0</real_value> |
4867 | + </constant> |
4868 | + </value> |
4869 | + <output/> |
4870 | + <stat> |
4871 | + <include_in_stat/> |
4872 | + </stat> |
4873 | + <detectors> |
4874 | + <exclude_from_detectors/> |
4875 | + </detectors> |
4876 | + </prescribed> |
4877 | + </vector_field> |
4878 | + <scalar_field name="m3_analytical" rank="0"> |
4879 | + <prescribed> |
4880 | + <mesh name="VelocityMesh"/> |
4881 | + <value name="WholeMesh"> |
4882 | + <python> |
4883 | + <string_value lines="20" type="code" language="python">def val(X,t): |
4884 | + from math import exp, pi, cos |
4885 | + if (abs(t-round(t))<=0.01): |
4886 | + nu=0.001 |
4887 | + L=1.0 |
4888 | + n=100 |
4889 | + phi_n=0.0 |
4890 | + i=1 |
4891 | + while i<=n: |
4892 | + j=2*i |
4893 | + val = (1.0/j**2)*exp(-(nu*j**2*pi**2*t)/(L**2))*cos((j*pi*X[0])/L) |
4894 | + phi_n = phi_n + val |
4895 | + i=i+1 |
4896 | + phi_n = phi_n*(-4.0/pi**2) + 1.0/6.0 |
4897 | + return phi_n |
4898 | + else: |
4899 | + return 0.0</string_value> |
4900 | + </python> |
4901 | + </value> |
4902 | + <output/> |
4903 | + <stat/> |
4904 | + <detectors> |
4905 | + <exclude_from_detectors/> |
4906 | + </detectors> |
4907 | + </prescribed> |
4908 | + </scalar_field> |
4909 | + <scalar_field name="ScalarAbsoluteDifference" rank="0"> |
4910 | + <diagnostic field_name_b="m3_analytical" field_name_a="Moment_3"> |
4911 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4912 | + <mesh name="VelocityMesh"/> |
4913 | + <output/> |
4914 | + <stat/> |
4915 | + <convergence> |
4916 | + <exclude_from_convergence/> |
4917 | + </convergence> |
4918 | + <detectors> |
4919 | + <exclude_from_detectors/> |
4920 | + </detectors> |
4921 | + <steady_state> |
4922 | + <exclude_from_steady_state/> |
4923 | + </steady_state> |
4924 | + </diagnostic> |
4925 | + </scalar_field> |
4926 | + <population_balance name="DQMOM"> |
4927 | + <use_prognostic_field_initial_conditions/> |
4928 | + <abscissa> |
4929 | + <scalar_field name="Abscissa_0" rank="0"> |
4930 | + <diagnostic> |
4931 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4932 | + <mesh name="VelocityMesh"/> |
4933 | + <output/> |
4934 | + <stat/> |
4935 | + <convergence> |
4936 | + <include_in_convergence/> |
4937 | + </convergence> |
4938 | + <detectors> |
4939 | + <include_in_detectors/> |
4940 | + </detectors> |
4941 | + <steady_state> |
4942 | + <include_in_steady_state/> |
4943 | + </steady_state> |
4944 | + <consistent_interpolation/> |
4945 | + </diagnostic> |
4946 | + </scalar_field> |
4947 | + <scalar_field name="Abscissa_1" rank="0"> |
4948 | + <diagnostic> |
4949 | + <algorithm name="Internal" material_phase_support="multiple"/> |
4950 | + <mesh name="VelocityMesh"/> |
4951 | + <output/> |
4952 | + <stat/> |
4953 | + <convergence> |
4954 | + <include_in_convergence/> |
4955 | + </convergence> |
4956 | + <detectors> |
4957 | + <include_in_detectors/> |
4958 | + </detectors> |
4959 | + <steady_state> |
4960 | + <include_in_steady_state/> |
4961 | + </steady_state> |
4962 | + <consistent_interpolation/> |
4963 | + </diagnostic> |
4964 | + </scalar_field> |
4965 | + </abscissa> |
4966 | + <weights> |
4967 | + <scalar_field name="Weight_0" rank="0"> |
4968 | + <prognostic> |
4969 | + <mesh name="VelocityMesh"/> |
4970 | + <equation name="AdvectionDiffusion"/> |
4971 | + <spatial_discretisation> |
4972 | + <continuous_galerkin> |
4973 | + <stabilisation> |
4974 | + <no_stabilisation/> |
4975 | + </stabilisation> |
4976 | + <advection_terms/> |
4977 | + <mass_terms/> |
4978 | + </continuous_galerkin> |
4979 | + <conservative_advection> |
4980 | + <real_value rank="0">0.0</real_value> |
4981 | + </conservative_advection> |
4982 | + </spatial_discretisation> |
4983 | + <temporal_discretisation> |
4984 | + <theta> |
4985 | + <real_value rank="0">0.5</real_value> |
4986 | + </theta> |
4987 | + </temporal_discretisation> |
4988 | + <solver> |
4989 | + <iterative_method name="gmres"> |
4990 | + <restart> |
4991 | + <integer_value rank="0">30</integer_value> |
4992 | + </restart> |
4993 | + </iterative_method> |
4994 | + <preconditioner name="sor"/> |
4995 | + <relative_error> |
4996 | + <real_value rank="0">1e-7</real_value> |
4997 | + </relative_error> |
4998 | + <max_iterations> |
4999 | + <integer_value rank="0">1000</integer_value> |
5000 | + </max_iterations> |
Hi Gaurav -- given this was proposed more than a couple of months ago and looks to be in active development at the moment I'm setting it back to 'in progress'; if you get to the point you want to move for a review and merge, please do set back to 'needs review'.