1
by hhiester
deleting initialisation as none of tools are used any longer. |
1 |
! Copyright (C) 2006 Imperial College London and others.
|
2 |
!
|
|
3 |
! Please see the AUTHORS file in the main source directory for a full list
|
|
4 |
! of copyright holders.
|
|
5 |
!
|
|
6 |
! Prof. C Pain
|
|
7 |
! Applied Modelling and Computation Group
|
|
8 |
! Department of Earth Science and Engineering
|
|
9 |
! Imperial College London
|
|
10 |
!
|
|
2392
by tmb1
Changing isntances of Chris' person email address to the group |
11 |
! amcgsoftware@imperial.ac.uk
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
12 |
!
|
13 |
! This library is free software; you can redistribute it and/or
|
|
14 |
! modify it under the terms of the GNU Lesser General Public
|
|
15 |
! License as published by the Free Software Foundation,
|
|
16 |
! version 2.1 of the License.
|
|
17 |
!
|
|
18 |
! This library is distributed in the hope that it will be useful,
|
|
19 |
! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 |
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21 |
! Lesser General Public License for more details.
|
|
22 |
!
|
|
23 |
! You should have received a copy of the GNU Lesser General Public
|
|
24 |
! License along with this library; if not, write to the Free Software
|
|
25 |
! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
26 |
! USA
|
|
27 |
#include "fdebug.h"
|
|
28 |
||
29 |
module field_equations_cv |
|
30 |
!!< This module contains the assembly subroutines for advection
|
|
31 |
!!< using control volumes
|
|
32 |
use fields |
|
33 |
use sparse_matrices_fields |
|
34 |
use sparsity_patterns_meshes |
|
35 |
use state_module |
|
36 |
use spud |
|
37 |
use cv_shape_functions |
|
38 |
use cv_faces |
|
39 |
use cvtools |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
40 |
use cv_fields |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
41 |
use cv_upwind_values |
42 |
use cv_face_values |
|
43 |
use diagnostic_fields, only: calculate_diagnostic_variable |
|
44 |
use cv_options |
|
45 |
use diagnostic_variables, only: field_tag |
|
46 |
use boundary_conditions |
|
47 |
use boundary_conditions_from_options |
|
48 |
use divergence_matrix_cv, only: assemble_divergence_matrix_cv |
|
108
by maddison
Bye bye FLComms |
49 |
use global_parameters, only: OPTION_PATH_LEN |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
50 |
use fefields, only: compute_cv_mass |
1403
by skramer
Actually add the "higher_order_lumping" as an "mg" option in the schema. |
51 |
use petsc_solve_state_module |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
52 |
use transform_elements, only: transform_cvsurf_to_physical, & |
53 |
transform_cvsurf_facet_to_physical
|
|
54 |
use parallel_tools, only: getprocno |
|
55 |
use halos |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
56 |
use field_options |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
57 |
use state_fields_module |
3930.1.4
by Brendan Tollit
Remove not required code that was added to this branch |
58 |
use porous_media |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
59 |
|
60 |
implicit none
|
|
61 |
||
62 |
private
|
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
63 |
public :: solve_field_eqn_cv, field_equations_cv_check_options, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
64 |
initialise_advection_convergence, coupled_cv_field_eqn, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
65 |
assemble_advectiondiffusion_m_cv
|
66 |
||
67 |
integer, dimension(:), allocatable, save :: conv_unit |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
68 |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
69 |
!! This allows a reference between the field and the file its meant to be
|
70 |
!! writing to.
|
|
71 |
character(len=OPTION_PATH_LEN), dimension(:), allocatable, save :: sfield_list |
|
72 |
||
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
73 |
! are we moving the mesh?
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
74 |
logical :: move_mesh = .false. |
75 |
! are we including density?
|
|
76 |
logical :: include_density = .false. |
|
77 |
! are we including a souce?
|
|
78 |
logical :: include_source = .false. |
|
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
79 |
! Add source directly to the right hand side?
|
80 |
logical :: add_src_directly_to_rhs = .false. |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
81 |
! are we including an absorption?
|
82 |
logical :: include_absorption = .false. |
|
83 |
! are we including diffusion?
|
|
84 |
logical :: include_diffusion = .false. |
|
85 |
! are we including advection?
|
|
86 |
logical :: include_advection = .true. |
|
87 |
! are we including mass?
|
|
88 |
logical :: include_mass = .true. |
|
89 |
! are we assembling particular matrices?
|
|
90 |
! advection?
|
|
91 |
logical :: assemble_advection_matrix = .true. |
|
92 |
! diffusion?
|
|
93 |
logical :: assemble_diffusion = .false. |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
94 |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
95 |
contains
|
96 |
!************************************************************************
|
|
97 |
! solution wrapping subroutines
|
|
98 |
subroutine solve_field_eqn_cv(field_name, state, global_it) |
|
99 |
!!< Construct and solve the advection-diffusion equation for the given
|
|
100 |
!!< field using control volumes.
|
|
101 |
||
102 |
!! Name of the field to be solved for.
|
|
103 |
character(len=*), intent(in) :: field_name |
|
104 |
!! Collection of fields defining system state.
|
|
105 |
type(state_type), dimension(:), intent(inout) :: state |
|
106 |
! global iteration number - passed in so it can be output to file
|
|
107 |
integer, intent(in) :: global_it |
|
108 |
||
109 |
! Field to be solved for (plus its old and globally iterated versions)
|
|
110 |
type(scalar_field), pointer :: tfield, oldtfield, it_tfield |
|
111 |
! Density fields associated with tfield's equation (i.e. if its not pure advection)
|
|
112 |
type(scalar_field), pointer :: tdensity, oldtdensity |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
113 |
! Coordinate field(s)
|
114 |
type(vector_field), pointer :: x, x_old, x_new |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
115 |
type(vector_field) :: x_tfield |
116 |
||
117 |
type(tensor_field), pointer :: diffusivity |
|
118 |
type(scalar_field), pointer :: source, absorption |
|
119 |
||
120 |
! Change in tfield over one timestep.
|
|
121 |
type(scalar_field) :: delta_tfield |
|
122 |
||
123 |
! LHS equation matrix.
|
|
124 |
type(csr_matrix) :: M |
|
125 |
! Advection matrix
|
|
126 |
type(csr_matrix) :: A_m |
|
127 |
! Diffusion matrix
|
|
128 |
type(csr_matrix) :: D_m |
|
129 |
! sparsity structure to construct the matrices with
|
|
130 |
type(csr_sparsity), pointer :: mesh_sparsity_1, mesh_sparsity, & |
|
131 |
mesh_sparsity_x, grad_m_t_sparsity |
|
132 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
133 |
! Right hand side vector, cv mass matrix,
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
134 |
! locally iterated field (for advection iterations)
|
135 |
! and local old field (for subcycling)
|
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
136 |
type(scalar_field), pointer :: t_cvmass, q_cvmass, t_abs_src_cvmass |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
137 |
type(scalar_field) :: t_cvmass_old, t_cvmass_new |
138 |
type(scalar_field) :: rhs, cvmass, advit_tfield, l_old_tfield |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
139 |
! Diffusion contribution to rhs
|
140 |
type(scalar_field) :: diff_rhs |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
141 |
|
3930.1.4
by Brendan Tollit
Remove not required code that was added to this branch |
142 |
! Porosity field
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
143 |
type(scalar_field) :: porosity_theta |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
144 |
type(scalar_field), target :: t_cvmass_with_porosity |
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
145 |
logical :: include_porosity |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
146 |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
147 |
! local copy of option_path for solution field
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
148 |
character(len=OPTION_PATH_LEN) :: option_path, tdensity_option_path |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
149 |
|
150 |
! number of advection iterations and subcycles
|
|
151 |
integer :: adv_iterations, no_subcycles |
|
152 |
! iterators
|
|
153 |
integer :: adv_it, sub |
|
154 |
! time (to output to file), timestep, iterations tolerance, subcycling timestep
|
|
155 |
real :: time, dt, error, adv_tolerance, sub_dt |
|
156 |
||
157 |
! degree of quadrature to use on each control volume face
|
|
158 |
integer :: quaddegree |
|
159 |
! control volume face information
|
|
160 |
type(cv_faces_type) :: cvfaces |
|
161 |
! control volume shape function for volume and boundary
|
|
162 |
type(element_type) :: u_cvshape, u_cvbdyshape |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
163 |
type(element_type) :: ug_cvshape, ug_cvbdyshape |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
164 |
type(element_type) :: x_cvshape, x_cvbdyshape, & |
165 |
x_cvshape_full, x_cvbdyshape_full |
|
166 |
! t_cvshape is the element with reduced numbers of derivatives
|
|
167 |
! taken across the control volume faces
|
|
168 |
! t_cvshape_full contains the derivatives with respect to the parent
|
|
169 |
! elements canonical coordinates evaluated at the control volume faces
|
|
170 |
! t_cvbdyshape_full is the same but on the boundary
|
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
171 |
type(element_type) :: t_cvshape, t_cvshape_full, diff_cvshape_full, & |
172 |
t_cvbdyshape_full, diff_cvbdyshape_full |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
173 |
|
174 |
! options wrappers for tfield and tdensity
|
|
175 |
type(cv_options_type) :: tfield_options, tdensity_options |
|
176 |
||
177 |
! a dummy density in case we're solving for Advection
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
178 |
type(scalar_field), pointer :: dummyscalar |
179 |
type(vector_field), pointer :: dummyvector |
|
180 |
type(tensor_field), pointer :: dummytensor |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
181 |
! somewhere to put strings temporarily
|
182 |
character(len=FIELD_NAME_LEN) :: tmpstring |
|
183 |
! what equation type are we solving for?
|
|
184 |
integer :: equation_type |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
185 |
! success indicator
|
186 |
integer :: stat |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
187 |
! the courant number field
|
188 |
type(scalar_field) :: cfl_no |
|
189 |
! nonlinear and grid velocities
|
|
190 |
type(vector_field), pointer :: nu, ug |
|
191 |
! advection velocity
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
192 |
type(vector_field), pointer :: advu |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
193 |
!! Gravitational sinking term
|
194 |
type(scalar_field), pointer :: sink |
|
195 |
!! Direction of gravity
|
|
196 |
type(vector_field), pointer :: gravity |
|
197 |
||
198 |
! assume explicitness?
|
|
199 |
logical :: explicit |
|
200 |
! if we're subcycling how fast can we go?
|
|
201 |
real :: max_sub_cfl, max_cfl |
|
202 |
||
203 |
! temporary hack to get around compiler failure to construct arrays of characters
|
|
204 |
character(len=OPTION_PATH_LEN), dimension(1) :: option_path_array |
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
205 |
character(len=OPTION_PATH_LEN), dimension(1) :: tdensity_option_path_array |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
206 |
|
207 |
ewrite(2,*) 'in solve_field_eqn_cv' |
|
208 |
ewrite(2,*) 'solving for '//field_name//' in state '//trim(state(1)%name) |
|
209 |
||
210 |
! extract lots of fields:
|
|
211 |
! the actual thing we're trying to solve for
|
|
212 |
tfield=>extract_scalar_field(state(1), trim(field_name)) |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
213 |
ewrite_minmax(tfield) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
214 |
option_path=tfield%option_path |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
215 |
! its previous timelevel - if we're doing more than one iteration per timestep!
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
216 |
oldtfield=>extract_scalar_field(state(1), "Old"//trim(field_name)) |
217 |
! because fluidity resets tfield to oldtfield at the start of every
|
|
218 |
! global iteration we need to undo this so that the control volume faces
|
|
219 |
! are discretised using the most up to date values
|
|
220 |
! therefore extract the iterated values:
|
|
221 |
it_tfield=>extract_scalar_field(state(1), "Iterated"//trim(field_name)) |
|
222 |
! and set tfield to them:
|
|
223 |
call set(tfield, it_tfield) |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
224 |
ewrite_minmax(tfield) |
225 |
ewrite_minmax(oldtfield) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
226 |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
227 |
! allocate dummy scalar in case density/source/absorption fields aren't needed (this can be a constant field!)
|
228 |
allocate(dummyscalar) |
|
229 |
call allocate(dummyscalar, tfield%mesh, name="DummyScalar", field_type=FIELD_TYPE_CONSTANT) |
|
230 |
call zero(dummyscalar) |
|
231 |
dummyscalar%option_path = " " |
|
232 |
||
233 |
! allocate dummy vector in case the velocity field isn't needed (this can be a constant field!)
|
|
234 |
allocate(dummyvector) |
|
235 |
call allocate(dummyvector, mesh_dim(tfield), tfield%mesh, name="DummyVector", field_type=FIELD_TYPE_CONSTANT) |
|
236 |
call zero(dummyvector) |
|
237 |
dummyvector%option_path = " " |
|
238 |
||
239 |
! allocate dummy tensor in case diffusivity field isn't needed (this can be a constant field!)
|
|
240 |
allocate(dummytensor) |
|
241 |
call allocate(dummytensor, tfield%mesh, name="DummyTensor", field_type=FIELD_TYPE_CONSTANT) |
|
242 |
call zero(dummytensor) |
|
243 |
dummytensor%option_path = " " |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
244 |
|
245 |
! find out equation type and hence if density is needed or not
|
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
246 |
equation_type=equation_type_index(trim(option_path)) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
247 |
include_density = .false. |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
248 |
select case(equation_type) |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
249 |
case(FIELD_EQUATION_ADVECTIONDIFFUSION) |
1107
by dp204
add density to adv diff eq only works for cv |
250 |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
251 |
! density not needed so use a constant field for assembly
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
252 |
tdensity=>dummyscalar |
253 |
oldtdensity=>dummyscalar |
|
1107
by dp204
add density to adv diff eq only works for cv |
254 |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
255 |
case(FIELD_EQUATION_CONSERVATIONOFMASS, FIELD_EQUATION_REDUCEDCONSERVATIONOFMASS, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
256 |
FIELD_EQUATION_INTERNALENERGY, FIELD_EQUATION_HEATTRANSFER ) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
257 |
call get_option(trim(option_path)//'/prognostic/equation[0]/density[0]/name', & |
258 |
tmpstring) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
259 |
include_density = .true. |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
260 |
! density needed so extract the type specified in the input
|
261 |
! ?? are there circumstances where this should be "Iterated"... need to be
|
|
262 |
! careful with priority ordering
|
|
263 |
tdensity=>extract_scalar_field(state(1), trim(tmpstring)) |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
264 |
ewrite_minmax(tdensity) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
265 |
! halo exchange? - not currently necessary when suboptimal halo exchange if density
|
266 |
! is solved for with this subroutine and the correct priority ordering.
|
|
267 |
oldtdensity=>extract_scalar_field(state(1), "Old"//trim(tmpstring)) |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
268 |
ewrite_minmax(oldtdensity) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
269 |
end select
|
270 |
||
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
271 |
! get the density option path
|
272 |
if(have_option(trim(option_path)//'/prognostic/equation[0]/density[0]/discretisation_options')) then |
|
273 |
tdensity_option_path = trim(option_path)//'/prognostic/equation[0]/density[0]/discretisation_options' |
|
274 |
else
|
|
275 |
tdensity_option_path = trim(tdensity%option_path) |
|
276 |
end if
|
|
277 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
278 |
! now we can get the options for these fields
|
279 |
! handily wrapped in a new type...
|
|
1948
by cwilson
1d control volumes for the 1d simple advection example. Unlike with other simplex elements this defaults to a locally_bound_upwind_value as projecting really makes no sense if no upwind scheme is selected. Ideally it would actually default to a pseudo_structured_upwind_value but this isn't available with periodic, works in nonperiodic 1d though - as apparently do all the other upwind schemes. |
280 |
tfield_options=get_cv_options(tfield%option_path, tfield%mesh%shape%numbering%family, mesh_dim(tfield)) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
281 |
if(include_density) then |
1948
by cwilson
1d control volumes for the 1d simple advection example. Unlike with other simplex elements this defaults to a locally_bound_upwind_value as projecting really makes no sense if no upwind scheme is selected. Ideally it would actually default to a pseudo_structured_upwind_value but this isn't available with periodic, works in nonperiodic 1d though - as apparently do all the other upwind schemes. |
282 |
tdensity_options=get_cv_options(tdensity_option_path, tdensity%mesh%shape%numbering%family, mesh_dim(tdensity), coefficient_field=.true.) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
283 |
end if
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
284 |
|
285 |
! extract fields from state
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
286 |
! the base Coordinate field
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
287 |
x=>extract_vector_field(state(1), "Coordinate") |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
288 |
! the Coordinate field on the same mesh as tfield
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
289 |
x_tfield=get_coordinate_field(state(1), tfield%mesh) |
290 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
291 |
! are we including the mass (generally yes)?
|
292 |
include_mass = .not.have_option(trim(tfield%option_path)//"/prognostic/spatial_discretisation/control_volumes/mass_terms/exclude_mass_terms") |
|
293 |
||
294 |
! are we inclulding advection (generally yes)?
|
|
295 |
include_advection = .not.(tfield_options%facevalue==CV_FACEVALUE_NONE) |
|
296 |
if(include_advection) then |
|
297 |
nu=>extract_vector_field(state(1), "NonlinearVelocity") |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
298 |
ewrite_minmax(nu) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
299 |
! find relative velocity
|
300 |
allocate(advu) |
|
301 |
call allocate(advu, nu%dim, nu%mesh, "AdvectionVelocity") |
|
302 |
call set(advu, nu) |
|
1979
by jhill1
Minor mods to the last commit. Moved option under the face value choice - only available under Finite_Element for now - and renamed to make it clearer as to what the option is meant to do. Added brief doc to schema. Thanks to Cian for suggestions. Loosen tolerances on sinking_velocity_cv which passes fine on my laptop, but not buildbot. |
303 |
if (have_option(trim(tfield%option_path)// & |
304 |
"/prognostic/spatial_discretisation/control_volumes/"// & |
|
305 |
"face_value::FiniteElement/only_sinking_velocity")) then |
|
1978
by jhill1
Adding options to CG and CV adv-diff to ignore velocity, but keep sinking velocity, so I can run a psuedo-1D column with biology and adaptivity, and conserve biology. Adapted the sinking_velocity_cv test to check this and adding a adaptive biology conservation test. The CG version is untested as yet. |
306 |
call zero(advu) |
307 |
ewrite(2,*) "Removing velocity from ", trim(field_name) |
|
308 |
end if
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
309 |
! add in sinking velocity
|
310 |
sink=>extract_scalar_field(state(1), trim(field_name)//"SinkingVelocity"& |
|
311 |
&, stat=stat) |
|
312 |
if(stat==0) then |
|
313 |
gravity=>extract_vector_field(state(1), "GravityDirection") |
|
3606
by Christian Jacobs
Corrected a typo in Field_Equations_CV.F90. |
314 |
! this may perform a "remap" internally from CoordinateMesh to VelocityMesh
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
315 |
call addto(advu, gravity, scale=sink) |
316 |
end if
|
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
317 |
ewrite_minmax(advu) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
318 |
else
|
319 |
ewrite(2,*) 'Excluding advection' |
|
320 |
advu => dummyvector |
|
321 |
if(has_scalar_field(state(1), trim(field_name)//"SinkingVelocity")) then |
|
1979
by jhill1
Minor mods to the last commit. Moved option under the face value choice - only available under Finite_Element for now - and renamed to make it clearer as to what the option is meant to do. Added brief doc to schema. Thanks to Cian for suggestions. Loosen tolerances on sinking_velocity_cv which passes fine on my laptop, but not buildbot. |
322 |
ewrite(-1,*) "No advection in "//trim(field_name) |
323 |
FLExit("But you have a sinking velocity on. Can't have that") |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
324 |
end if
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
325 |
end if
|
326 |
||
327 |
! do we have a diffusivity - this will control whether we construct an auxiliary
|
|
328 |
! eqn or not (if BassiRebay is selected) or whether we construct gradients (if ElementGradient
|
|
329 |
! is selected)
|
|
330 |
diffusivity=>extract_tensor_field(state(1), trim(field_name)//"Diffusivity", stat=stat) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
331 |
include_diffusion = (stat==0).and.(tfield_options%diffusionscheme/=CV_DIFFUSION_NONE) |
332 |
if(.not.include_diffusion) then |
|
333 |
diffusivity => dummytensor |
|
334 |
else
|
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
335 |
ewrite_minmax(diffusivity) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
336 |
end if
|
337 |
||
338 |
! do we have a source?
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
339 |
source=>extract_scalar_field(state(1), trim(field_name)//"Source", stat=stat) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
340 |
include_source = (stat==0) |
341 |
if(.not.include_source) then |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
342 |
source=>dummyscalar |
343 |
else
|
|
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
344 |
add_src_directly_to_rhs = have_option(trim(source%option_path)//'/diagnostic/add_directly_to_rhs') |
345 |
||
346 |
if (add_src_directly_to_rhs) then |
|
347 |
ewrite(2, *) "Adding Source field directly to the right hand side" |
|
348 |
assert(node_count(source) == node_count(tfield)) |
|
349 |
end if
|
|
350 |
||
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
351 |
ewrite_minmax(source) |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
352 |
end if
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
353 |
|
354 |
! do we have an absorption?
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
355 |
absorption=>extract_scalar_field(state(1), trim(field_name)//"Absorption", stat=stat) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
356 |
include_absorption = (stat==0) |
357 |
if(.not.include_absorption) then |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
358 |
absorption=>dummyscalar |
359 |
else
|
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
360 |
ewrite_minmax(absorption) |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
361 |
end if
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
362 |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
363 |
! create control volume shape functions
|
364 |
call get_option("/geometry/quadrature/controlvolume_surface_degree", & |
|
365 |
quaddegree, default=1) |
|
366 |
cvfaces=find_cv_faces(vertices=ele_vertices(tfield, 1), & |
|
367 |
dimension=mesh_dim(tfield), & |
|
368 |
polydegree=tfield%mesh%shape%degree, & |
|
369 |
quaddegree=quaddegree) |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
370 |
x_cvshape=make_cv_element_shape(cvfaces, x%mesh%shape) |
371 |
t_cvshape=make_cv_element_shape(cvfaces, tfield%mesh%shape) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
372 |
if(include_advection) then |
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
373 |
u_cvshape=make_cv_element_shape(cvfaces, nu%mesh%shape) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
374 |
else
|
375 |
u_cvshape=t_cvshape |
|
376 |
call incref(u_cvshape) |
|
377 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
378 |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
379 |
x_cvbdyshape=make_cvbdy_element_shape(cvfaces, x%mesh%faces%shape) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
380 |
if(include_advection) then |
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
381 |
u_cvbdyshape=make_cvbdy_element_shape(cvfaces, nu%mesh%faces%shape) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
382 |
else
|
383 |
u_cvbdyshape=x_cvbdyshape |
|
384 |
call incref(u_cvbdyshape) |
|
385 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
386 |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
387 |
if(include_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_ELEMENTGRADIENT)) then |
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
388 |
x_cvshape_full=make_cv_element_shape(cvfaces, x%mesh%shape, & |
389 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
|
390 |
t_cvshape_full=make_cv_element_shape(cvfaces, tfield%mesh%shape, & |
|
391 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
|
392 |
diff_cvshape_full=make_cv_element_shape(cvfaces, diffusivity%mesh%shape, & |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
393 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
394 |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
395 |
x_cvbdyshape_full=make_cvbdy_element_shape(cvfaces, x%mesh%faces%shape, & |
396 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
|
397 |
t_cvbdyshape_full=make_cvbdy_element_shape(cvfaces, tfield%mesh%shape, & |
|
398 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
|
399 |
diff_cvbdyshape_full=make_cvbdy_element_shape(cvfaces, diffusivity%mesh%shape, & |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
400 |
type=ELEMENT_CONTROLVOLUME_SURFACE_BODYDERIVATIVES) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
401 |
else
|
402 |
x_cvshape_full=x_cvshape |
|
403 |
t_cvshape_full=t_cvshape |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
404 |
diff_cvshape_full=t_cvshape |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
405 |
x_cvbdyshape_full=x_cvbdyshape |
406 |
t_cvbdyshape_full=x_cvbdyshape |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
407 |
diff_cvbdyshape_full=x_cvbdyshape |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
408 |
|
409 |
call incref(x_cvshape_full) |
|
410 |
call incref(t_cvshape_full) |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
411 |
call incref(diff_cvshape_full) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
412 |
call incref(x_cvbdyshape_full) |
413 |
call incref(t_cvbdyshape_full) |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
414 |
call incref(diff_cvbdyshape_full) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
415 |
end if
|
416 |
||
417 |
! is this explicit?
|
|
418 |
explicit=have_option(trim(option_path)//"/prognostic/explicit") |
|
419 |
! find the timestep
|
|
420 |
call get_option("/timestepping/timestep", dt) |
|
421 |
call get_option("/timestepping/current_time", time) ! so it can be output in the convergence file |
|
422 |
||
423 |
! allocate and retrieve the cfl no. if necessary
|
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
424 |
option_path_array(1) = trim(option_path) ! temporary hack for compiler failure |
425 |
tdensity_option_path_array(1) = tdensity_option_path |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
426 |
call cv_disc_get_cfl_no(option_path_array, & |
427 |
state(1), tfield%mesh, cfl_no, & |
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
428 |
tdensity_option_path_array) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
429 |
|
430 |
! get the mesh sparsity for the matrices
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
431 |
if(include_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
432 |
! in this case we need to extend the sparsity to second order
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
433 |
mesh_sparsity => get_csr_sparsity_secondorder(state, tfield%mesh, diffusivity%mesh) |
434 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
435 |
! except for some things we still need a first order sparsity (upwind value matrices for instance)
|
436 |
! although note that this may get modified when periodic depending on the face value scheme
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
437 |
mesh_sparsity_1 => get_csr_sparsity_firstorder(state, tfield%mesh, tfield%mesh) |
438 |
if(.not.(tfield%mesh==diffusivity%mesh)) then |
|
439 |
if(tfield%mesh%shape%degree>1) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
440 |
FLExit("To have a different diffusivity mesh the field must be at most P1") |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
441 |
elseif(diffusivity%mesh%shape%degree>tfield%mesh%shape%degree) then |
1695
by cwilson
A commit full of things that don't work yet... |
442 |
FLExit("The diffusivity mesh must be of a lower degree than the field") |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
443 |
end if
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
444 |
|
445 |
! we also need a first order sparsity using the diffusivity mesh for the assembly of the auxilliary eqn
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
446 |
grad_m_t_sparsity => get_csr_sparsity_firstorder(state, tfield%mesh, diffusivity%mesh) |
447 |
else
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
448 |
! no difference between the meshes so this is safe (and faster)
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
449 |
grad_m_t_sparsity => mesh_sparsity_1 |
450 |
end if
|
|
451 |
|
|
452 |
else
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
453 |
! no BassiRebay diffusion so only a first order sparsity is needed... woo!
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
454 |
mesh_sparsity => get_csr_sparsity_firstorder(state, tfield%mesh, tfield%mesh) |
455 |
grad_m_t_sparsity => mesh_sparsity |
|
456 |
mesh_sparsity_1 => mesh_sparsity |
|
457 |
end if
|
|
458 |
||
459 |
if(mesh_periodic(tfield)) then |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
460 |
! we have a periodic mesh and depending on the upwind value scheme
|
461 |
! we may want to modify the sparsity for the upwind value matrices
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
462 |
if((tfield_options%upwind_scheme==CV_UPWINDVALUE_PROJECT_POINT).or.& |
463 |
(tfield_options%upwind_scheme==CV_UPWINDVALUE_PROJECT_GRAD)) then |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
464 |
! yup, we need an unperiodic sparsity
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
465 |
mesh_sparsity_x => get_csr_sparsity_firstorder(state, x_tfield%mesh, x_tfield%mesh) |
466 |
else
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
467 |
! periodic sparsity is fine
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
468 |
mesh_sparsity_x => mesh_sparsity_1 |
469 |
end if
|
|
470 |
else
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
471 |
! not periodic so who cares
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
472 |
mesh_sparsity_x => mesh_sparsity_1 |
473 |
end if
|
|
474 |
||
475 |
if(.not.explicit) then |
|
476 |
! allocate the lhs matrix
|
|
477 |
call allocate(M, mesh_sparsity, name=trim(field_name)//"Matrix") |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
478 |
call zero(M) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
479 |
|
480 |
! allocate the advection matrix
|
|
481 |
call allocate(A_m, mesh_sparsity, name=trim(field_name)//"AdvectionMatrix") |
|
482 |
call zero(A_m) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
483 |
else
|
484 |
if(.not.include_mass) then |
|
485 |
FLExit("Can't be explicit and exclude the mass terms.") |
|
486 |
end if
|
|
487 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
488 |
! allocate a local cvmass field because it will get modified by bc etc.
|
489 |
call allocate(cvmass, tfield%mesh, name=trim(field_name)//"CVMass") |
|
490 |
call zero(cvmass) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
491 |
end if
|
492 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
493 |
if(include_diffusion) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
494 |
call allocate(D_m, sparsity=mesh_sparsity, name=trim(field_name)//"AuxiliaryMatrix") |
495 |
call zero(D_m) |
|
496 |
||
497 |
call allocate(diff_rhs, tfield%mesh, name=trim(field_name)//"DiffusionRHS") |
|
498 |
call zero(diff_rhs) |
|
499 |
end if
|
|
500 |
||
501 |
! allocate the rhs of the equation
|
|
502 |
call allocate(rhs, tfield%mesh, name=trim(field_name)//"RHS") |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
503 |
|
504 |
! are we including a porosity coefficient on the time term?
|
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
505 |
if (have_option(trim(complete_field_path(tfield%option_path))//'/porosity')) then |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
506 |
include_porosity = .true. |
3900.1.19
by Brendan Tollit
Small change to Field_Equations_CV.F90 by adding a check that |
507 |
|
3930.1.4
by Brendan Tollit
Remove not required code that was added to this branch |
508 |
! get the porosity theta averaged field - this will allocate it
|
509 |
call form_porosity_theta(porosity_theta, state(1), & |
|
510 |
&option_path = trim(complete_field_path(tfield%option_path))//'/porosity') |
|
511 |
||
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
512 |
call allocate(t_cvmass_with_porosity, tfield%mesh, name="CVMassWithPorosity") |
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
513 |
call compute_cv_mass(x, t_cvmass_with_porosity, porosity_theta) |
514 |
ewrite_minmax(t_cvmass_with_porosity) |
|
515 |
||
516 |
call deallocate(porosity_theta) |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
517 |
else
|
518 |
include_porosity = .false. |
|
519 |
end if
|
|
520 |
||
521 |
! find the cv mass that is used for the absorption and source terms
|
|
522 |
t_abs_src_cvmass => get_cv_mass(state, tfield%mesh) |
|
523 |
ewrite_minmax(t_abs_src_cvmass) |
|
524 |
||
525 |
! find the cv mass that is used for the time term derivative
|
|
526 |
if (include_porosity) then |
|
527 |
t_cvmass => t_cvmass_with_porosity |
|
528 |
else
|
|
529 |
t_cvmass => t_abs_src_cvmass |
|
530 |
end if
|
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
531 |
ewrite_minmax(t_cvmass) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
532 |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
533 |
move_mesh = have_option("/mesh_adaptivity/mesh_movement") |
534 |
if(move_mesh) then |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
535 |
if(.not.include_advection) then |
536 |
FLExit("Moving the mesh but not including advection is not possible yet.") |
|
537 |
end if
|
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
538 |
if (include_porosity) then |
539 |
FLExit("Moving mesh not set up to work when including porosity") |
|
540 |
end if
|
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
541 |
ewrite(2,*) "Moving mesh." |
542 |
x_old=>extract_vector_field(state(1), "OldCoordinate") |
|
543 |
x_new=>extract_vector_field(state(1), "IteratedCoordinate") |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
544 |
call allocate(t_cvmass_old, tfield%mesh, name=trim(field_name)//"OldCVMass") |
545 |
call allocate(t_cvmass_new, tfield%mesh, name=trim(field_name)//"NewCVMass") |
|
546 |
||
547 |
call compute_cv_mass(x_old, t_cvmass_old) |
|
548 |
call compute_cv_mass(x_new, t_cvmass_new) |
|
549 |
ewrite_minmax(t_cvmass_old) |
|
550 |
ewrite_minmax(t_cvmass_new) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
551 |
|
552 |
ug=>extract_vector_field(state(1), "GridVelocity") |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
553 |
ewrite_minmax(ug) |
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
554 |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
555 |
ug_cvshape=make_cv_element_shape(cvfaces, ug%mesh%shape) |
556 |
ug_cvbdyshape=make_cvbdy_element_shape(cvfaces, ug%mesh%faces%shape) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
557 |
|
558 |
else
|
|
559 |
ewrite(2,*) "Not moving mesh." |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
560 |
ug_cvshape=u_cvshape |
561 |
ug_cvbdyshape=u_cvbdyshape |
|
562 |
call incref(ug_cvshape) |
|
563 |
call incref(ug_cvbdyshape) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
564 |
end if
|
565 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
566 |
if(include_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
567 |
if(.not.(tfield%mesh==diffusivity%mesh)) then |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
568 |
q_cvmass => get_cv_mass(state, diffusivity%mesh) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
569 |
else
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
570 |
q_cvmass => t_cvmass |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
571 |
end if
|
572 |
else
|
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
573 |
q_cvmass => t_cvmass |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
574 |
end if
|
575 |
||
576 |
! allocate a field to store the locally iterated values in
|
|
577 |
call allocate(advit_tfield, tfield%mesh, name="AdvIterated"//trim(field_name)) |
|
578 |
! allocate a field to use as the local old field for subcycling
|
|
579 |
call allocate(l_old_tfield, tfield%mesh, name="LocalOld"//trim(field_name)) |
|
580 |
||
581 |
! allocate a field to store the change between the old and new values
|
|
582 |
call allocate(delta_tfield, tfield%mesh, name="Delta_"//trim(field_name)) |
|
583 |
call zero(delta_tfield) ! Impose zero initial guess. |
|
584 |
! Ensure delta_tfield inherits options from tfield for solver
|
|
585 |
delta_tfield%option_path = option_path |
|
586 |
||
587 |
! find out how many iterations we'll be doing
|
|
588 |
call get_option(trim(option_path)//"/prognostic/temporal_discretisation& |
|
589 |
&/control_volumes/number_advection_iterations", & |
|
590 |
adv_iterations, default=1) |
|
591 |
call get_option(trim(option_path)//"/prognostic/temporal_discretisation& |
|
592 |
&/control_volumes/number_advection_iterations/tolerance", & |
|
593 |
adv_tolerance, default=0.0) |
|
594 |
||
595 |
sub_dt=dt ! just in case I don't initialise this somehow |
|
596 |
! are we subcycling?
|
|
597 |
no_subcycles = 1 |
|
598 |
call get_option(trim(option_path)//"/prognostic/temporal_discretisation& |
|
599 |
&/control_volumes/number_advection_subcycles", & |
|
600 |
no_subcycles, stat=stat) |
|
601 |
if(stat/=0) then |
|
602 |
! have not specified a number of subcycles but perhaps we're using a
|
|
603 |
! courant number definition?
|
|
604 |
call get_option(trim(option_path)//"/prognostic/temporal_discretisation& |
|
605 |
&/control_volumes/maximum_courant_number_per_subcycle", & |
|
606 |
max_sub_cfl, stat=stat) |
|
607 |
if(stat==0) then |
|
608 |
max_cfl = maxval(cfl_no%val) |
|
609 |
call allmax(max_cfl) |
|
610 |
! yes, we're subcycling
|
|
611 |
! we should have already calculated the courant number (or aborted in the attempt)
|
|
612 |
no_subcycles=ceiling(max_cfl/max_sub_cfl) |
|
613 |
if(no_subcycles>1) then |
|
614 |
sub_dt=dt/real(no_subcycles) |
|
615 |
call scale(cfl_no, 1.0/real(no_subcycles)) |
|
616 |
end if
|
|
617 |
else
|
|
618 |
! no, we're not subcycling
|
|
619 |
no_subcycles=1 |
|
620 |
sub_dt = dt |
|
621 |
end if
|
|
622 |
else
|
|
623 |
if(no_subcycles>1) then |
|
624 |
sub_dt=dt/real(no_subcycles) |
|
625 |
call scale(cfl_no, 1.0/real(no_subcycles)) |
|
626 |
end if
|
|
627 |
end if
|
|
628 |
||
629 |
! when subcycling we're going to need to be starting each subcycle from the
|
|
630 |
! "new" old value but I don't want to screw with old code by updating the actual
|
|
631 |
! global timestep old value so lets create a copy now and update it instead
|
|
632 |
call set(l_old_tfield, oldtfield) |
|
633 |
||
634 |
ewrite(2,*) 'entering subcycling_loop', no_subcycles |
|
635 |
! subcycling loop
|
|
636 |
subcycling_loop: do sub = 1, no_subcycles |
|
637 |
||
638 |
! advection iteration loop
|
|
639 |
advection_iteration_loop: do adv_it = 1, adv_iterations |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
640 |
! construct the advection matrix if this is the first advection iteration
|
641 |
! and the first subcycle and we're not explicit and we're including advection
|
|
642 |
assemble_advection_matrix=(adv_it==1).and.(sub==1).and.(.not.explicit).and.include_advection |
|
643 |
! construct the diffusion matrix and rhs if we're including diffusion and
|
|
644 |
! if we're on the first advection iteration and the first subcycle
|
|
645 |
assemble_diffusion=(adv_it==1).and.(sub==1).and.include_diffusion |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
646 |
|
647 |
! record the value of tfield since the previous iteration
|
|
648 |
call set(advit_tfield, tfield) |
|
649 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
650 |
if(include_advection.or.assemble_diffusion) then |
651 |
! if advection is being included or we need to assemble a
|
|
652 |
! diffusion matrix then assemble A_m, D_m and rhs here
|
|
653 |
call assemble_advectiondiffusion_m_cv(A_m, rhs, D_m, diff_rhs, & |
|
654 |
tfield, l_old_tfield, tfield_options, & |
|
655 |
tdensity, oldtdensity, tdensity_options, & |
|
656 |
cvfaces, x_cvshape, x_cvbdyshape, & |
|
657 |
u_cvshape, u_cvbdyshape, t_cvshape, & |
|
658 |
ug_cvshape, ug_cvbdyshape, & |
|
659 |
x_cvshape_full, x_cvbdyshape_full, & |
|
660 |
t_cvshape_full, t_cvbdyshape_full, & |
|
661 |
diff_cvshape_full, diff_cvbdyshape_full, & |
|
662 |
state, advu, ug, x, x_tfield, cfl_no, sub_dt, & |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
663 |
diffusivity, q_cvmass, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
664 |
mesh_sparsity_x, grad_m_t_sparsity) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
665 |
end if
|
666 |
||
667 |
! assemble it all into a coherent equation
|
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
668 |
call assemble_field_eqn_cv(M, A_m, cvmass, rhs, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
669 |
tfield, l_old_tfield, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
670 |
tdensity, oldtdensity, tdensity_options, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
671 |
source, absorption, tfield_options%theta, & |
672 |
state, advu, sub_dt, explicit, & |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
673 |
t_cvmass, t_abs_src_cvmass, t_cvmass_old, t_cvmass_new, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
674 |
D_m, diff_rhs) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
675 |
|
676 |
||
677 |
! Solve for the change in tfield.
|
|
678 |
if(explicit) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
679 |
call apply_dirichlet_conditions(cvmass, rhs, tfield, sub_dt) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
680 |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
681 |
delta_tfield%val = rhs%val/cvmass%val |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
682 |
else
|
683 |
! apply strong dirichlet boundary conditions (if any)
|
|
684 |
! note that weak conditions (known as control volume boundary conditions)
|
|
685 |
! will already have been applied
|
|
686 |
call apply_dirichlet_conditions(M, rhs, tfield, sub_dt) |
|
687 |
||
688 |
call zero(delta_tfield) |
|
1403
by skramer
Actually add the "higher_order_lumping" as an "mg" option in the schema. |
689 |
call petsc_solve(delta_tfield, M, rhs, state(1)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
690 |
end if
|
691 |
||
692 |
! reset tfield to l_old_tfield before applying change
|
|
693 |
call set(tfield, l_old_tfield) |
|
694 |
! Add the change in tfield to tfield.
|
|
695 |
call addto(tfield, delta_tfield, sub_dt) |
|
696 |
||
697 |
call halo_update(tfield) ! exchange the extended halos |
|
698 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
699 |
call test_and_write_advection_convergence(tfield, advit_tfield, x, t_cvmass, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
700 |
filename=trim(state(1)%name)//"__"//trim(tfield%name), & |
701 |
time=time+sub_dt, dt=sub_dt, it=global_it, adv_it=adv_it, & |
|
702 |
subcyc=sub, error=error) |
|
703 |
||
704 |
if(error<adv_tolerance) exit advection_iteration_loop |
|
705 |
||
706 |
end do advection_iteration_loop |
|
707 |
||
708 |
! update the local old field to the new values and start again
|
|
709 |
call set(l_old_tfield, tfield) |
|
710 |
||
711 |
end do subcycling_loop |
|
712 |
||
713 |
call deallocate(delta_tfield) |
|
714 |
call deallocate(advit_tfield) |
|
715 |
call deallocate(l_old_tfield) |
|
716 |
call deallocate(rhs) |
|
717 |
if(.not.explicit) call deallocate(A_m) |
|
718 |
if(.not.explicit) call deallocate(M) |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
719 |
if(explicit) call deallocate(cvmass) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
720 |
call deallocate(cfl_no) |
721 |
call deallocate(x_cvbdyshape) |
|
722 |
call deallocate(x_cvbdyshape_full) |
|
723 |
call deallocate(u_cvbdyshape) |
|
724 |
call deallocate(x_cvshape) |
|
725 |
call deallocate(x_cvshape_full) |
|
726 |
call deallocate(u_cvshape) |
|
727 |
call deallocate(t_cvshape) |
|
728 |
call deallocate(t_cvshape_full) |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
729 |
call deallocate(diff_cvshape_full) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
730 |
call deallocate(t_cvbdyshape_full) |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
731 |
call deallocate(diff_cvbdyshape_full) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
732 |
call deallocate(cvfaces) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
733 |
if(include_advection) then |
734 |
call deallocate(advu) |
|
735 |
deallocate(advu) |
|
736 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
737 |
call deallocate(dummyscalar) |
738 |
deallocate(dummyscalar) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
739 |
call deallocate(dummyvector) |
740 |
deallocate(dummyvector) |
|
741 |
call deallocate(dummytensor) |
|
742 |
deallocate(dummytensor) |
|
743 |
if (include_diffusion) then |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
744 |
call deallocate(D_m) |
745 |
call deallocate(diff_rhs) |
|
746 |
end if
|
|
747 |
call deallocate(x_tfield) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
748 |
if(move_mesh) then |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
749 |
call deallocate(t_cvmass_new) |
750 |
call deallocate(t_cvmass_old) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
751 |
end if
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
752 |
call deallocate(ug_cvshape) |
753 |
call deallocate(ug_cvbdyshape) |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
754 |
if (include_porosity) then |
755 |
call deallocate(t_cvmass_with_porosity) |
|
756 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
757 |
|
758 |
end subroutine solve_field_eqn_cv |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
759 |
! end of solution wrapping subroutines
|
760 |
!************************************************************************
|
|
761 |
!************************************************************************
|
|
762 |
! equation wrapping subroutines
|
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
763 |
subroutine assemble_field_eqn_cv(M, A_m, m_cvmass, rhs, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
764 |
tfield, oldtfield, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
765 |
tdensity, oldtdensity, tdensity_options, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
766 |
source, absorption, theta, & |
767 |
state, advu, dt, explicit, & |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
768 |
cvmass, abs_src_cvmass, cvmass_old, cvmass_new, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
769 |
D_m, diff_rhs) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
770 |
|
771 |
! This subroutine assembles the equation
|
|
772 |
! M(T^{n+1}-T^{n})/\Delta T = rhs
|
|
773 |
! for control volumes.
|
|
774 |
! By the time you get here M should already contain the mass
|
|
775 |
! components (and if back compatible the diffusional components)
|
|
776 |
! of the equation.
|
|
777 |
||
778 |
! inputs/outputs:
|
|
779 |
! lhs matrix
|
|
780 |
type(csr_matrix), intent(inout) :: M |
|
781 |
! matrix containing advective terms - to be incorporated
|
|
782 |
! into M during this subroutine
|
|
783 |
type(csr_matrix), intent(inout) :: A_m |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
784 |
! explicit lhs and rhs of equation
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
785 |
type(scalar_field), intent(inout) :: m_cvmass, rhs |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
786 |
! the field we are solving for
|
787 |
type(scalar_field), intent(inout) :: tfield |
|
788 |
type(scalar_field), intent(inout) :: oldtfield, tdensity, oldtdensity |
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
789 |
! options wrappers for tdensity
|
790 |
type(cv_options_type) :: tdensity_options |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
791 |
type(scalar_field), intent(inout) :: source, absorption |
792 |
! time discretisation parameter
|
|
793 |
real, intent(in) :: theta |
|
794 |
! bucket full of fields
|
|
795 |
type(state_type), dimension(:), intent(inout) :: state |
|
796 |
! advection velocity
|
|
797 |
type(vector_field), intent(inout) :: advu |
|
798 |
! the timestep
|
|
799 |
real, intent(in) :: dt |
|
800 |
! are we assuming this is a fully explicit equation?
|
|
801 |
logical, intent(in) :: explicit |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
802 |
! cv mass to use for time derivative term
|
803 |
type(scalar_field), intent(in) :: cvmass |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
804 |
! moving mesh stuff
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
805 |
type(scalar_field), intent(in) :: cvmass_old |
806 |
type(scalar_field), intent(in) :: cvmass_new |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
807 |
! cv mass to use for absorption and source
|
808 |
type(scalar_field), intent(in) :: abs_src_cvmass |
|
809 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
810 |
! diffusion:
|
811 |
type(csr_matrix), intent(inout), optional :: D_m |
|
812 |
type(scalar_field), intent(inout), optional :: diff_rhs |
|
813 |
||
814 |
! local memory:
|
|
815 |
! for all equation types:
|
|
816 |
! product of A_m or D_m and oldtfield
|
|
817 |
type(scalar_field) :: MT_old |
|
818 |
type(scalar_field) :: masssource, massabsorption, massconservation |
|
819 |
||
820 |
! for InternalEnergy equations:
|
|
821 |
! sparsity for CT_m
|
|
822 |
type(csr_sparsity), pointer :: gradient_sparsity |
|
823 |
! divergence matrix for energy equation
|
|
824 |
type(block_csr_matrix) :: CT_m |
|
825 |
! pressure
|
|
826 |
type(scalar_field), pointer :: p |
|
827 |
! the assembled pressure term
|
|
828 |
type(scalar_field) :: pterm |
|
829 |
! atmospheric pressure for the energy equation
|
|
830 |
real :: atmospheric_pressure |
|
831 |
||
832 |
! for ConservationOfMass equations:
|
|
833 |
! tmpfield used in assembly of conservation term, consterm
|
|
834 |
type(scalar_field) :: consterm |
|
835 |
||
836 |
! for ReducedConservationOfMass equations:
|
|
837 |
real :: tdensity_theta |
|
838 |
||
839 |
! self explanatory strings
|
|
840 |
integer :: equation_type |
|
841 |
||
842 |
ewrite(1, *) "In assemble_field_eqn_cv" |
|
843 |
||
844 |
if(include_diffusion) then |
|
845 |
if(.not.present(D_m).or..not.present(diff_rhs)) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
846 |
! if this happens it's a code error
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
847 |
FLAbort("Must supply a diffusion matrix and rhs to use diffusion.") |
848 |
end if
|
|
849 |
end if
|
|
850 |
||
851 |
! zero the "matrices" being assembled
|
|
852 |
if(explicit) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
853 |
call zero(m_cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
854 |
else
|
855 |
call zero(M) |
|
856 |
end if
|
|
857 |
||
858 |
! start by adding the mass - common to all equation types
|
|
859 |
if(include_mass) then |
|
860 |
if(move_mesh) then |
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
861 |
if(explicit) then |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
862 |
call set(m_cvmass, cvmass_new) |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
863 |
else
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
864 |
call addto_diag(M, cvmass_new) |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
865 |
end if
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
866 |
else
|
867 |
if(explicit) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
868 |
call set(m_cvmass, cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
869 |
else
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
870 |
call addto_diag(M, cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
871 |
end if
|
872 |
end if
|
|
873 |
end if
|
|
874 |
||
875 |
! allocate some memory for assembly
|
|
876 |
call allocate(MT_old, rhs%mesh, name="MT_oldProduct" ) |
|
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
877 |
if(include_source .and. (.not. add_src_directly_to_rhs)) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
878 |
call allocate(masssource, rhs%mesh, name="MassSourceProduct" ) |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
879 |
call set(masssource, abs_src_cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
880 |
call scale(masssource, source) |
881 |
end if
|
|
882 |
if(include_absorption) then |
|
883 |
call allocate(massabsorption, rhs%mesh, name="MassAbsorptionProduct" ) |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
884 |
call set(massabsorption, abs_src_cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
885 |
call scale(massabsorption, absorption) |
886 |
end if
|
|
887 |
|
|
888 |
if(move_mesh) then |
|
889 |
call allocate(massconservation, rhs%mesh, name="MovingMeshMassConservation") |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
890 |
call set(massconservation, cvmass_old) |
891 |
call addto(massconservation, cvmass_new, scale=-1.0) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
892 |
call scale(massconservation, 1./dt) |
893 |
call scale(massconservation, oldtfield) |
|
894 |
end if
|
|
895 |
||
896 |
! find out equation type and hence if density is needed or not
|
|
897 |
equation_type=equation_type_index(trim(tfield%option_path)) |
|
898 |
! now we need to incorporate A_m into M and turn the equation into
|
|
899 |
! rate of change form (as well as adding in any extra terms for InternalEnergy
|
|
900 |
! for instance)
|
|
901 |
select case(equation_type) |
|
902 |
case (FIELD_EQUATION_ADVECTIONDIFFUSION) |
|
903 |
||
904 |
! [M + dt*A_m + theta*dt*D_m](T^{n+1}-T^{n})/dt = rhs - [A_m+D_m]*T^{n} - diff_rhs
|
|
905 |
||
906 |
if(.not.explicit) then |
|
907 |
! construct M
|
|
908 |
if(include_advection) call addto(M, A_m, dt) |
|
909 |
if(include_absorption) call addto_diag(M, massabsorption, theta*dt) |
|
910 |
||
911 |
! construct rhs
|
|
912 |
if(include_advection) then |
|
913 |
call mult(MT_old, A_m, oldtfield) |
|
914 |
call addto(rhs, MT_old, -1.0) |
|
915 |
end if
|
|
916 |
end if
|
|
917 |
||
918 |
||
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
919 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call addto(rhs, masssource) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
920 |
|
921 |
if(include_absorption) then |
|
922 |
! massabsorption has already been added to the matrix so it can now be scaled
|
|
923 |
! by the old field value to add it to the rhs
|
|
924 |
call scale(massabsorption, oldtfield) |
|
925 |
call addto(rhs, massabsorption, -1.0) |
|
926 |
end if
|
|
927 |
||
928 |
if(include_diffusion) then |
|
929 |
call mult(MT_old, D_m, oldtfield) |
|
930 |
call addto(rhs, MT_old, -1.0) |
|
931 |
call addto(rhs, diff_rhs, -1.0) |
|
932 |
||
933 |
if(.not.explicit) then |
|
934 |
call addto(M, D_m, theta*dt) |
|
935 |
end if
|
|
936 |
end if
|
|
937 |
|
|
938 |
if(move_mesh) then |
|
939 |
call addto(rhs, massconservation) |
|
940 |
end if
|
|
941 |
||
942 |
case (FIELD_EQUATION_CONSERVATIONOFMASS) |
|
943 |
||
944 |
! [\rho^{n+1}M + dt*A_m + theta*dt*D_m](T^{n+1}-T^{n})/dt = rhs - [A_m + D_m]*T^{n} - diff_rhs - M*(\rho^{n+1}-\rho^{n})*T^{n}/dt
|
|
945 |
||
946 |
! construct rhs
|
|
947 |
if(include_mass) then |
|
948 |
call allocate(consterm, tfield%mesh, name="DensityDifference") |
|
949 |
call set(consterm, tdensity) |
|
950 |
call addto(consterm, oldtdensity, -1.0) |
|
951 |
call scale(consterm, oldtfield) |
|
952 |
call scale(consterm, 1./dt) |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
953 |
call scale(consterm, cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
954 |
|
955 |
call addto(rhs, consterm, -1.0) |
|
956 |
||
957 |
call deallocate(consterm) |
|
958 |
end if
|
|
959 |
||
960 |
! construct M:
|
|
961 |
! multiply the diagonal of M by the up to date density
|
|
962 |
if(explicit) then |
|
963 |
if(include_mass) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
964 |
call scale(m_cvmass, tdensity) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
965 |
end if
|
966 |
else
|
|
967 |
if(include_mass) then |
|
968 |
call mult_diag(M, tdensity) |
|
969 |
end if
|
|
970 |
|
|
971 |
if(include_advection) call addto(M, A_m, dt) |
|
972 |
if(include_absorption) call addto_diag(M, massabsorption, theta*dt) |
|
973 |
||
974 |
if(include_advection) then |
|
975 |
call mult(MT_old, A_m, oldtfield) |
|
976 |
call addto(rhs, MT_old, -1.0) |
|
977 |
end if
|
|
978 |
end if
|
|
979 |
|
|
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
980 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call addto(rhs, masssource) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
981 |
|
982 |
if(include_absorption) then |
|
983 |
! massabsorption has already been added to the matrix so it can now be scaled
|
|
984 |
! by the old field value to add it to the rhs
|
|
985 |
call scale(massabsorption, oldtfield) |
|
986 |
call addto(rhs, massabsorption, -1.0) |
|
987 |
end if
|
|
988 |
||
989 |
if(include_diffusion) then |
|
990 |
call mult(MT_old, D_m, oldtfield) |
|
991 |
call addto(rhs, MT_old, -1.0) |
|
992 |
call addto(rhs, diff_rhs, -1.0) |
|
993 |
||
994 |
if(.not.explicit) then |
|
995 |
call addto(M, D_m, theta*dt) |
|
996 |
end if
|
|
997 |
end if
|
|
998 |
|
|
999 |
if(move_mesh) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
1000 |
FLExit("Moving mesh with this equation type not yet supported.") |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1001 |
end if
|
1002 |
||
1003 |
case (FIELD_EQUATION_REDUCEDCONSERVATIONOFMASS) |
|
1004 |
||
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1005 |
! [\rho^{n+\theta}M + dt*A_m + dt*theta*D_m](T^{n+1}-T^{n})/dt = rhs - [A_m + D_m]*T^{n} - diff_rhs
|
1006 |
tdensity_theta = tdensity_options%theta |
|
1007 |
||
1008 |
! construct M
|
|
1009 |
! multiply the diagonal by the previous timesteps density
|
|
1010 |
if(explicit) then |
|
1011 |
if(include_mass) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1012 |
m_cvmass%val = m_cvmass%val*(tdensity_theta*tdensity%val+(1.0-tdensity_theta)*oldtdensity%val) |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1013 |
end if
|
1014 |
else
|
|
1015 |
if(include_mass) then |
|
1016 |
call mult_diag(M, ((tdensity_theta)*tdensity%val+(1.0-tdensity_theta)*oldtdensity%val)) |
|
1017 |
end if
|
|
1018 |
if(include_advection) call addto(M, A_m, dt) |
|
1019 |
if(include_absorption) call addto_diag(M, massabsorption, theta*dt) |
|
1020 |
||
1021 |
! construct rhs
|
|
1022 |
if(include_advection) then |
|
1023 |
call mult(MT_old, A_m, oldtfield) |
|
1024 |
call addto(rhs, MT_old, -1.0) |
|
1025 |
end if
|
|
1026 |
end if
|
|
1027 |
||
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
1028 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call addto(rhs, masssource) |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1029 |
|
1030 |
if(include_absorption) then |
|
1031 |
! massabsorption has already been added to the matrix so it can now be scaled
|
|
1032 |
! by the old field value to add it to the rhs
|
|
1033 |
call scale(massabsorption, oldtfield) |
|
1034 |
call addto(rhs, massabsorption, -1.0) |
|
1035 |
end if
|
|
1036 |
||
1037 |
if(include_diffusion) then |
|
1038 |
call mult(MT_old, D_m, oldtfield) |
|
1039 |
call addto(rhs, MT_old, -1.0) |
|
1040 |
call addto(rhs, diff_rhs, -1.0) |
|
1041 |
||
1042 |
if(.not.explicit) then |
|
1043 |
call addto(M, D_m, theta*dt) |
|
1044 |
end if
|
|
1045 |
end if
|
|
1046 |
|
|
1047 |
if(move_mesh) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
1048 |
FLExit("Moving mesh with this equation type not yet supported.") |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1049 |
end if
|
1050 |
||
1051 |
case (FIELD_EQUATION_HEATTRANSFER) |
|
1052 |
||
1053 |
! [\rho^{n+\theta}M + dt*A_m + dt*theta*D_m](T^{n+1}-T^{n})/dt = rhs - [A_m + D_m]*T^{n} - diff_rhs
|
|
1054 |
tdensity_theta = tdensity_options%theta |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1055 |
|
1056 |
! construct M
|
|
1057 |
! multiply the diagonal by the previous timesteps density
|
|
1058 |
if(explicit) then |
|
1059 |
if(include_mass) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1060 |
m_cvmass%val = m_cvmass%val*(tdensity_theta*tdensity%val+(1.0-tdensity_theta)*oldtdensity%val) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1061 |
end if
|
1062 |
else
|
|
1063 |
if(include_mass) then |
|
1064 |
call mult_diag(M, ((tdensity_theta)*tdensity%val+(1.0-tdensity_theta)*oldtdensity%val)) |
|
1065 |
end if
|
|
1066 |
if(include_advection) call addto(M, A_m, dt) |
|
1067 |
if(include_absorption) call addto_diag(M, massabsorption, theta*dt) |
|
1068 |
||
1069 |
! construct rhs
|
|
1070 |
if(include_advection) then |
|
1071 |
call mult(MT_old, A_m, oldtfield) |
|
1072 |
call addto(rhs, MT_old, -1.0) |
|
1073 |
end if
|
|
1074 |
end if
|
|
1075 |
||
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
1076 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call addto(rhs, masssource) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1077 |
|
1078 |
if(include_absorption) then |
|
1079 |
! massabsorption has already been added to the matrix so it can now be scaled
|
|
1080 |
! by the old field value to add it to the rhs
|
|
1081 |
call scale(massabsorption, oldtfield) |
|
1082 |
call addto(rhs, massabsorption, -1.0) |
|
1083 |
end if
|
|
1084 |
||
1085 |
if(include_diffusion) then |
|
1086 |
call mult(MT_old, D_m, oldtfield) |
|
1087 |
call addto(rhs, MT_old, -1.0) |
|
1088 |
call addto(rhs, diff_rhs, -1.0) |
|
1089 |
||
1090 |
if(.not.explicit) then |
|
1091 |
call addto(M, D_m, theta*dt) |
|
1092 |
end if
|
|
1093 |
end if
|
|
1094 |
|
|
1095 |
if(move_mesh) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
1096 |
FLExit("Moving mesh with this equation type not yet supported.") |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1097 |
end if
|
1098 |
||
1099 |
case (FIELD_EQUATION_INTERNALENERGY) |
|
1100 |
||
1101 |
! [\rho^{n+1}M + dt*A_m + dt*theta*D_m](T^{n+1}-T^{n})/dt = rhs - [A_m + D_m]*T^{n} - diff_rhs - (p+atm_p)*CT_m*u
|
|
1102 |
||
1103 |
! construct rhs
|
|
1104 |
p=>extract_scalar_field(state(1), "Pressure") |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
1105 |
ewrite_minmax(p) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1106 |
assert(p%mesh==tfield%mesh) |
1107 |
! halo exchange not necessary as it is done straight after solve
|
|
1108 |
call get_option(trim(p%option_path)//'/prognostic/atmospheric_pressure', & |
|
1109 |
atmospheric_pressure, default=0.0) |
|
1110 |
gradient_sparsity => get_csr_sparsity_firstorder(state, p%mesh, advu%mesh) |
|
1111 |
||
1112 |
call allocate(CT_m, gradient_sparsity, (/1, advu%dim/), name="DivergenceMatrix" ) |
|
1113 |
call assemble_divergence_matrix_cv(CT_m, state(1), & |
|
1114 |
test_mesh=p%mesh, field=advu) |
|
1115 |
||
1116 |
call allocate(pterm, p%mesh, "PressureTerm") |
|
1117 |
||
1118 |
! construct the pressure term
|
|
1119 |
call mult(pterm, CT_m, advu) |
|
1120 |
! should this really be the advection velocity or just the relative or the nonlinear?
|
|
1121 |
pterm%val = pterm%val*(p%val+atmospheric_pressure) |
|
1122 |
||
1123 |
call addto(rhs, pterm, -1.0) |
|
1124 |
||
1125 |
call deallocate(CT_m) |
|
1126 |
call deallocate(pterm) |
|
1127 |
||
1128 |
! construct M
|
|
1129 |
if(explicit) then |
|
1130 |
if(include_mass) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1131 |
call scale(m_cvmass, tdensity) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1132 |
end if
|
1133 |
else
|
|
1134 |
if(include_mass) then |
|
1135 |
call mult_diag(M, tdensity) |
|
1136 |
end if
|
|
1137 |
if(include_advection) call addto(M, A_m, dt) |
|
1138 |
if(include_absorption) call addto_diag(M, massabsorption, theta*dt) |
|
1139 |
||
1140 |
if(include_advection) then |
|
1141 |
call mult(MT_old, A_m, oldtfield) |
|
1142 |
call addto(rhs, MT_old, -1.0) |
|
1143 |
end if
|
|
1144 |
end if
|
|
1145 |
||
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
1146 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call addto(rhs, masssource) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1147 |
|
1148 |
if(include_absorption) then |
|
1149 |
! massabsorption has already been added to the matrix so it can now be scaled
|
|
1150 |
! by the old field value to add it to the rhs
|
|
1151 |
call scale(massabsorption, oldtfield) |
|
1152 |
call addto(rhs, massabsorption, -1.0) |
|
1153 |
end if
|
|
1154 |
||
1155 |
if(include_diffusion) then |
|
1156 |
call mult(MT_old, D_m, oldtfield) |
|
1157 |
call addto(rhs, MT_old, -1.0) |
|
1158 |
call addto(rhs, diff_rhs, -1.0) |
|
1159 |
||
1160 |
if(.not.explicit) then |
|
1161 |
call addto(M, D_m, theta*dt) |
|
1162 |
end if
|
|
1163 |
end if
|
|
1164 |
|
|
1165 |
if(move_mesh) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
1166 |
FLExit("Moving mesh with this equation type not yet supported.") |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1167 |
end if
|
1168 |
||
1169 |
end select
|
|
1170 |
||
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
1171 |
! Add the source directly to the rhs if required
|
1172 |
! which must be included before dirichlet BC's.
|
|
1173 |
if (add_src_directly_to_rhs) call addto(rhs, source) |
|
1174 |
||
1175 |
if(include_source .and. (.not. add_src_directly_to_rhs)) call deallocate(masssource) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1176 |
if(include_absorption) call deallocate(massabsorption) |
1177 |
call deallocate(MT_old) |
|
1178 |
if(move_mesh) call deallocate(massconservation) |
|
1179 |
||
1180 |
ewrite(1, *) "Exiting assemble_field_eqn_cv" |
|
1181 |
||
1182 |
end subroutine assemble_field_eqn_cv |
|
1183 |
! end of equation wrapping subroutines
|
|
1184 |
!************************************************************************
|
|
1185 |
!************************************************************************
|
|
1186 |
! assembly subroutines
|
|
1187 |
subroutine assemble_advectiondiffusion_m_cv(A_m, rhs, D_m, diff_rhs, & |
|
1188 |
tfield, oldtfield, tfield_options, & |
|
1189 |
tdensity, oldtdensity, tdensity_options, & |
|
1190 |
cvfaces, x_cvshape, x_cvbdyshape, & |
|
1191 |
u_cvshape, u_cvbdyshape, t_cvshape, & |
|
1192 |
ug_cvshape, ug_cvbdyshape, & |
|
1193 |
x_cvshape_full, x_cvbdyshape_full, & |
|
1194 |
t_cvshape_full, t_cvbdyshape_full, & |
|
1195 |
diff_cvshape_full, diff_cvbdyshape_full, & |
|
1196 |
state, advu, ug, x, x_tfield, cfl_no, dt, & |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1197 |
diffusivity, q_cvmass, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1198 |
mesh_sparsity, grad_m_t_sparsity) |
1199 |
||
1200 |
! This subroutine assembles the advection and diffusion matrices and rhs(s) for
|
|
1201 |
! control volume field equations such that:
|
|
1202 |
! A_m = div(\rho u T) - (1-beta)*T*div(\rho u)
|
|
1203 |
! and:
|
|
1204 |
! D_m = div(\kappa grad T)
|
|
1205 |
||
1206 |
! inputs/outputs:
|
|
1207 |
! the advection matrix
|
|
1208 |
type(csr_matrix), intent(inout) :: A_m |
|
1209 |
! the rhs of the control volume field eqn
|
|
1210 |
type(scalar_field), intent(inout) :: rhs |
|
1211 |
! the diffusion matrix
|
|
1212 |
type(csr_matrix), intent(inout) :: D_m |
|
1213 |
! the diffusion rhs
|
|
1214 |
type(scalar_field), intent(inout) :: diff_rhs |
|
1215 |
||
1216 |
! the field being solved for
|
|
1217 |
type(scalar_field), intent(inout), target :: tfield |
|
1218 |
! previous time level of the field being solved for
|
|
1219 |
type(scalar_field), intent(inout) :: oldtfield |
|
1220 |
! a type containing all the tfield options
|
|
1221 |
type(cv_options_type), intent(in) :: tfield_options |
|
1222 |
! density and previous time level of density associated with the
|
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1223 |
! field (only a real density if solving for an equation other than
|
1224 |
! AdvectionDiffusion)
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1225 |
type(scalar_field), intent(inout) :: tdensity, oldtdensity |
1226 |
! a type containing all the tdensity options
|
|
1227 |
type(cv_options_type), intent(in) :: tdensity_options |
|
1228 |
||
1229 |
! information about cv faces
|
|
1230 |
type(cv_faces_type), intent(in) :: cvfaces |
|
1231 |
! shape functions for region and surface
|
|
1232 |
type(element_type), intent(in) :: x_cvshape, x_cvbdyshape |
|
1233 |
type(element_type), intent(in) :: u_cvshape, u_cvbdyshape |
|
1234 |
type(element_type), intent(in) :: ug_cvshape, ug_cvbdyshape |
|
1235 |
type(element_type), intent(in) :: t_cvshape |
|
1236 |
! shape functions with full body derivatives (for ElementGradient diffusion)
|
|
1237 |
type(element_type), intent(inout) :: x_cvshape_full, x_cvbdyshape_full |
|
1238 |
type(element_type), intent(inout) :: t_cvshape_full, diff_cvshape_full |
|
1239 |
type(element_type), intent(inout) :: t_cvbdyshape_full, diff_cvbdyshape_full |
|
1240 |
||
1241 |
! bucket full of fields
|
|
1242 |
type(state_type), dimension(:), intent(inout) :: state |
|
1243 |
! the relative velocity
|
|
1244 |
type(vector_field), intent(in) :: advu |
|
1245 |
type(vector_field), pointer :: ug |
|
1246 |
! the coordinates (base and on the tfield mesh)
|
|
1247 |
type(vector_field), intent(inout) :: x, x_tfield |
|
1248 |
! the cfl number
|
|
1249 |
type(scalar_field), intent(in) :: cfl_no |
|
1250 |
! timestep
|
|
1251 |
real, intent(in) :: dt |
|
1252 |
||
1253 |
! mesh sparsity for upwind value matrices
|
|
1254 |
type(csr_sparsity), intent(in) :: mesh_sparsity |
|
1255 |
||
1256 |
! the diffusivity tensor
|
|
1257 |
type(tensor_field), intent(in) :: diffusivity |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1258 |
! the cv mass = the mass matrix for the auxilliary diffusion equation
|
1259 |
type(scalar_field), intent(in) :: q_cvmass |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1260 |
! sparsity pattern for the gradient transposed operator
|
1261 |
type(csr_sparsity), intent(inout) :: grad_m_t_sparsity |
|
1262 |
||
1263 |
! local memory:
|
|
1264 |
! memory for coordinates, velocity, normals, determinants, nodes
|
|
1265 |
! and the cfl number at the gauss pts and nodes
|
|
1266 |
real, dimension(x%dim,ele_loc(x,1)) :: x_ele |
|
1267 |
real, dimension(x%dim,face_loc(x,1)) :: x_ele_bdy |
|
1268 |
real, dimension(x%dim,x_cvshape%ngi) :: x_f |
|
1269 |
real, dimension(advu%dim,u_cvshape%ngi) :: u_f |
|
1270 |
real, dimension(advu%dim, ug_cvshape%ngi) :: ug_f |
|
1271 |
real, dimension(advu%dim,u_cvbdyshape%ngi) :: u_bdy_f |
|
1272 |
real, dimension(advu%dim,ug_cvbdyshape%ngi) :: ug_bdy_f |
|
1273 |
real, dimension(x%dim,x_cvshape%ngi) :: normal |
|
1274 |
real, dimension(x%dim, x_cvbdyshape%ngi) :: normal_bdy |
|
1275 |
real, dimension(x_cvshape%ngi) :: detwei |
|
1276 |
real, dimension(x_cvbdyshape%ngi) :: detwei_bdy |
|
1277 |
real, dimension(x%dim) :: normgi |
|
1278 |
integer, dimension(:), pointer :: nodes, x_nodes, diffusivity_nodes, upwind_nodes |
|
1279 |
integer, dimension(face_loc(tfield,1)) :: nodes_bdy |
|
1280 |
integer, dimension(face_loc(diffusivity,1)) :: diffusivity_nodes_bdy |
|
1281 |
real, dimension(ele_loc(cfl_no, 1)) :: cfl_ele |
|
1282 |
||
1283 |
! memory for the values of the field and density at the nodes
|
|
1284 |
! and on the boundary and for ghost values outside the boundary
|
|
1285 |
real, dimension(ele_loc(tdensity,1)) :: tdensity_ele, oldtdensity_ele |
|
1286 |
real, dimension(ele_loc(tfield,1)) :: tfield_ele, oldtfield_ele |
|
1287 |
real, dimension(face_loc(tdensity,1)) :: tdensity_ele_bdy, oldtdensity_ele_bdy, & |
|
1288 |
ghost_tdensity_ele_bdy, ghost_oldtdensity_ele_bdy |
|
1289 |
real, dimension(face_loc(tfield,1)) :: tfield_ele_bdy, oldtfield_ele_bdy, & |
|
1290 |
ghost_tfield_ele_bdy, ghost_gradtfield_ele_bdy, ghost_oldtfield_ele_bdy |
|
1291 |
||
1292 |
! some memory used in assembly of the face values
|
|
1293 |
real :: tfield_theta_val, tdensity_theta_val, tfield_pivot_val |
|
1294 |
real :: tfield_face_val, oldtfield_face_val |
|
1295 |
real :: tdensity_face_val, oldtdensity_face_val |
|
1296 |
||
1297 |
! logical array indicating if a face has already been visited by the opposing node
|
|
1298 |
logical, dimension(x_cvshape%ngi) :: notvisited |
|
1299 |
||
1300 |
! loop integers
|
|
1301 |
integer :: ele, sele, iloc, oloc, dloc, face, gi, ggi, dim |
|
1302 |
||
1303 |
! upwind value matrices for the fields and densities
|
|
1304 |
type(csr_matrix) :: tfield_upwind, & |
|
1305 |
oldtfield_upwind, tdensity_upwind, oldtdensity_upwind |
|
1306 |
||
1307 |
! incoming or outgoing flow
|
|
1308 |
real :: udotn, divudotn, income |
|
1309 |
logical :: inflow |
|
1310 |
! time and face discretisation
|
|
1311 |
real :: ptheta, ftheta, beta |
|
1312 |
||
1313 |
! the type of the bc if integrating over domain boundaries
|
|
1314 |
integer, dimension(:), allocatable :: tfield_bc_type, tdensity_bc_type |
|
1315 |
! fields for the bcs over the entire surface mesh
|
|
1316 |
type(scalar_field) :: tfield_bc, tdensity_bc |
|
1317 |
||
1318 |
! local element matrices - allow the assembly of an entire face without multiple calls to csr_pos
|
|
1319 |
real, dimension(mesh_dim(tfield), ele_loc(tfield,1), ele_loc(tfield,1)) :: grad_mat_local |
|
1320 |
real, dimension(ele_loc(tfield,1), ele_loc(tfield,1)) :: mat_local, diff_mat_local |
|
1321 |
real, dimension(face_loc(tfield,1),face_loc(tfield,1)) :: diff_mat_local_bdy |
|
1322 |
real, dimension(mesh_dim(tfield), face_loc(tfield,1)) :: grad_mat_local_bdy, grad_rhs_local_bdy |
|
1323 |
real, dimension(face_loc(tfield,1)) :: mat_local_bdy, rhs_local_bdy, div_rhs_local_bdy |
|
1324 |
real, dimension(ele_loc(tfield,1)) :: rhs_local |
|
1325 |
||
1326 |
! the auxilliary gradient matrix (assembled as a divergence confusingly)
|
|
1327 |
type(block_csr_matrix) :: div_m |
|
1328 |
! the auxilliary gradient equation rhs
|
|
1329 |
type(vector_field) :: grad_rhs |
|
1330 |
! the diffusivity evaluated at the nodes and the transformed full body gradients
|
|
1331 |
real, dimension(ele_loc(tfield,1), x_cvshape%ngi, mesh_dim(tfield)) :: dt_t |
|
1332 |
real, dimension(mesh_dim(tfield), mesh_dim(tfield), x_cvshape%ngi) :: diffusivity_gi |
|
1333 |
real, dimension(face_loc(tfield,1), x_cvbdyshape%ngi, mesh_dim(tfield)) :: dt_ft |
|
1334 |
real, dimension(mesh_dim(tfield), mesh_dim(tfield), x_cvbdyshape%ngi) :: diffusivity_gi_f |
|
1335 |
! a dummy array to potentially store multiple copies of the diffusivity nodes
|
|
1336 |
integer, dimension(ele_loc(tfield,1)) :: diffusivity_lglno |
|
1337 |
integer, dimension(face_loc(tfield,1)) :: diffusivity_lglno_bdy |
|
1338 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1339 |
! Boundary condition types
|
1340 |
integer, parameter :: BC_TYPE_WEAKDIRICHLET = 1, BC_TYPE_NEUMANN = 2, BC_TYPE_INTERNAL = 3, & |
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1341 |
BC_TYPE_ZEROFLUX = 4, BC_TYPE_FLUX = 5 |
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1342 |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1343 |
ewrite(1, *) "In assemble_advectiondiffusion_m_cv" |
1344 |
||
1345 |
! Clear memory of arrays being designed
|
|
1346 |
if(assemble_advection_matrix) call zero(A_m) |
|
1347 |
call zero(rhs) |
|
1348 |
||
1349 |
! allocate upwind value matrices
|
|
1350 |
call allocate(tfield_upwind, mesh_sparsity, name="TFieldUpwindValues") |
|
1351 |
call allocate(oldtfield_upwind, mesh_sparsity, name="OldTFieldUpwindValues") |
|
1352 |
! does the field need upwind values
|
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1353 |
if(need_upwind_values(tfield_options)) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1354 |
|
1355 |
call find_upwind_values(state, x_tfield, tfield, tfield_upwind, & |
|
1356 |
oldtfield, oldtfield_upwind, & |
|
1357 |
option_path=trim(tfield%option_path)) |
|
1358 |
||
1359 |
else
|
|
1360 |
||
1361 |
call zero(tfield_upwind) |
|
1362 |
call zero(oldtfield_upwind) |
|
1363 |
||
1364 |
end if
|
|
1365 |
||
1366 |
! does the density field need upwind values?
|
|
1367 |
if(include_density) then |
|
1368 |
call allocate(tdensity_upwind, mesh_sparsity, name="TDensityUpwindValues") |
|
1369 |
call allocate(oldtdensity_upwind, mesh_sparsity, name="OldTDensityUpwindValues") |
|
1370 |
||
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
1371 |
if(need_upwind_values(tdensity_options)) then |
1372 |
if(have_option(trim(tfield%option_path)//'/prognostic/equation[0]/density[0]/discretisation_options')) then |
|
1373 |
call find_upwind_values(state, x_tfield, tdensity, tdensity_upwind, & |
|
1374 |
oldtdensity, oldtdensity_upwind, & |
|
1375 |
option_path=trim(tfield%option_path)//'/prognostic/equation[0]/density[0]/discretisation_options') |
|
1376 |
else
|
|
1377 |
call find_upwind_values(state, x_tfield, tdensity, tdensity_upwind, & |
|
1378 |
oldtdensity, oldtdensity_upwind & |
|
1379 |
)
|
|
1380 |
end if
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1381 |
|
1382 |
else
|
|
1383 |
||
1384 |
call zero(tdensity_upwind) |
|
1385 |
call zero(oldtdensity_upwind) |
|
1386 |
||
1387 |
end if
|
|
1388 |
end if
|
|
1389 |
||
1390 |
! allocate and clear memory for diffusion
|
|
1391 |
if(assemble_diffusion) then |
|
1392 |
if(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY) then |
|
1393 |
call allocate(div_m, sparsity=grad_m_t_sparsity, & |
|
1394 |
blocks=(/1, mesh_dim(tfield)/), & |
|
1395 |
name=trim(tfield%name)//"AuxilliaryGradientMatrixTransposed") |
|
1396 |
call zero(div_m) |
|
1397 |
call allocate(grad_rhs, mesh_dim(tfield), diffusivity%mesh, & |
|
1398 |
name=trim(tfield%name)//"AuxilliaryGradientRHS") |
|
1399 |
call zero(grad_rhs) |
|
1400 |
end if
|
|
1401 |
||
1402 |
call zero(D_m) |
|
1403 |
call zero(diff_rhs) |
|
1404 |
end if
|
|
1405 |
||
1406 |
! some temporal discretisation options for clarity
|
|
1407 |
ptheta = tfield_options%ptheta |
|
1408 |
beta = tfield_options%beta |
|
1409 |
||
1410 |
! loop over elements
|
|
1411 |
element_loop: do ele=1, element_count(tfield) |
|
1412 |
x_ele=ele_val(x, ele) |
|
1413 |
x_f=ele_val_at_quad(x, ele, x_cvshape) |
|
1414 |
nodes=>ele_nodes(tfield, ele) |
|
1415 |
! the nodes in this element from the coordinate mesh projected
|
|
1416 |
! to the tfield mesh (unperiodised perhaps... hence different to tfield mesh)
|
|
1417 |
x_nodes=>ele_nodes(x_tfield, ele) |
|
1418 |
if(include_advection) then |
|
1419 |
u_f=ele_val_at_quad(advu, ele, u_cvshape) |
|
1420 |
if(move_mesh) ug_f=ele_val_at_quad(ug, ele, ug_cvshape) |
|
1421 |
if((tfield_options%upwind_scheme==CV_UPWINDVALUE_PROJECT_POINT).or.& |
|
1422 |
(tfield_options%upwind_scheme==CV_UPWINDVALUE_PROJECT_GRAD)) then |
|
1423 |
upwind_nodes=>x_nodes |
|
1424 |
else
|
|
1425 |
upwind_nodes=>nodes |
|
1426 |
end if
|
|
1427 |
end if
|
|
1428 |
||
1429 |
! find determinant and unorientated normal
|
|
1430 |
call transform_cvsurf_to_physical(x_ele, x_cvshape, & |
|
1431 |
detwei, normal, cvfaces) |
|
1432 |
||
1433 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
|
1434 |
diffusivity_nodes=>ele_nodes(diffusivity, ele) |
|
1435 |
! diffusivity may be on a lower degree mesh than the field... to allow that
|
|
1436 |
! without changing the assembly code for each specific case we construct
|
|
1437 |
! a mapping to the global nodes that is consistent with the local node
|
|
1438 |
! numbering of the parent field.
|
|
1439 |
! warning: this is not ideal as it will require more csr_pos's
|
|
1440 |
! but its more intended as a proof of concept
|
|
1441 |
do iloc = 1, size(diffusivity_lglno), size(diffusivity_nodes) |
|
1442 |
diffusivity_lglno(iloc:iloc+size(diffusivity_nodes)-1)=diffusivity_nodes |
|
1443 |
end do
|
|
1444 |
end if
|
|
1445 |
||
1446 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_ELEMENTGRADIENT)) then |
|
1447 |
call transform_to_physical(X, ele, x_shape=x_cvshape_full, & |
|
1448 |
shape=t_cvshape_full, dshape=dt_t) |
|
1449 |
diffusivity_gi = ele_val_at_quad(diffusivity, ele, diff_cvshape_full) |
|
1450 |
end if
|
|
1451 |
||
1452 |
cfl_ele = ele_val(cfl_no, ele) |
|
1453 |
||
1454 |
tfield_ele = ele_val(tfield, ele) |
|
1455 |
oldtfield_ele = ele_val(oldtfield, ele) |
|
1456 |
||
1457 |
if(include_density) then |
|
1458 |
tdensity_ele = ele_val(tdensity, ele) |
|
1459 |
oldtdensity_ele = ele_val(oldtdensity, ele) |
|
1460 |
end if
|
|
1461 |
||
1462 |
notvisited=.true. |
|
1463 |
||
1464 |
grad_mat_local = 0.0 |
|
1465 |
mat_local = 0.0 |
|
1466 |
rhs_local = 0.0 |
|
1467 |
diff_mat_local = 0.0 |
|
1468 |
||
1469 |
! loop over nodes within this element
|
|
1470 |
nodal_loop_i: do iloc = 1, tfield%mesh%shape%loc |
|
1471 |
||
1472 |
! loop over cv faces internal to this element
|
|
1473 |
face_loop: do face = 1, cvfaces%faces |
|
1474 |
||
1475 |
! is this a face neighbouring iloc?
|
|
1476 |
if(cvfaces%neiloc(iloc, face) /= 0) then |
|
1477 |
oloc = cvfaces%neiloc(iloc, face) |
|
1478 |
||
1479 |
! loop over gauss points on face
|
|
1480 |
quadrature_loop: do gi = 1, cvfaces%shape%ngi |
|
1481 |
||
1482 |
! global gauss pt index
|
|
1483 |
ggi = (face-1)*cvfaces%shape%ngi + gi |
|
1484 |
||
1485 |
! have we been here before?
|
|
1486 |
if(notvisited(ggi)) then |
|
1487 |
notvisited(ggi)=.false. |
|
1488 |
||
1489 |
! correct the orientation of the normal so it points away from iloc
|
|
1490 |
normgi=orientate_cvsurf_normgi(node_val(x_tfield, x_nodes(iloc)),x_f(:,ggi),normal(:,ggi)) |
|
1491 |
||
1492 |
if(include_advection) then |
|
1493 |
! calculate u.n
|
|
1494 |
if(move_mesh) then |
|
1495 |
udotn=dot_product((u_f(:,ggi)-ug_f(:,ggi)), normgi(:)) |
|
1496 |
divudotn=dot_product(u_f(:,ggi), normgi(:)) |
|
1497 |
else
|
|
1498 |
udotn=dot_product(u_f(:,ggi), normgi(:)) |
|
1499 |
divudotn=udotn |
|
1500 |
end if
|
|
1501 |
inflow = (udotn<=0.0) |
|
1502 |
income = merge(1.0,0.0,inflow) |
|
1503 |
||
1504 |
! calculate the iterated pivot value (so far only does first order upwind)
|
|
1505 |
! which will be subtracted out from the rhs such that with an increasing number
|
|
1506 |
! of iterations the true implicit lhs pivot is cancelled out (if it converges!)
|
|
1507 |
tfield_pivot_val = income*tfield_ele(oloc) + (1.-income)*tfield_ele(iloc) |
|
1508 |
||
1509 |
! evaluate the nonlinear face value that will go into the rhs
|
|
1510 |
! this is the value that you choose the discretisation for and
|
|
1511 |
! that will become the dominant term once convergence is achieved
|
|
1512 |
call evaluate_face_val(tfield_face_val, oldtfield_face_val, & |
|
1513 |
iloc, oloc, ggi, upwind_nodes, & |
|
1514 |
t_cvshape, & |
|
1515 |
tfield_ele, oldtfield_ele, & |
|
1516 |
tfield_upwind, oldtfield_upwind, & |
|
1517 |
inflow, cfl_ele, & |
|
1518 |
tfield_options) |
|
1519 |
||
1520 |
! perform the time discretisation on the combined tdensity tfield product
|
|
1521 |
tfield_theta_val=theta_val(iloc, oloc, & |
|
1522 |
tfield_face_val, & |
|
1523 |
oldtfield_face_val, & |
|
1524 |
tfield_options%theta, dt, udotn, & |
|
1525 |
x_ele, tfield_options%limit_theta, & |
|
1526 |
tfield_ele, oldtfield_ele, & |
|
1527 |
ftheta=ftheta) |
|
1528 |
||
1529 |
if(include_density) then |
|
1530 |
! do the same for the density but save some effort if it's just a dummy
|
|
1531 |
select case (tdensity%field_type) |
|
1532 |
case(FIELD_TYPE_CONSTANT) |
|
1533 |
||
1534 |
tdensity_face_val = tdensity_ele(iloc) |
|
1535 |
oldtdensity_face_val = oldtdensity_ele(iloc) |
|
1536 |
||
1537 |
case default |
|
1538 |
||
1539 |
call evaluate_face_val(tdensity_face_val, oldtdensity_face_val, & |
|
1540 |
iloc, oloc, ggi, upwind_nodes, & |
|
1541 |
t_cvshape,& |
|
1542 |
tdensity_ele, oldtdensity_ele, & |
|
1543 |
tdensity_upwind, oldtdensity_upwind, & |
|
1544 |
inflow, cfl_ele, & |
|
1545 |
tdensity_options) |
|
1546 |
||
1547 |
end select
|
|
1548 |
||
1549 |
tdensity_theta_val=theta_val(iloc, oloc, & |
|
1550 |
tdensity_face_val, & |
|
1551 |
oldtdensity_face_val, & |
|
1552 |
tdensity_options%theta, dt, udotn, & |
|
1553 |
x_ele, tdensity_options%limit_theta, & |
|
1554 |
tdensity_ele, oldtdensity_ele) |
|
1555 |
||
1556 |
if(assemble_advection_matrix) then |
|
1557 |
mat_local(iloc, oloc) = mat_local(iloc, oloc) & |
|
1558 |
+ ptheta*detwei(ggi)*udotn*income*tdensity_theta_val |
|
1559 |
mat_local(oloc, iloc) = mat_local(oloc, iloc) & |
|
1560 |
+ ptheta*detwei(ggi)*(-udotn)*(1.-income)*tdensity_theta_val |
|
1561 |
mat_local(iloc, iloc) = mat_local(iloc, iloc) & |
|
1562 |
+ ptheta*detwei(ggi)*udotn*(1.0-income)*tdensity_theta_val & |
|
1563 |
- ftheta*(1.-beta)*detwei(ggi)*divudotn*tdensity_theta_val |
|
1564 |
mat_local(oloc, oloc) = mat_local(oloc, oloc) & |
|
1565 |
+ ptheta*detwei(ggi)*(-udotn)*income*tdensity_theta_val & |
|
1566 |
- ftheta*(1.-beta)*detwei(ggi)*(-divudotn)*tdensity_theta_val |
|
1567 |
end if
|
|
1568 |
||
1569 |
rhs_local(iloc) = rhs_local(iloc) & |
|
1570 |
+ ptheta*udotn*detwei(ggi)*tdensity_theta_val*tfield_pivot_val & |
|
1571 |
- udotn*detwei(ggi)*tfield_theta_val*tdensity_theta_val & |
|
1572 |
+ (1.-ftheta)*(1.-beta)*detwei(ggi)*divudotn*tdensity_theta_val*oldtfield_ele(iloc) |
|
1573 |
rhs_local(oloc) = rhs_local(oloc) & |
|
1574 |
+ ptheta*(-udotn)*detwei(ggi)*tdensity_theta_val*tfield_pivot_val & |
|
1575 |
- (-udotn)*detwei(ggi)*tfield_theta_val*tdensity_theta_val & |
|
1576 |
+ (1.-ftheta)*(1.-beta)*detwei(ggi)*(-divudotn)*tdensity_theta_val*oldtfield_ele(oloc) |
|
1577 |
||
1578 |
else
|
|
1579 |
if(assemble_advection_matrix) then |
|
1580 |
mat_local(iloc, oloc) = mat_local(iloc, oloc) & |
|
1581 |
+ ptheta*detwei(ggi)*udotn*income |
|
1582 |
mat_local(oloc, iloc) = mat_local(oloc, iloc) & |
|
1583 |
+ ptheta*detwei(ggi)*(-udotn)*(1.-income) |
|
1584 |
mat_local(iloc, iloc) = mat_local(iloc, iloc) & |
|
1585 |
+ ptheta*detwei(ggi)*udotn*(1.0-income) & |
|
1586 |
- ftheta*(1.-beta)*detwei(ggi)*divudotn |
|
1587 |
mat_local(oloc, oloc) = mat_local(oloc, oloc) & |
|
1588 |
+ ptheta*detwei(ggi)*(-udotn)*income & |
|
1589 |
- ftheta*(1.-beta)*detwei(ggi)*(-divudotn) |
|
1590 |
end if
|
|
1591 |
||
1592 |
rhs_local(iloc) = rhs_local(iloc) & |
|
1593 |
+ ptheta*udotn*detwei(ggi)*tfield_pivot_val & |
|
1594 |
- udotn*detwei(ggi)*tfield_theta_val & |
|
1595 |
+ (1.-ftheta)*(1.-beta)*detwei(ggi)*divudotn*oldtfield_ele(iloc) |
|
1596 |
rhs_local(oloc) = rhs_local(oloc) & |
|
1597 |
+ ptheta*(-udotn)*detwei(ggi)*tfield_pivot_val & |
|
1598 |
- (-udotn)*detwei(ggi)*tfield_theta_val & |
|
1599 |
+ (1.-ftheta)*(1.-beta)*detwei(ggi)*(-divudotn)*oldtfield_ele(oloc) |
|
1600 |
end if
|
|
1601 |
end if
|
|
1602 |
||
1603 |
if(assemble_diffusion) then |
|
1604 |
select case(tfield_options%diffusionscheme) |
|
1605 |
case(CV_DIFFUSION_BASSIREBAY) |
|
1606 |
||
1607 |
! assemble the auxiliary gradient matrix
|
|
1608 |
dimension_loop1: do dim = 1, mesh_dim(tfield) |
|
1609 |
||
1610 |
grad_mat_local(dim, iloc, iloc) = grad_mat_local(dim, iloc, iloc) & |
|
1611 |
+0.5*detwei(ggi)*normgi(dim) |
|
1612 |
! the divergence form:
|
|
1613 |
grad_mat_local(dim, iloc, oloc) = grad_mat_local(dim, iloc, oloc) & |
|
1614 |
+0.5*detwei(ggi)*normgi(dim) ! remember this is a divergence assembly |
|
1615 |
! this is the equivalent gradient transposed form:
|
|
1616 |
! grad_mat_local(dim, oloc, iloc) = grad_mat_local(dim, oloc, iloc) &
|
|
1617 |
! +0.5*detwei(ggi)*normgi(dim) ! remember this is a gradient transposed
|
|
1618 |
||
1619 |
! evaluate the faces we're not visiting (as an optimisation)
|
|
1620 |
grad_mat_local(dim, oloc, oloc) = grad_mat_local(dim, oloc, oloc) & |
|
1621 |
-0.5*detwei(ggi)*normgi(dim) |
|
1622 |
grad_mat_local(dim, oloc, iloc) = grad_mat_local(dim, oloc, iloc) & |
|
1623 |
-0.5*detwei(ggi)*normgi(dim) ! remember this is a divergence assembly |
|
1624 |
! this is the equivalent gradient transposed form:
|
|
1625 |
! grad_mat_local(dim, iloc, oloc) = grad_mat_local(dim, iloc, oloc) &
|
|
1626 |
! -0.5*detwei(ggi)*normgi(dim) ! remember this is a gradient transposed
|
|
1627 |
end do dimension_loop1 |
|
1628 |
||
1629 |
case(CV_DIFFUSION_ELEMENTGRADIENT) |
|
1630 |
||
1631 |
do dloc=1,size(dt_t,1) |
|
1632 |
! n_i K_{ij} dT/dx_j
|
|
1633 |
diff_mat_local(iloc,dloc) = diff_mat_local(iloc,dloc) - & |
|
1634 |
sum(matmul(diffusivity_gi(:,:,ggi), dt_t(dloc, ggi, :))*normgi, 1)*detwei(ggi) |
|
1635 |
||
1636 |
! notvisited
|
|
1637 |
diff_mat_local(oloc, dloc) = diff_mat_local(oloc,dloc) - & |
|
1638 |
sum(matmul(diffusivity_gi(:,:,ggi), dt_t(dloc, ggi, :))*(-normgi), 1)*detwei(ggi) |
|
1639 |
end do
|
|
1640 |
||
1641 |
end select
|
|
1642 |
end if
|
|
1643 |
||
1644 |
end if ! notvisited |
|
1645 |
end do quadrature_loop |
|
1646 |
||
1647 |
end if ! neiloc |
|
1648 |
end do face_loop |
|
1649 |
end do nodal_loop_i |
|
1650 |
||
1651 |
! if we need the matrix then assemble it now
|
|
1652 |
if(assemble_advection_matrix) then |
|
1653 |
call addto(A_m, nodes, nodes, mat_local) |
|
1654 |
end if
|
|
1655 |
||
1656 |
if(assemble_diffusion) then |
|
1657 |
select case(tfield_options%diffusionscheme) |
|
1658 |
case(CV_DIFFUSION_BASSIREBAY) |
|
1659 |
||
1660 |
call addto(div_m, nodes, diffusivity_lglno, spread(grad_mat_local, 1, 1)) |
|
1661 |
||
1662 |
case(CV_DIFFUSION_ELEMENTGRADIENT) |
|
1663 |
||
1664 |
call addto(D_m, nodes, nodes, diff_mat_local) |
|
1665 |
||
1666 |
end select
|
|
1667 |
end if
|
|
1668 |
||
1669 |
! assemble the rhs
|
|
1670 |
if(include_advection) then |
|
1671 |
call addto(rhs, nodes, rhs_local) |
|
1672 |
end if
|
|
1673 |
||
1674 |
end do element_loop |
|
1675 |
||
1676 |
! allocate memory for bc information
|
|
1677 |
allocate(tfield_bc_type(surface_element_count(tfield))) |
|
1678 |
||
1679 |
! get the fields over the surface containing the bcs
|
|
1680 |
call get_entire_boundary_condition(tfield, (/ & |
|
1681 |
"weakdirichlet", & |
|
1682 |
"neumann ", & |
|
1668
by cwilson
Changing the keyword boundary condition type 'periodic' to 'internal' to avoid confusion. Also if an internal bc is found an error is no longer thrown by get_entire_boundary_condition, instead the prescribed bc is respected and the fact that it may be on a periodic boundary is ignored. As with Stephan's commit this should NOT be taken as an indication that internal bcs work. |
1683 |
"internal ", & |
3408.1.66
by Christian Jacobs
Extended Field_Equations_CV.F90 and Boundary_Conditions_From_Options.F90 to handle the new 'influx' boundary condition. This essentially gets treated the same way as a Neumann BC, but weakly applies u.n = 0 so we get the correct influx. |
1684 |
"zero_flux ", & |
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1685 |
"flux "/), tfield_bc, tfield_bc_type) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1686 |
if(include_density) then |
1687 |
allocate(tdensity_bc_type(surface_element_count(tdensity))) |
|
1688 |
call get_entire_boundary_condition(tdensity, (/"weakdirichlet"/), tdensity_bc, tdensity_bc_type) |
|
1689 |
end if
|
|
1690 |
||
1691 |
! loop over the surface elements
|
|
1692 |
surface_element_loop: do sele = 1, surface_element_count(tfield) |
|
1693 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1694 |
if((tfield_bc_type(sele)==BC_TYPE_INTERNAL)) cycle |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1695 |
|
1696 |
ele = face_ele(x, sele) |
|
1697 |
x_ele = ele_val(x, ele) |
|
1698 |
x_ele_bdy = face_val(x, sele) |
|
1699 |
nodes_bdy=face_global_nodes(tfield, sele) |
|
1700 |
||
1701 |
! calculate the determinant and orientated normal
|
|
1702 |
call transform_cvsurf_facet_to_physical(x_ele, x_ele_bdy, & |
|
1703 |
x_cvbdyshape, normal_bdy, detwei_bdy) |
|
1704 |
||
1705 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
|
1706 |
diffusivity_nodes_bdy=face_global_nodes(diffusivity,sele) |
|
1707 |
! diffusivity may be on a lower degree mesh than the field... to allow that
|
|
1708 |
! without changing the assembly code for each specific case we construct
|
|
1709 |
! a mapping to the global nodes that is consistent with the local node
|
|
1710 |
! numbering of the parent field.
|
|
1711 |
! warning: this is not ideal as it will require more csr_pos's
|
|
1712 |
! but its more intended as a proof of concept
|
|
1713 |
do iloc = 1, size(diffusivity_lglno_bdy), size(diffusivity_nodes_bdy) |
|
1714 |
diffusivity_lglno_bdy(iloc:iloc+size(diffusivity_nodes_bdy)-1)=diffusivity_nodes_bdy |
|
1715 |
end do
|
|
1716 |
end if
|
|
1717 |
||
1718 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_ELEMENTGRADIENT)) then |
|
1719 |
! call transform_to_physical(x_ele_bdy, x_cvbdyshape_full, &
|
|
1720 |
! m=t_cvbdyshape_full, dm_t=dt_ft)
|
|
1721 |
dt_ft = 0.0 ! at the moment its not possible to get the full gradient |
|
1722 |
! so until this is fixed we're just going to have to assume
|
|
1723 |
! zero neumann on outflow boundaries
|
|
1724 |
diffusivity_gi_f = face_val_at_quad(diffusivity, sele, diff_cvbdyshape_full) |
|
1725 |
end if
|
|
1726 |
||
1727 |
! deal with bcs for tfield
|
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1728 |
if(tfield_bc_type(sele)==BC_TYPE_WEAKDIRICHLET .or. tfield_bc_type(sele)==BC_TYPE_FLUX) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1729 |
ghost_tfield_ele_bdy=ele_val(tfield_bc, sele) |
1730 |
else
|
|
1731 |
ghost_tfield_ele_bdy=face_val(tfield, sele) |
|
1732 |
end if
|
|
1733 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1734 |
if(tfield_bc_type(sele)==BC_TYPE_WEAKDIRICHLET) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1735 |
ghost_oldtfield_ele_bdy=ele_val(tfield_bc, sele) ! not considering time varying bcs yet |
1736 |
else
|
|
1737 |
ghost_oldtfield_ele_bdy=face_val(oldtfield, sele) |
|
1738 |
end if
|
|
1739 |
||
1740 |
if(include_advection) then |
|
1741 |
u_bdy_f=face_val_at_quad(advu, sele, u_cvbdyshape) |
|
1742 |
if(move_mesh) ug_bdy_f=face_val_at_quad(ug, sele, ug_cvbdyshape) |
|
1743 |
||
1744 |
tfield_ele_bdy=face_val(tfield, sele) |
|
1745 |
oldtfield_ele_bdy=face_val(oldtfield, sele) |
|
1746 |
||
1747 |
if(include_density) then |
|
1748 |
! deal with bcs for tdensity
|
|
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1749 |
if(tdensity_bc_type(sele)==BC_TYPE_WEAKDIRICHLET) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1750 |
ghost_tdensity_ele_bdy=ele_val(tdensity_bc, sele) |
1751 |
else
|
|
1752 |
ghost_tdensity_ele_bdy=face_val(tdensity, sele) |
|
1753 |
end if
|
|
1754 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1755 |
if(tdensity_bc_type(sele)==BC_TYPE_WEAKDIRICHLET) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1756 |
ghost_oldtdensity_ele_bdy=ele_val(tdensity_bc, sele) ! not considering time varying bcs yet |
1757 |
else
|
|
1758 |
ghost_oldtdensity_ele_bdy=face_val(oldtdensity, sele) |
|
1759 |
end if
|
|
1760 |
||
1761 |
tdensity_ele_bdy=face_val(tdensity, sele) |
|
1762 |
oldtdensity_ele_bdy=face_val(oldtdensity, sele) |
|
1763 |
end if
|
|
1764 |
end if
|
|
1765 |
||
1766 |
if(assemble_diffusion) then |
|
1767 |
ghost_gradtfield_ele_bdy = ele_val(tfield_bc, sele) |
|
1768 |
end if
|
|
1769 |
||
1770 |
! zero small matrices for assembly
|
|
1771 |
grad_mat_local_bdy = 0.0 |
|
1772 |
grad_rhs_local_bdy = 0.0 |
|
1773 |
div_rhs_local_bdy = 0.0 |
|
1774 |
mat_local_bdy = 0.0 |
|
1775 |
rhs_local_bdy = 0.0 |
|
1776 |
diff_mat_local_bdy = 0.0 |
|
1777 |
||
1778 |
! loop over the nodes on this surface element
|
|
1779 |
surface_nodal_loop_i: do iloc = 1, tfield%mesh%faces%shape%loc |
|
1780 |
||
1781 |
! loop over the faces in this surface element
|
|
1782 |
surface_face_loop: do face = 1, cvfaces%sfaces |
|
1783 |
||
1784 |
! is this face a neighbour of iloc?
|
|
1785 |
if(cvfaces%sneiloc(iloc,face)/=0) then |
|
1786 |
||
1787 |
! loop over the gauss pts on this face
|
|
1788 |
surface_quadrature_loop: do gi = 1, cvfaces%shape%ngi |
|
1789 |
||
1790 |
! global gauss point index
|
|
1791 |
ggi = (face-1)*cvfaces%shape%ngi + gi |
|
1792 |
||
1793 |
if(include_advection) then |
|
1794 |
||
1795 |
! u.n
|
|
1796 |
if(move_mesh) then |
|
1797 |
divudotn = dot_product(u_bdy_f(:,ggi), normal_bdy(:,ggi)) |
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1798 |
if((tfield_bc_type(sele)==BC_TYPE_ZEROFLUX .or. tfield_bc_type(sele)==BC_TYPE_FLUX)) then |
3408.1.97
by Christian Jacobs
To use the new influx boundary condition (CV only at the moment), users no longer need to enable Diffusivity and set it to zero to get the equation in the correct form. |
1799 |
! If we have zero flux, or a flux BC, set u.n = 0
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1800 |
udotn = 0.0 |
1801 |
else
|
|
1802 |
udotn = dot_product((u_bdy_f(:,ggi)-ug_bdy_f(:,ggi)), normal_bdy(:,ggi)) |
|
1803 |
end if
|
|
1804 |
else
|
|
1805 |
divudotn = dot_product(u_bdy_f(:,ggi), normal_bdy(:,ggi)) |
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1806 |
if((tfield_bc_type(sele)==BC_TYPE_ZEROFLUX .or. tfield_bc_type(sele)==BC_TYPE_FLUX)) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1807 |
udotn = 0.0 |
1808 |
else
|
|
1809 |
udotn = divudotn |
|
1810 |
end if
|
|
1811 |
end if
|
|
1812 |
|
|
1813 |
if(udotn>0) then |
|
1814 |
income=0.0 ! flow leaving the domain |
|
1815 |
else
|
|
1816 |
income=1.0 ! flow entering the domain |
|
1817 |
end if
|
|
1818 |
||
1819 |
! as we're on the boundary it's not possible to use "high order" methods so just
|
|
1820 |
! default to the pivotted solution method (first order upwinding)
|
|
1821 |
! if the flow is incoming then use the bc ghost values
|
|
1822 |
! if the flow is outgoing then use the surface nodes value
|
|
1823 |
||
1824 |
! for tfield
|
|
1825 |
tfield_face_val = income*ghost_tfield_ele_bdy(iloc) + (1.-income)*tfield_ele_bdy(iloc) |
|
1826 |
oldtfield_face_val = income*ghost_oldtfield_ele_bdy(iloc) + (1.-income)*oldtfield_ele_bdy(iloc) |
|
1827 |
||
1828 |
if(include_density) then |
|
1829 |
! for tdensity
|
|
1830 |
tdensity_face_val = income*ghost_tdensity_ele_bdy(iloc) + (1.-income)*tdensity_ele_bdy(iloc) |
|
1831 |
oldtdensity_face_val = income*ghost_oldtdensity_ele_bdy(iloc) + (1.-income)*oldtdensity_ele_bdy(iloc) |
|
1832 |
||
1833 |
tdensity_theta_val = tdensity_options%theta*tdensity_face_val + (1.-tdensity_options%theta)*oldtdensity_face_val |
|
1834 |
||
1835 |
if(assemble_advection_matrix) then |
|
1836 |
! if iloc is the donor we can do this implicitly
|
|
1837 |
mat_local_bdy(iloc) = mat_local_bdy(iloc) & |
|
1838 |
+ ptheta*detwei_bdy(ggi)*udotn*(1.-income)*tdensity_theta_val & |
|
1839 |
- ptheta*(1.-beta)*detwei_bdy(ggi)*divudotn*tdensity_theta_val |
|
1840 |
end if
|
|
1841 |
||
1842 |
! but we can't if it's the downwind
|
|
1843 |
rhs_local_bdy(iloc) = rhs_local_bdy(iloc) & |
|
1844 |
- ptheta*udotn*detwei_bdy(ggi)*income*tdensity_theta_val*ghost_tfield_ele_bdy(iloc) & |
|
1845 |
- (1.-ptheta)*udotn*detwei_bdy(ggi)*tdensity_theta_val*oldtfield_face_val & |
|
1846 |
+ (1.-ptheta)*(1.-beta)*divudotn*detwei_bdy(ggi)*tdensity_theta_val*oldtfield_ele_bdy(iloc) |
|
1847 |
else
|
|
1848 |
if(assemble_advection_matrix) then |
|
1849 |
! if iloc is the donor we can do this implicitly
|
|
1850 |
mat_local_bdy(iloc) = mat_local_bdy(iloc) & |
|
1851 |
+ ptheta*detwei_bdy(ggi)*udotn*(1.-income) & |
|
1852 |
- ptheta*(1.-beta)*detwei_bdy(ggi)*divudotn |
|
1853 |
end if
|
|
1854 |
||
1855 |
! but we can't if it's the downwind
|
|
1856 |
rhs_local_bdy(iloc) = rhs_local_bdy(iloc) & |
|
1857 |
- ptheta*udotn*detwei_bdy(ggi)*income*ghost_tfield_ele_bdy(iloc) & |
|
1858 |
- (1.-ptheta)*udotn*detwei_bdy(ggi)*oldtfield_face_val & |
|
1859 |
+ (1.-ptheta)*(1.-beta)*divudotn*detwei_bdy(ggi)*oldtfield_ele_bdy(iloc) |
|
1860 |
end if
|
|
1861 |
end if
|
|
1862 |
||
3408.1.97
by Christian Jacobs
To use the new influx boundary condition (CV only at the moment), users no longer need to enable Diffusivity and set it to zero to get the equation in the correct form. |
1863 |
! If we have a flux boundary condition, then we need to set up the equation so that
|
1864 |
! d(field)/dt = flux_val_at_boundary
|
|
1865 |
! We add the flux_val_at_boundary contribution to rhs_local_bdy, after setting the advection
|
|
1866 |
! and diffusion terms to zero at the boundary.
|
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1867 |
if(tfield_bc_type(sele)==BC_TYPE_FLUX) then |
3408.1.97
by Christian Jacobs
To use the new influx boundary condition (CV only at the moment), users no longer need to enable Diffusivity and set it to zero to get the equation in the correct form. |
1868 |
rhs_local_bdy(iloc) = rhs_local_bdy(iloc) + detwei_bdy(ggi)*ghost_tfield_ele_bdy(iloc) |
1869 |
end if
|
|
1870 |
||
3408.1.102
by Christian Jacobs
Removing the unnecessary second condition in "if(assemble_diffusion .and. tfield_bc_type(sele)/=BC_TYPE_FLUX)". Thanks to Cian for this one. |
1871 |
if(assemble_diffusion) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1872 |
|
1873 |
select case(tfield_options%diffusionscheme) |
|
1874 |
case(CV_DIFFUSION_BASSIREBAY) |
|
1875 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1876 |
if(tfield_bc_type(sele)==BC_TYPE_WEAKDIRICHLET) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1877 |
! assemble grad_rhs
|
1878 |
||
1879 |
grad_rhs_local_bdy(:, iloc) = grad_rhs_local_bdy(:,iloc) & |
|
1880 |
-detwei_bdy(ggi)*normal_bdy(:,ggi)*ghost_tfield_ele_bdy(iloc) |
|
1881 |
||
1882 |
! when assembling a divergence operator you need this:
|
|
1883 |
! (but not when its a gradient transposed operator)
|
|
1884 |
dimension_loop2: do dim = 1, mesh_dim(tfield) |
|
1885 |
! assemble matrix
|
|
1886 |
grad_mat_local_bdy(dim, iloc) = grad_mat_local_bdy(dim, iloc) & |
|
1887 |
+detwei_bdy(ggi)*normal_bdy(dim,ggi) |
|
1888 |
end do dimension_loop2 |
|
1889 |
||
1890 |
else
|
|
1891 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1892 |
if(tfield_bc_type(sele)==BC_TYPE_NEUMANN) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1893 |
|
1894 |
! assemble div_rhs
|
|
1895 |
div_rhs_local_bdy(iloc) = div_rhs_local_bdy(iloc) & |
|
1896 |
-detwei_bdy(ggi)*ghost_gradtfield_ele_bdy(iloc) |
|
1897 |
||
1898 |
end if
|
|
1899 |
||
1900 |
||
1901 |
! when assembling a gradient transposed operator you need this:
|
|
1902 |
! (but not when its a divergence operator)
|
|
1903 |
! dimension_loop2: do dim = 1, mesh_dim(tfield)
|
|
1904 |
! grad_mat_local_bdy(dim, iloc) = grad_mat_local_bdy(dim, iloc) &
|
|
1905 |
! -detwei_bdy(ggi)*normal_bdy(dim,ggi)
|
|
1906 |
! end do dimension_loop2
|
|
1907 |
||
1908 |
end if
|
|
1909 |
||
1910 |
case(CV_DIFFUSION_ELEMENTGRADIENT) |
|
1911 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1912 |
if(tfield_bc_type(sele)==BC_TYPE_NEUMANN) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1913 |
|
1914 |
div_rhs_local_bdy(iloc) = div_rhs_local_bdy(iloc) & |
|
1915 |
-detwei_bdy(ggi)*ghost_gradtfield_ele_bdy(iloc) |
|
1916 |
||
1917 |
else
|
|
1918 |
||
1919 |
! because transform to physical doesn't give the full gradient at a face
|
|
1920 |
! yet this can't be done so we're going to have to assume zero neumann
|
|
1921 |
! at outflow faces
|
|
1922 |
! do dloc= 1,tfield%mesh%faces%shape%loc
|
|
1923 |
!
|
|
1924 |
! ! n_i K_{ij} dT/dx_j
|
|
1925 |
! diff_mat_local_bdy(iloc, dloc) = diff_mat_local_bdy(iloc,dloc) + &
|
|
1926 |
! sum(matmul(diffusivity_gi_f(:,:,ggi), dt_ft(dloc, ggi, :))*normal_bdy(:,ggi), 1)&
|
|
1927 |
! *detwei_bdy(ggi)
|
|
1928 |
!
|
|
1929 |
! end do
|
|
1930 |
||
1931 |
end if
|
|
1932 |
||
1933 |
end select
|
|
1934 |
||
1935 |
end if
|
|
1936 |
||
1937 |
end do surface_quadrature_loop |
|
1938 |
||
1939 |
end if ! sneiloc |
|
1940 |
||
1941 |
end do surface_face_loop |
|
1942 |
||
1943 |
end do surface_nodal_loop_i |
|
1944 |
||
1945 |
! assemble matrix
|
|
1946 |
if(assemble_advection_matrix) then |
|
1947 |
call addto_diag(A_m, nodes_bdy, mat_local_bdy) |
|
1948 |
end if
|
|
1949 |
||
1950 |
if(assemble_diffusion) then |
|
1951 |
select case(tfield_options%diffusionscheme) |
|
1952 |
case(CV_DIFFUSION_BASSIREBAY) |
|
1953 |
||
1954 |
do dim = 1, mesh_dim(tfield) |
|
1955 |
do iloc = 1, size(grad_mat_local_bdy,2) |
|
1956 |
call addto(div_m, 1, dim, nodes_bdy(iloc), diffusivity_lglno_bdy(iloc), & |
|
1957 |
grad_mat_local_bdy(dim,iloc)) |
|
1958 |
end do
|
|
1959 |
end do
|
|
1960 |
call addto(grad_rhs, diffusivity_lglno_bdy, grad_rhs_local_bdy) |
|
1961 |
||
1962 |
call addto(diff_rhs, nodes_bdy, div_rhs_local_bdy) |
|
1963 |
||
1964 |
case(CV_DIFFUSION_ELEMENTGRADIENT) |
|
1965 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1966 |
if(tfield_bc_type(sele)==BC_TYPE_WEAKDIRICHLET) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1967 |
|
1968 |
! assume zero neumann for the moment
|
|
1969 |
! call addto(diff_rhs, nodes_bdy, -matmul(diff_mat_local_bdy, ghost_gradtfield_ele_bdy))
|
|
1970 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
1971 |
elseif(tfield_bc_type(sele)==BC_TYPE_NEUMANN) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1972 |
|
1973 |
call addto(diff_rhs, nodes_bdy, div_rhs_local_bdy) |
|
1974 |
||
1975 |
else
|
|
1976 |
||
1977 |
! assume zero neumann for the moment
|
|
1978 |
! call addto(D_m, nodes_bdy, nodes_bdy, diff_mat_local_bdy)
|
|
1979 |
||
1980 |
end if
|
|
1981 |
||
1982 |
end select
|
|
1983 |
end if
|
|
1984 |
||
3408.1.97
by Christian Jacobs
To use the new influx boundary condition (CV only at the moment), users no longer need to enable Diffusivity and set it to zero to get the equation in the correct form. |
1985 |
! assemble RHS - this contains the advection boundary terms, or
|
1986 |
! a RHS term from the flux boundary condition, so that
|
|
1987 |
! we have the equation in the form d(field)/dt = flux_val
|
|
3408.1.99
by Christian Jacobs
Renaming the "influx" boundary condition to "flux". Thanks to Stephan for the feedback leading to this commit, as well as r3505. |
1988 |
if(include_advection .or. tfield_bc_type(sele)==BC_TYPE_FLUX) then |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1989 |
call addto(rhs, nodes_bdy, rhs_local_bdy) |
1990 |
end if
|
|
1991 |
||
1992 |
end do surface_element_loop |
|
1993 |
||
1994 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
|
1995 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1996 |
! assemble div_m and q_cvmass into the final D_m
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
1997 |
call assemble_bassirebay_diffusion_m_cv(D_m, diff_rhs, & |
1998 |
div_m, grad_rhs, & |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
1999 |
diffusivity, q_cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2000 |
! ElementGradient assembles D_m directly so no need for a step like this
|
2001 |
||
2002 |
end if
|
|
2003 |
||
2004 |
deallocate(tfield_bc_type) |
|
2005 |
call deallocate(tfield_bc) |
|
2006 |
call deallocate(tfield_upwind) |
|
2007 |
call deallocate(oldtfield_upwind) |
|
2008 |
if(include_density) then |
|
2009 |
deallocate(tdensity_bc_type) |
|
2010 |
call deallocate(tdensity_bc) |
|
2011 |
call deallocate(tdensity_upwind) |
|
2012 |
call deallocate(oldtdensity_upwind) |
|
2013 |
end if
|
|
2014 |
||
2015 |
if(assemble_diffusion.and.(tfield_options%diffusionscheme==CV_DIFFUSION_BASSIREBAY)) then |
|
2016 |
call deallocate(div_m) |
|
2017 |
call deallocate(grad_rhs) |
|
2018 |
end if
|
|
2019 |
||
2020 |
ewrite(1, *) "Exiting assemble_advectiondiffusion_m_cv" |
|
2021 |
||
2022 |
end subroutine assemble_advectiondiffusion_m_cv |
|
2023 |
||
2024 |
subroutine assemble_bassirebay_diffusion_m_cv(D_m, diff_rhs, & |
|
2025 |
div_m, grad_rhs, & |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2026 |
diffusivity, q_cvmass) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2027 |
|
2028 |
type(csr_matrix), intent(inout) :: D_m |
|
2029 |
type(scalar_field), intent(inout) :: diff_rhs |
|
2030 |
||
2031 |
type(block_csr_matrix), intent(inout) :: div_m |
|
2032 |
type(vector_field), intent(inout) :: grad_rhs |
|
2033 |
||
2034 |
type(tensor_field), intent(in) :: diffusivity |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2035 |
type(scalar_field), intent(in) :: q_cvmass |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2036 |
|
2037 |
logical :: isotropic |
|
2038 |
||
2039 |
ewrite(1,*) 'in assemble_bassirebay_diffusion_m_cv' |
|
2040 |
||
2041 |
! an optimisation that reduces the number of matrix multiplies if we're isotropic
|
|
2042 |
isotropic=isotropic_field(diffusivity) |
|
2043 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2044 |
call mult_div_tensorinvscalar_div_T(D_m, div_m, diffusivity, q_cvmass, div_m, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2045 |
isotropic) |
2046 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2047 |
call mult_div_tensorinvscalar_vector(diff_rhs, div_m, diffusivity, q_cvmass, grad_rhs, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2048 |
isotropic) |
2049 |
||
2050 |
end subroutine assemble_bassirebay_diffusion_m_cv |
|
2051 |
!************************************************************************
|
|
2052 |
||
2053 |
!************************************************************************
|
|
2054 |
! subroutines dealing coupled control volume advection
|
|
2055 |
! coupled wrapper
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2056 |
subroutine coupled_cv_field_eqn(state, global_it) |
2057 |
!!< This subroutine wraps the solve for groups of interdependent coupled fields.
|
|
2058 |
||
2059 |
!! bucket full of fields from all materials
|
|
2060 |
type(state_type), dimension(:), intent(inout) :: state |
|
2061 |
!! global iteration - passed in to be output to convergence file
|
|
2062 |
integer, intent(in) :: global_it |
|
2063 |
||
2064 |
type(scalar_field), pointer :: sfield |
|
2065 |
||
2066 |
!! list of fields that use the coupled_cv spatial_discretisation
|
|
2067 |
character(len=FIELD_NAME_LEN), dimension(:), allocatable :: field_name_list |
|
2068 |
!! number of fields with the same name in different states that are therefore assumed to be interdependent
|
|
2069 |
integer, dimension(:), allocatable :: field_numbers |
|
2070 |
||
2071 |
integer :: i, f, c, nfields, nfield_groups |
|
2072 |
||
2073 |
ewrite(1,*) 'in coupled_cv_field_eqn' |
|
2074 |
||
2075 |
! find the number of fields in all states (assumed to be in material_phases) that use the coupled_cv
|
|
2076 |
! this is the maximum possible of fields we'll have to actually solve for (in reality will be fewer)
|
|
2077 |
nfields = option_count("/material_phase/scalar_field/prognostic/spatial_discretisation/coupled_cv") |
|
2078 |
||
2079 |
ewrite(2,*) 'nfields = ', nfields |
|
2080 |
||
2081 |
allocate(field_name_list(nfields)) |
|
2082 |
allocate(field_numbers(nfields)) |
|
2083 |
field_name_list = "" |
|
2084 |
field_numbers = 0 |
|
2085 |
||
2086 |
! nfield_groups is the actual number of field groups we need to solve for
|
|
2087 |
nfield_groups = 0 |
|
2088 |
do i = 1, size(state) |
|
2089 |
||
2090 |
do f = 1, scalar_field_count(state(i)) |
|
2091 |
||
2092 |
sfield => extract_scalar_field(state(i), f) |
|
2093 |
if(have_option(trim(sfield%option_path)//"/prognostic/spatial_discretisation/coupled_cv")) then |
|
2094 |
||
2095 |
name_check_loop: do c = 1, nfields |
|
2096 |
if(trim(sfield%name)==trim(field_name_list(c))) exit name_check_loop |
|
2097 |
end do name_check_loop |
|
2098 |
||
2099 |
if(c>nfields) then |
|
2100 |
! not yet in the list so add it
|
|
2101 |
nfield_groups = nfield_groups + 1 |
|
2102 |
field_name_list(nfield_groups) = trim(sfield%name) |
|
2103 |
field_numbers(nfield_groups) = 1 |
|
2104 |
else
|
|
2105 |
! found in list, increment number of fields
|
|
2106 |
assert(c<=nfield_groups) |
|
2107 |
field_numbers(c) = field_numbers(c) + 1 |
|
2108 |
end if
|
|
2109 |
||
2110 |
end if
|
|
2111 |
||
2112 |
end do
|
|
2113 |
||
2114 |
end do
|
|
2115 |
|
|
2116 |
ewrite(2,*) 'nfield_groups = ', nfield_groups |
|
2117 |
||
2118 |
do i = 1, nfield_groups |
|
2119 |
assert(field_numbers(i)>0) |
|
2120 |
call solve_coupled_cv(trim(field_name_list(i)), field_numbers(i), state, global_it) |
|
2121 |
end do
|
|
2122 |
||
2123 |
deallocate(field_name_list) |
|
2124 |
deallocate(field_numbers) |
|
2125 |
||
2126 |
end subroutine coupled_cv_field_eqn |
|
2127 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2128 |
! coupled solution:
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2129 |
subroutine solve_coupled_cv(field_name, nfields, state, global_it) |
2130 |
!!< Construct and solve the advection equation for the given
|
|
2131 |
!!< field using coupled (i.e. interdependent face values) control volumes.
|
|
2132 |
||
2133 |
!! Name of the field to be solved for.
|
|
2134 |
character(len=*), intent(in) :: field_name |
|
2135 |
!! Number of interdependent fields (assumed to have the same name and be in different states)
|
|
2136 |
integer :: nfields |
|
2137 |
!! Collection of fields defining system state.
|
|
2138 |
type(state_type), dimension(:), intent(inout) :: state |
|
2139 |
!! global iteration number - passed in so it can be output to file
|
|
2140 |
integer, intent(in) :: global_it |
|
2141 |
||
2142 |
! Field to be solved for (plus its old and globally iterated versions)
|
|
2143 |
type(scalar_field_pointer), dimension(nfields) :: tfield, oldtfield |
|
2144 |
type(scalar_field), pointer :: it_tfield |
|
2145 |
type(scalar_field), pointer :: tmpfield |
|
2146 |
! Density fields associated with tfield's equation (i.e. if its not pure advection)
|
|
2147 |
type(scalar_field_pointer), dimension(nfields) :: tdensity, oldtdensity |
|
2148 |
! Coordinate field
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2149 |
type(vector_field), pointer :: x, x_old, x_new |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2150 |
type(vector_field) :: x_tfield |
2151 |
||
2152 |
type(scalar_field_pointer), dimension(nfields) :: source, absorption |
|
2153 |
||
2154 |
! Change in tfield over one timestep.
|
|
2155 |
type(scalar_field), dimension(nfields) :: delta_tfield |
|
2156 |
||
2157 |
! LHS equation matrix.
|
|
2158 |
! Advection matrix
|
|
2159 |
type(csr_matrix), dimension(nfields) :: M, A_m |
|
2160 |
! sparsity structure to construct the matrices with
|
|
2161 |
type(csr_sparsity), pointer :: mesh_sparsity, mesh_sparsity_x |
|
2162 |
||
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2163 |
! Right hand side vector, cv mass matrix,
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2164 |
! locally iterated field (for advection iterations)
|
2165 |
! and local old field (for subcycling)
|
|
2166 |
type(scalar_field), dimension(nfields) :: rhs, advit_tfield |
|
2167 |
type(scalar_field_pointer), dimension(nfields) :: l_old_tfield |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2168 |
type(scalar_field), dimension(nfields) :: cvmass |
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2169 |
type(scalar_field), pointer :: t_abs_src_cvmass |
2170 |
type(scalar_field_pointer), dimension(nfields) :: t_cvmass |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2171 |
type(scalar_field) :: t_cvmass_old, t_cvmass_new |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
2172 |
|
3930.1.4
by Brendan Tollit
Remove not required code that was added to this branch |
2173 |
! Porosity field
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2174 |
type(scalar_field) :: porosity_theta |
2175 |
type(scalar_field), dimension(nfields), target :: t_cvmass_with_porosity |
|
2176 |
logical, dimension(nfields) :: include_porosity |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2177 |
|
2178 |
! local copy of option_path for solution field
|
|
2179 |
character(len=OPTION_PATH_LEN), dimension(nfields) :: option_path |
|
2180 |
character(len=OPTION_PATH_LEN), dimension(nfields) :: tdensity_option_path |
|
2181 |
||
2182 |
! number of advection iterations and subcycles
|
|
2183 |
integer, dimension(nfields) :: adv_iterations, no_subcycles |
|
2184 |
! iterators
|
|
2185 |
integer :: adv_it, i, p, f, sub |
|
2186 |
! state indices
|
|
2187 |
integer, dimension(nfields) :: state_indices, tmp_state_indices, priorities |
|
2188 |
! time (to output to file), timestep, iterations tolerance, subcycling timestep
|
|
2189 |
real :: time, dt, sub_dt |
|
2190 |
real, dimension(nfields) :: error |
|
2191 |
real, dimension(nfields) :: adv_tolerance |
|
2192 |
! construct the matrix?
|
|
2193 |
logical, dimension(nfields) :: getmat |
|
2194 |
||
2195 |
! degree of quadrature to use on each control volume face
|
|
2196 |
integer :: quaddegree |
|
2197 |
! control volume face information
|
|
2198 |
type(cv_faces_type) :: cvfaces |
|
2199 |
! control volume shape function for volume and boundary
|
|
2200 |
type(element_type) :: u_cvshape, u_cvbdyshape |
|
2201 |
type(element_type) :: x_cvshape, x_cvbdyshape |
|
2202 |
type(element_type) :: t_cvshape |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2203 |
type(element_type) :: ug_cvshape, ug_cvbdyshape |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2204 |
|
2205 |
! options wrappers for tfield and tdensity
|
|
2206 |
type(cv_options_type), dimension(nfields) :: tfield_options, tdensity_options |
|
2207 |
||
2208 |
! a dummy density in case we're solving for Advection
|
|
2209 |
type(scalar_field), pointer :: dummydensity, dummyscalar |
|
2210 |
! somewhere to put strings temporarily
|
|
2211 |
character(len=FIELD_NAME_LEN) :: tmpstring |
|
2212 |
! what equation type are we solving for?
|
|
2213 |
integer :: equation_type |
|
2214 |
! success indicators?
|
|
2215 |
integer :: stat |
|
2216 |
integer, dimension(nfields) :: cfl_sub_stat |
|
2217 |
! the courant number field
|
|
2218 |
type(scalar_field) :: cfl_no |
|
2219 |
! nonlinear and grid velocities
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2220 |
type(vector_field), pointer :: nu, ug |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2221 |
! advection velocity
|
2222 |
type(vector_field) :: advu |
|
2223 |
! assume explicitness?
|
|
2224 |
logical, dimension(nfields) :: explicit |
|
2225 |
! if we're subcycling how fast can we go?
|
|
2226 |
real, dimension(nfields) :: max_sub_cfl |
|
2227 |
real :: max_cfl |
|
2228 |
||
2229 |
ewrite(1,*) 'in solve_coupled_cv' |
|
2230 |
ewrite(2,*) 'solving for '//trim(field_name)//' '//int2str(nfields)//' times' |
|
2231 |
||
2232 |
! find out where the fields are
|
|
2233 |
f = 0 |
|
2234 |
tmp_state_indices = 0 |
|
2235 |
priorities = 0 |
|
2236 |
do i = 1, size(state) |
|
2237 |
tmpfield=>extract_scalar_field(state(i), trim(field_name)) |
|
2238 |
||
2239 |
if(have_option(trim(tmpfield%option_path)//"/prognostic/spatial_discretisation/coupled_cv")) then |
|
2240 |
f = f + 1 |
|
2241 |
call get_option(trim(tmpfield%option_path)//"/prognostic/priority", priorities(f)) |
|
2242 |
tmp_state_indices(f) = i |
|
2243 |
end if
|
|
2244 |
end do
|
|
2245 |
||
2246 |
assert(f==nfields) |
|
2247 |
||
2248 |
! now work out the right order
|
|
2249 |
f = 0 |
|
2250 |
state_indices = 0 |
|
2251 |
do p = maxval(priorities), minval(priorities), -1 |
|
2252 |
do i=1, nfields |
|
2253 |
if(priorities(i)==p) then |
|
2254 |
f = f + 1 |
|
2255 |
state_indices(f) = tmp_state_indices(i) |
|
2256 |
end if
|
|
2257 |
end do
|
|
2258 |
end do
|
|
2259 |
||
2260 |
assert(f==nfields) |
|
2261 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2262 |
include_diffusion = .false. |
2263 |
include_source = .false. |
|
2264 |
include_absorption = .false. |
|
2265 |
include_mass = .true. |
|
2266 |
include_advection = .true. |
|
2267 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2268 |
! allocate dummy density in case density field isn't needed (this can be a constant field!)
|
2269 |
allocate(dummydensity) |
|
2270 |
call allocate(dummydensity, tmpfield%mesh, name="DummyDensity", field_type=FIELD_TYPE_CONSTANT) |
|
2271 |
call set(dummydensity, 1.0) |
|
2272 |
dummydensity%option_path = "" |
|
2273 |
||
2274 |
! allocate dummy scalar in case source/absorption fields aren't needed (this can be a constant field!)
|
|
2275 |
allocate(dummyscalar) |
|
2276 |
call allocate(dummyscalar, tmpfield%mesh, name="DummyScalar", field_type=FIELD_TYPE_CONSTANT) |
|
2277 |
call zero(dummyscalar) |
|
2278 |
dummyscalar%option_path = "" |
|
2279 |
||
2280 |
! now extract everything in the right order
|
|
2281 |
do f = 1, nfields |
|
2282 |
ewrite(2,*) 'extracting '//trim(field_name)//' from state '//trim(state(state_indices(f))%name) |
|
2283 |
! the field we want to solve for
|
|
2284 |
tfield(f)%ptr => extract_scalar_field(state(state_indices(f)), trim(field_name)) |
|
2285 |
! its option path
|
|
2286 |
option_path(f)=tfield(f)%ptr%option_path |
|
2287 |
! its previous timelevel
|
|
2288 |
oldtfield(f)%ptr=>extract_scalar_field(state(state_indices(f)), "Old"//trim(field_name)) |
|
2289 |
! because fluidity resets tfield to oldtfield at the start of every
|
|
2290 |
! global iteration we need to undo this so that the control volume faces
|
|
2291 |
! are discretised using the most up to date values
|
|
2292 |
! therefore extract the iterated values:
|
|
2293 |
it_tfield=>extract_scalar_field(state(state_indices(f)), "Iterated"//trim(field_name)) |
|
2294 |
! and set tfield to them:
|
|
2295 |
call set(tfield(f)%ptr, it_tfield) |
|
2296 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2297 |
include_density = .false. |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2298 |
! find out equation type and hence if density is needed or not
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2299 |
equation_type=equation_type_index(trim(option_path(f))) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2300 |
select case(equation_type) |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2301 |
case(FIELD_EQUATION_ADVECTIONDIFFUSION) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2302 |
! density not needed so use a constant field for assembly
|
2303 |
tdensity(f)%ptr=>dummydensity |
|
2304 |
oldtdensity(f)%ptr=>dummydensity |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2305 |
case(FIELD_EQUATION_CONSERVATIONOFMASS, FIELD_EQUATION_REDUCEDCONSERVATIONOFMASS, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
2306 |
FIELD_EQUATION_INTERNALENERGY, FIELD_EQUATION_HEATTRANSFER ) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2307 |
call get_option(trim(option_path(f))//'/prognostic/equation[0]/density[0]/name', & |
2308 |
tmpstring) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2309 |
include_density = .true. |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2310 |
! density needed so extract the type specified in the input
|
2311 |
! ?? are there circumstances where this should be "Iterated"... need to be
|
|
2312 |
! careful with priority ordering
|
|
2313 |
tdensity(f)%ptr=>extract_scalar_field(state(state_indices(f)), trim(tmpstring)) |
|
2314 |
! halo exchange? - not currently necessary when suboptimal halo exchange if density
|
|
2315 |
! is solved for with this subroutine and the correct priority ordering.
|
|
2316 |
oldtdensity(f)%ptr=>extract_scalar_field(state(state_indices(f)), "Old"//trim(tmpstring)) |
|
2317 |
end select
|
|
2318 |
! its option path
|
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
2319 |
if(have_option(trim(option_path(f))//'/prognostic/equation[0]/density[0]/discretisation_options')) then |
2320 |
tdensity_option_path(f)=trim(option_path(f))//'/prognostic/equation[0]/density[0]/discretisation_options' |
|
2321 |
else
|
|
2322 |
tdensity_option_path(f)=tdensity(f)%ptr%option_path |
|
2323 |
end if
|
|
2324 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2325 |
! now we can get the options for these fields
|
2326 |
! handily wrapped in a new type...
|
|
1948
by cwilson
1d control volumes for the 1d simple advection example. Unlike with other simplex elements this defaults to a locally_bound_upwind_value as projecting really makes no sense if no upwind scheme is selected. Ideally it would actually default to a pseudo_structured_upwind_value but this isn't available with periodic, works in nonperiodic 1d though - as apparently do all the other upwind schemes. |
2327 |
tfield_options(f)=get_cv_options(tfield(f)%ptr%option_path, tfield(f)%ptr%mesh%shape%numbering%family, mesh_dim(tfield(f)%ptr)) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2328 |
if(include_density) then |
1948
by cwilson
1d control volumes for the 1d simple advection example. Unlike with other simplex elements this defaults to a locally_bound_upwind_value as projecting really makes no sense if no upwind scheme is selected. Ideally it would actually default to a pseudo_structured_upwind_value but this isn't available with periodic, works in nonperiodic 1d though - as apparently do all the other upwind schemes. |
2329 |
tdensity_options(f)=get_cv_options(tdensity_option_path(f), tdensity(f)%ptr%mesh%shape%numbering%family, mesh_dim(tdensity(f)%ptr), coefficient_field=.true.) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2330 |
end if
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2331 |
|
2332 |
source(f)%ptr=>extract_scalar_field(state(state_indices(f)), trim(field_name)//"Source", stat=stat) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2333 |
if(stat==0) then |
2334 |
FLExit("Coupled CV broken with Sources") |
|
3868.3.1
by Brendan Tollit
Add an option to have the source directly added to the rhs. |
2335 |
! If Coupled CV is ever fixed to work with Sources then the
|
2336 |
! option source(f)%option_path//'/diagnostic/add_directly_to_rhs'
|
|
2337 |
! should be accounted for.
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2338 |
end if
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2339 |
if(stat/=0) source(f)%ptr=>dummyscalar |
2340 |
absorption(f)%ptr=>extract_scalar_field(state(state_indices(f)), trim(field_name)//"Absorption", stat=stat) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2341 |
if(stat==0) then |
2342 |
FLExit("Coupled CV broken with Absorptions") |
|
2343 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2344 |
if(stat/=0) absorption(f)%ptr=>dummyscalar |
2345 |
||
2346 |
! is this explicit?
|
|
2347 |
explicit(f)=have_option(trim(option_path(f))//"/prognostic/explicit") |
|
2348 |
||
2349 |
end do
|
|
2350 |
||
2351 |
! we assume that all fields are on the same mesh as for the method to the work the faces must intersect!
|
|
2352 |
do f = 2, nfields |
|
2353 |
assert(tfield(f)%ptr%mesh%shape%degree==tfield(1)%ptr%mesh%shape%degree) |
|
2354 |
assert(all(tfield(f)%ptr%mesh%ndglno==tfield(1)%ptr%mesh%ndglno)) |
|
2355 |
end do
|
|
2356 |
||
2357 |
! for now we assume as this is a effectively a multimaterial problem
|
|
2358 |
! that all fields are advected using the same velocity
|
|
2359 |
! on the same coordinate field
|
|
2360 |
! extract velocity and coordinate fields from state
|
|
2361 |
nu=>extract_vector_field(state(state_indices(1)), "NonlinearVelocity") |
|
2362 |
x=>extract_vector_field(state(state_indices(1)), "Coordinate") |
|
2363 |
x_tfield = get_coordinate_field(state(state_indices(1)), tfield(1)%ptr%mesh) |
|
2364 |
||
2365 |
! find relative velocity
|
|
2366 |
call allocate(advu, nu%dim, nu%mesh, "RelativeVelocity") |
|
2367 |
call set(advu, nu) |
|
2368 |
||
2369 |
! create control volume shape functions
|
|
2370 |
call get_option("/geometry/quadrature/controlvolume_surface_degree", & |
|
2371 |
quaddegree, default=1) |
|
2372 |
cvfaces=find_cv_faces(vertices=ele_vertices(tfield(1)%ptr, 1), & |
|
2373 |
dimension=mesh_dim(tfield(1)%ptr), & |
|
2374 |
polydegree=element_degree(tfield(1)%ptr, 1), & |
|
2375 |
quaddegree=quaddegree) |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
2376 |
u_cvshape=make_cv_element_shape(cvfaces, nu%mesh%shape) |
2377 |
x_cvshape=make_cv_element_shape(cvfaces, x%mesh%shape) |
|
2378 |
t_cvshape=make_cv_element_shape(cvfaces, tfield(1)%ptr%mesh%shape) |
|
2379 |
u_cvbdyshape=make_cvbdy_element_shape(cvfaces, nu%mesh%faces%shape) |
|
2380 |
x_cvbdyshape=make_cvbdy_element_shape(cvfaces, x%mesh%faces%shape) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2381 |
|
2382 |
! find the timestep
|
|
2383 |
call get_option("/timestepping/timestep", dt) |
|
2384 |
call get_option("/timestepping/current_time", time) ! so it can be output in the convergence file |
|
2385 |
||
2386 |
! allocate and retrieve the cfl no. if necessary
|
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2387 |
call cv_disc_get_cfl_no(option_path, & |
2388 |
state(state_indices(1)), tfield(1)%ptr%mesh, cfl_no, & |
|
2389 |
tdensity_option_path) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2390 |
|
2391 |
! get the mesh sparsity for the matrices
|
|
2392 |
mesh_sparsity => get_csr_sparsity_firstorder(state, tfield(1)%ptr%mesh, tfield(1)%ptr%mesh) |
|
2393 |
if(mesh_periodic(tfield(1)%ptr)) then |
|
2394 |
if((tfield_options(1)%upwind_scheme==CV_UPWINDVALUE_PROJECT_POINT).or.& |
|
2395 |
(tfield_options(1)%upwind_scheme==CV_UPWINDVALUE_PROJECT_GRAD)) then |
|
2396 |
mesh_sparsity_x => get_csr_sparsity_firstorder(state, x_tfield%mesh, x_tfield%mesh) |
|
2397 |
else
|
|
2398 |
mesh_sparsity_x => mesh_sparsity |
|
2399 |
end if
|
|
2400 |
else
|
|
2401 |
mesh_sparsity_x => mesh_sparsity |
|
2402 |
end if
|
|
2403 |
||
2404 |
||
2405 |
do f = 1, nfields |
|
2406 |
! allocate the lhs matrix
|
|
2407 |
if(.not.explicit(f)) then |
|
2408 |
call allocate(M(f), mesh_sparsity, name=trim(field_name)//"Matrix") |
|
2409 |
call zero(M(f)) |
|
2410 |
||
2411 |
! allocate the advection matrix
|
|
2412 |
call allocate(A_m(f), mesh_sparsity, name=trim(field_name)//int2str(f)//"AdvectionMatrix") |
|
2413 |
call zero(A_m(f)) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2414 |
else
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2415 |
call allocate(cvmass(f), tfield(1)%ptr%mesh, name=trim(field_name)//"LocalCVMass") |
2416 |
call zero(cvmass(f)) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2417 |
end if
|
2418 |
||
2419 |
! allocate the rhs of the equation
|
|
2420 |
call allocate(rhs(f), tfield(f)%ptr%mesh, name=trim(field_name)//int2str(f)//"RHS") |
|
2421 |
end do
|
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2422 |
|
2423 |
! find the cv mass that is used for the absorption and source terms
|
|
2424 |
t_abs_src_cvmass => get_cv_mass(state, tfield(1)%ptr%mesh) |
|
2425 |
ewrite_minmax(t_abs_src_cvmass) |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
2426 |
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2427 |
! find the cv mass that is used for the time term derivative - which may include the porosity
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
2428 |
do f = 1,nfields |
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2429 |
if (have_option(trim(complete_field_path(tfield(f)%ptr%option_path))//'/porosity')) then |
2430 |
include_porosity(f) = .true. |
|
3900.1.24
by Brendan Tollit
Final adjustments to not have FLExit/FLAbort's with if () statements. |
2431 |
|
3930.1.4
by Brendan Tollit
Remove not required code that was added to this branch |
2432 |
! get the porosity theta averaged field - this will allocate it
|
2433 |
call form_porosity_theta(porosity_theta, state(state_indices(f)), & |
|
2434 |
&option_path = trim(complete_field_path(tfield(f)%ptr%option_path))//'/porosity') |
|
2435 |
||
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2436 |
call allocate(t_cvmass_with_porosity(f), tfield(f)%ptr%mesh, name="CVMassWithPorosity") |
2437 |
call compute_cv_mass(x, t_cvmass_with_porosity(f), porosity_theta) |
|
2438 |
||
2439 |
call deallocate(porosity_theta) |
|
2440 |
||
2441 |
t_cvmass(f)%ptr => t_cvmass_with_porosity(f) |
|
2442 |
else
|
|
2443 |
include_porosity(f) = .false. |
|
2444 |
||
2445 |
t_cvmass(f)%ptr => t_abs_src_cvmass |
|
2446 |
end if
|
|
2447 |
ewrite_minmax(t_cvmass(f)%ptr) |
|
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
2448 |
end do
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2449 |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
2450 |
move_mesh = have_option("/mesh_adaptivity/mesh_movement") |
2451 |
if(move_mesh) then |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2452 |
FLExit("Moving meshes not fully set-up with coupled cv.") |
2453 |
if(.not.include_advection) then |
|
2454 |
FLExit("Moving the mesh but not including advection is not possible yet.") |
|
2455 |
end if
|
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2456 |
if (any(include_porosity)) then |
3900.1.5
by Brendan Tollit
Add an option to include a porosity field for control_volumes and |
2457 |
FLExit("Moving mesh not set up to work when including porosity") |
2458 |
end if
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2459 |
ewrite(2,*) "Moving mesh." |
2460 |
x_old=>extract_vector_field(state(1), "OldCoordinate") |
|
2461 |
x_new=>extract_vector_field(state(1), "IteratedCoordinate") |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2462 |
call allocate(t_cvmass_old, tfield(1)%ptr%mesh, name=trim(field_name)//"OldCVMass") |
2463 |
call allocate(t_cvmass_new, tfield(1)%ptr%mesh, name=trim(field_name)//"NewCVMass") |
|
2464 |
||
2465 |
call compute_cv_mass(x_old, t_cvmass_old) |
|
2466 |
call compute_cv_mass(x_new, t_cvmass_new) |
|
2467 |
ewrite_minmax(t_cvmass_old) |
|
2468 |
ewrite_minmax(t_cvmass_new) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2469 |
|
2470 |
ug=>extract_vector_field(state(1), "GridVelocity") |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
2471 |
ewrite_minmax(ug) |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2472 |
|
2162
by cwilson
Changes to the code to allow bubble elements (in 1d only p1+, in 2d p1+ and p2+, no 3d yet). |
2473 |
ug_cvshape=make_cv_element_shape(cvfaces, ug%mesh%shape) |
2474 |
ug_cvbdyshape=make_cvbdy_element_shape(cvfaces, ug%mesh%faces%shape) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2475 |
|
2476 |
else
|
|
2477 |
ewrite(2,*) "Not moving mesh." |
|
2478 |
ug_cvshape=u_cvshape |
|
2479 |
ug_cvbdyshape=u_cvbdyshape |
|
2480 |
call incref(ug_cvshape) |
|
2481 |
call incref(ug_cvbdyshape) |
|
400
by cwilson
Some work on moving meshes. Not quite right yet (in particular for non-conservative advection in general and for conservative advection where the grid velocity doesn't dissappear on the domain boundaries) but still hopefully an improvement on the current implementation. |
2482 |
end if
|
2483 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2484 |
do f = 1, nfields |
2485 |
! allocate a field to store the locally iterated values in
|
|
2486 |
call allocate(advit_tfield(f), tfield(f)%ptr%mesh, name="AdvIterated"//int2str(f)//trim(field_name)) |
|
2487 |
! allocate a field to use as the local old field for subcycling
|
|
2488 |
allocate(l_old_tfield(f)%ptr) |
|
2489 |
call allocate(l_old_tfield(f)%ptr, tfield(f)%ptr%mesh, name="LocalOld"//int2str(f)//trim(field_name)) |
|
2490 |
! when subcycling we're going to need to be starting each subcycle from the
|
|
2491 |
! "new" old value but I don't want to screw with old code by updating the actual
|
|
2492 |
! global timestep old value so lets create a copy now and update it instead
|
|
2493 |
call set(l_old_tfield(f)%ptr, oldtfield(f)%ptr) |
|
2494 |
||
2495 |
! allocate a field to store the change between the old and new values
|
|
2496 |
call allocate(delta_tfield(f), tfield(f)%ptr%mesh, name="Delta_"//int2str(f)//trim(field_name)) |
|
2497 |
call zero(delta_tfield(f)) ! Impose zero initial guess. |
|
2498 |
! Ensure delta_tfield inherits options from tfield for solver
|
|
2499 |
delta_tfield(f)%option_path = option_path(f) |
|
2500 |
end do
|
|
2501 |
||
2502 |
adv_iterations = 1 |
|
2503 |
adv_tolerance = 0.0 |
|
2504 |
no_subcycles = 1 |
|
2505 |
cfl_sub_stat = 1 |
|
2506 |
sub_dt=dt ! just in case I don't initialise this somehow |
|
2507 |
do f = 1, nfields |
|
2508 |
! find out how many iterations we'll be doing
|
|
2509 |
call get_option(trim(option_path(f))//"/prognostic/temporal_discretisation& |
|
2510 |
&/control_volumes/number_advection_iterations", & |
|
2511 |
adv_iterations(f), default=1) |
|
2512 |
||
2513 |
call get_option(trim(option_path(f))//"/prognostic/temporal_discretisation& |
|
2514 |
&/control_volumes/number_advection_iterations/tolerance", & |
|
2515 |
adv_tolerance(f), default=0.0) |
|
2516 |
||
2517 |
call get_option(trim(option_path(f))//"/prognostic/temporal_discretisation& |
|
2518 |
&/control_volumes/number_advection_subcycles", & |
|
2519 |
no_subcycles(f), stat=cfl_sub_stat(f)) |
|
2520 |
||
2521 |
end do
|
|
2522 |
assert(all(adv_iterations==adv_iterations(1))) |
|
2523 |
assert(all(adv_tolerance==adv_tolerance(1))) |
|
2524 |
assert(all(no_subcycles==no_subcycles(1))) |
|
2525 |
assert(all(cfl_sub_stat==cfl_sub_stat(1))) |
|
2526 |
||
2527 |
stat = cfl_sub_stat(1) |
|
2528 |
cfl_sub_stat = 1 |
|
2529 |
max_sub_cfl=0.0 |
|
2530 |
if(stat/=0) then |
|
2531 |
! have not specified a number of subcycles but perhaps we're using a
|
|
2532 |
! courant number definition?
|
|
2533 |
do f = 1, nfields |
|
2534 |
call get_option(trim(option_path(f))//"/prognostic/temporal_discretisation& |
|
2535 |
&/control_volumes/maximum_courant_number_per_subcycle", & |
|
2536 |
max_sub_cfl(f), stat=cfl_sub_stat(f)) |
|
2537 |
end do
|
|
2538 |
assert(all(max_sub_cfl==max_sub_cfl(1))) |
|
2539 |
assert(all(cfl_sub_stat==cfl_sub_stat(1))) |
|
2540 |
if(cfl_sub_stat(1)==0) then |
|
2541 |
max_cfl = maxval(cfl_no%val) |
|
2542 |
call allmax(max_cfl) |
|
2543 |
! yes, we're subcycling
|
|
2544 |
! we should have already calculated the courant number (or aborted in the attempt)
|
|
2545 |
no_subcycles=ceiling(max_cfl/max_sub_cfl(1)) |
|
2546 |
if(no_subcycles(1)>1) then |
|
2547 |
sub_dt=dt/real(no_subcycles(1)) |
|
2548 |
call scale(cfl_no, 1.0/real(no_subcycles(1))) |
|
2549 |
end if
|
|
2550 |
else
|
|
2551 |
! no, we're not subcycling
|
|
2552 |
no_subcycles=1 |
|
2553 |
sub_dt = dt |
|
2554 |
end if
|
|
2555 |
else
|
|
2556 |
if(no_subcycles(1)>1) then |
|
2557 |
sub_dt=dt/real(no_subcycles(1)) |
|
2558 |
call scale(cfl_no, 1.0/real(no_subcycles(1))) |
|
2559 |
end if
|
|
2560 |
end if
|
|
2561 |
||
2562 |
ewrite(2,*) 'entering subcycling_loop', no_subcycles(1) |
|
2563 |
! subcycling loop
|
|
2564 |
subcycling_loop: do sub = 1, no_subcycles(1) |
|
2565 |
||
2566 |
! advection iteration loop
|
|
2567 |
advection_iteration_loop: do adv_it = 1, adv_iterations(1) |
|
2568 |
||
2569 |
do f = 1, nfields |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2570 |
getmat(f)=(adv_it==1).and.(sub==1).and.(.not.explicit(f)).and.include_advection |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2571 |
|
2572 |
! record the value of tfield since the previous iteration
|
|
2573 |
call set(advit_tfield(f), tfield(f)%ptr) |
|
2574 |
end do
|
|
2575 |
||
2576 |
! assemble A_m and rhs
|
|
2577 |
call assemble_coupled_advection_m_cv(A_m, rhs, & |
|
2578 |
tfield, l_old_tfield, tfield_options, & |
|
2579 |
tdensity, oldtdensity, tdensity_options, & |
|
2580 |
cvfaces, x_cvshape, x_cvbdyshape, & |
|
2581 |
u_cvshape, u_cvbdyshape, t_cvshape, & |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2582 |
state, advu, x, x_tfield, cfl_no, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2583 |
getmat, sub_dt, & |
2584 |
mesh_sparsity_x) |
|
2585 |
||
2586 |
||
2587 |
||
2588 |
do f = 1, nfields |
|
2589 |
||
2590 |
! assemble it all into a coherent equation
|
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2591 |
call assemble_field_eqn_cv(M(f), A_m(f), cvmass(f), rhs(f), & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2592 |
tfield(f)%ptr, l_old_tfield(f)%ptr, & |
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
2593 |
tdensity(f)%ptr, oldtdensity(f)%ptr, tdensity_options(f), & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2594 |
source(f)%ptr, absorption(f)%ptr, tfield_options(f)%theta, & |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2595 |
state(state_indices(f):state_indices(f)), advu, sub_dt, explicit(f), & |
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2596 |
t_cvmass(f)%ptr, t_abs_src_cvmass, t_cvmass_old, t_cvmass_new) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2597 |
|
2598 |
! Solve for the change in tfield.
|
|
2599 |
if(explicit(f)) then |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2600 |
call apply_dirichlet_conditions(cvmass(f), rhs(f), tfield(f)%ptr, sub_dt) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2601 |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2602 |
delta_tfield(f)%val = rhs(f)%val/cvmass(f)%val |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2603 |
else
|
2604 |
! apply strong dirichlet boundary conditions (if any)
|
|
2605 |
! note that weak conditions (known as control volume boundary conditions)
|
|
2606 |
! will already have been applied
|
|
2607 |
call apply_dirichlet_conditions(M(f), rhs(f), tfield(f)%ptr, sub_dt) |
|
2608 |
||
2609 |
call zero(delta_tfield(f)) |
|
1403
by skramer
Actually add the "higher_order_lumping" as an "mg" option in the schema. |
2610 |
call petsc_solve(delta_tfield(f), M(f), rhs(f), state(1)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2611 |
end if
|
2612 |
||
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
2613 |
ewrite_minmax(delta_tfield(f)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2614 |
|
2615 |
! reset tfield to l_old_tfield before applying change
|
|
2616 |
call set(tfield(f)%ptr, l_old_tfield(f)%ptr) |
|
2617 |
! Add the change in tfield to tfield.
|
|
2618 |
call addto(tfield(f)%ptr, delta_tfield(f), sub_dt) |
|
2619 |
||
2620 |
call halo_update(tfield(f)%ptr) ! exchange the extended halos |
|
2621 |
||
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2622 |
call test_and_write_advection_convergence(tfield(f)%ptr, advit_tfield(f), x, t_cvmass(f)%ptr, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2623 |
filename=trim(state(state_indices(f))%name)//"__"//trim(tfield(f)%ptr%name), & |
2624 |
time=time+sub_dt, dt=sub_dt, it=global_it, adv_it=adv_it, & |
|
2625 |
subcyc=sub, error=error(f)) |
|
2626 |
||
2627 |
end do
|
|
2628 |
||
2629 |
if(all(error<adv_tolerance)) exit advection_iteration_loop |
|
2630 |
||
2631 |
end do advection_iteration_loop |
|
2632 |
||
2633 |
do f = 1, nfields |
|
3449
by Stephan Kramer
Extending ewrite_minmax macro to work with scalar/vector/tensor_fields and (block_)csr_matrices. |
2634 |
ewrite_minmax(tfield(f)%ptr) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2635 |
! update the local old field to the new values and start again
|
2636 |
call set(l_old_tfield(f)%ptr, tfield(f)%ptr) |
|
2637 |
end do
|
|
2638 |
||
2639 |
end do subcycling_loop |
|
2640 |
||
2641 |
do f = 1, nfields |
|
2642 |
call deallocate(delta_tfield(f)) |
|
2643 |
call deallocate(advit_tfield(f)) |
|
2644 |
call deallocate(l_old_tfield(f)%ptr) |
|
2645 |
deallocate(l_old_tfield(f)%ptr) |
|
2646 |
call deallocate(rhs(f)) |
|
2647 |
if(.not.explicit(f)) call deallocate(A_m(f)) |
|
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2648 |
if(explicit(f)) call deallocate(cvmass(f)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2649 |
if(.not.explicit(f)) call deallocate(M(f)) |
2650 |
end do
|
|
2651 |
call deallocate(cfl_no) |
|
2652 |
call deallocate(x_cvbdyshape) |
|
2653 |
call deallocate(u_cvbdyshape) |
|
2654 |
call deallocate(x_cvshape) |
|
2655 |
call deallocate(u_cvshape) |
|
2656 |
call deallocate(t_cvshape) |
|
2657 |
call deallocate(cvfaces) |
|
2658 |
call deallocate(advu) |
|
2659 |
call deallocate(dummydensity) |
|
2660 |
deallocate(dummydensity) |
|
2661 |
call deallocate(dummyscalar) |
|
2662 |
deallocate(dummyscalar) |
|
2663 |
call deallocate(x_tfield) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2664 |
if(move_mesh) then |
3892.1.12
by Brendan Tollit
Change the way the CV mass matrix is found to use the hard coded |
2665 |
call deallocate(t_cvmass_new) |
2666 |
call deallocate(t_cvmass_old) |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2667 |
end if
|
2668 |
call deallocate(ug_cvshape) |
|
2669 |
call deallocate(ug_cvbdyshape) |
|
3900.1.18
by Brendan Tollit
In assemble/Diagnostic_Fields_Matrices.F90 do not initialise cv_mass |
2670 |
do f = 1,nfields |
2671 |
if (include_porosity(f)) call deallocate(t_cvmass_with_porosity(f)) |
|
2672 |
end do
|
|
2673 |
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2674 |
end subroutine solve_coupled_cv |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2675 |
|
2676 |
! coupled assembly:
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2677 |
subroutine assemble_coupled_advection_m_cv(A_m, rhs, & |
2678 |
tfield, oldtfield, tfield_options, & |
|
2679 |
tdensity, oldtdensity, tdensity_options, & |
|
2680 |
cvfaces, x_cvshape, x_cvbdyshape, & |
|
2681 |
u_cvshape, u_cvbdyshape, t_cvshape, & |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
2682 |
state, advu, x, x_tfield, cfl_no, getmat, dt, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2683 |
mesh_sparsity) |
2684 |
||
2685 |
!!< This subroutine assembles the advection matrix and rhs for
|
|
2686 |
!!< control volume field equations such that:
|
|
2687 |
!!< A_m = div(\rho u T) - (1-beta)*T*div(\rho u)
|
|
2688 |
!!< with the added restrictions between different material's face values
|
|
2689 |
||
2690 |
! inputs/outputs:
|
|
2691 |
! the advection matrix
|
|
2692 |
type(csr_matrix), dimension(:), intent(inout) :: A_m |
|
2693 |
! the rhs of the control volume field eqn
|
|
2694 |
type(scalar_field), dimension(:), intent(inout) :: rhs |
|
2695 |
||
2696 |
! the fields being solved for
|
|
2697 |
type(scalar_field_pointer), dimension(:), intent(inout) :: tfield |
|
2698 |
! previous time level of the fields being solved for
|
|
2699 |
type(scalar_field_pointer), dimension(:), intent(inout) :: oldtfield |
|
2700 |
! a type containing all the tfield options
|
|
2701 |
type(cv_options_type), dimension(:), intent(in) :: tfield_options |
|
2702 |
! density and previous time level of density associated with the
|
|
2703 |
! field (only a real density if solving for
|
|
2704 |
! a conservation equation, just constant 1 if AdvectionDiffusion)
|
|
2705 |
type(scalar_field_pointer), dimension(:), intent(inout) :: tdensity, oldtdensity |
|
2706 |
! a type containing all the tdensity options
|
|
2707 |
type(cv_options_type), dimension(:), intent(in) :: tdensity_options |
|
2708 |
||
2709 |
! information about cv faces
|
|
2710 |
type(cv_faces_type), intent(in) :: cvfaces |
|
2711 |
! shape functions for region and surface
|
|
2712 |
type(element_type), intent(in) :: x_cvshape, x_cvbdyshape |
|
2713 |
type(element_type), intent(in) :: u_cvshape, u_cvbdyshape |
|
2714 |
type(element_type), intent(in) :: t_cvshape |
|
2715 |
! bucket full of fields
|
|
2716 |
type(state_type), dimension(:), intent(inout) :: state |
|
2717 |
! the advection velocity
|
|
2718 |
type(vector_field), intent(in) :: advu |
|
2719 |
! the coordinates
|
|
2720 |
type(vector_field), intent(inout) :: x, x_tfield |
|
2721 |
! the cfl number
|
|
2722 |
type(scalar_field), intent(in) :: cfl_no |
|
2723 |
! logical indicating if the matrix should be constructed
|
|
2724 |
! or if it exists already from a previous iteration
|
|
2725 |
logical, dimension(:), intent(in) :: getmat |
|
2726 |
! timestep
|
|
2727 |
real, intent(in) :: dt |
|
2728 |
||
2729 |
! mesh sparsity for upwind value matrices
|
|
2730 |
type(csr_sparsity), intent(in) :: mesh_sparsity |
|
2731 |
||
2732 |
! local memory:
|
|
2733 |
! allocatable memory for coordinates, velocity, normals, determinants, nodes
|
|
2734 |
! and the cfl number at the gauss pts and nodes
|
|
2735 |
real, dimension(:,:), allocatable :: x_ele, x_ele_bdy |
|
2736 |
real, dimension(:,:), allocatable :: x_f, u_f, u_bdy_f |
|
2737 |
real, dimension(:,:), allocatable :: normal, normal_bdy |
|
2738 |
real, dimension(:), allocatable :: detwei, detwei_bdy |
|
2739 |
real, dimension(:), allocatable :: normgi |
|
2740 |
integer, dimension(:), pointer :: nodes, x_nodes, upwind_nodes |
|
2741 |
integer, dimension(:), allocatable :: nodes_bdy |
|
2742 |
real, dimension(:), allocatable :: cfl_ele |
|
2743 |
||
2744 |
! allocatable memory for the values of the field and density at the nodes
|
|
2745 |
! and on the boundary and for ghost values outside the boundary
|
|
2746 |
real, dimension(:,:), allocatable :: tdensity_ele, oldtdensity_ele, & |
|
2747 |
tfield_ele, oldtfield_ele, & |
|
2748 |
sum_tfield_ele, sum_oldtfield_ele |
|
2749 |
real, dimension(:,:), allocatable :: tdensity_ele_bdy, oldtdensity_ele_bdy, & |
|
2750 |
tfield_ele_bdy, oldtfield_ele_bdy |
|
2751 |
real, dimension(:,:), allocatable :: ghost_tdensity_ele_bdy, ghost_oldtdensity_ele_bdy, & |
|
2752 |
ghost_tfield_ele_bdy, ghost_oldtfield_ele_bdy |
|
2753 |
||
2754 |
! some memory used in assembly of the face values
|
|
2755 |
real :: tfield_theta_val, tfield_pivot_val, tdensity_theta_val |
|
2756 |
real, dimension(size(tfield)) :: tfield_face_val, oldtfield_face_val |
|
2757 |
real :: tdensity_face_val, oldtdensity_face_val |
|
2758 |
||
2759 |
! logical array indicating if a face has already been visited by the opposing node
|
|
2760 |
logical, dimension(:), allocatable :: notvisited |
|
2761 |
||
2762 |
! loop integers
|
|
2763 |
integer :: ele, sele, iloc, oloc, face, gi, ggi |
|
2764 |
||
2765 |
! upwind value matrices for the fields and densities
|
|
2766 |
type(csr_matrix), dimension(size(tfield)) :: tfield_upwind, & |
|
2767 |
oldtfield_upwind, tdensity_upwind, oldtdensity_upwind |
|
2768 |
||
2769 |
! incoming or outgoing flow
|
|
2770 |
real :: udotn, income, udotn_bdy |
|
2771 |
logical :: inflow |
|
2772 |
! time and face discretisation
|
|
2773 |
real, dimension(size(tfield)) :: ptheta, beta |
|
2774 |
real :: ftheta |
|
2775 |
||
2776 |
! the type of the bc if integrating over domain boundaries
|
|
2777 |
integer, dimension(:,:), allocatable :: tfield_bc_type, tdensity_bc_type |
|
2778 |
! fields for the bcs over the entire surface mesh
|
|
2779 |
type(scalar_field), dimension(size(tfield)) :: tfield_bc, tdensity_bc |
|
2780 |
||
2781 |
integer :: f, f2, nfields, upwind_pos |
|
2782 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
2783 |
! Boundary condition types
|
2784 |
integer, parameter :: BC_TYPE_WEAKDIRICHLET = 1, BC_TYPE_INTERNAL = 2, BC_TYPE_ZEROFLUX = 3 |
|
2785 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2786 |
ewrite(2,*) 'in assemble_coupled_advection_m_cv' |
2787 |
||
2788 |
nfields = size(tfield) |
|
2789 |
upwind_pos = 0 |
|
2790 |
||
2791 |
! allocate memory for assembly
|
|
2792 |
allocate(x_ele(x%dim,ele_loc(x,1)), & |
|
2793 |
x_f(x%dim, x_cvshape%ngi), & |
|
2794 |
u_f(advu%dim, u_cvshape%ngi), & |
|
2795 |
detwei(x_cvshape%ngi), & |
|
2796 |
normal(x%dim, x_cvshape%ngi), & |
|
2797 |
normgi(x%dim)) |
|
2798 |
allocate(cfl_ele(ele_loc(cfl_no,1)), & |
|
2799 |
tfield_ele(nfields, ele_loc(tfield(1)%ptr,1)), & |
|
2800 |
oldtfield_ele(nfields, ele_loc(oldtfield(1)%ptr, 1)), & |
|
2801 |
sum_tfield_ele(nfields, ele_loc(tfield(1)%ptr,1)), & |
|
2802 |
sum_oldtfield_ele(nfields, ele_loc(oldtfield(1)%ptr, 1)), & |
|
2803 |
tdensity_ele(nfields, ele_loc(tdensity(1)%ptr, 1)), & |
|
2804 |
oldtdensity_ele(nfields, ele_loc(oldtdensity(1)%ptr,1))) |
|
2805 |
allocate(notvisited(x_cvshape%ngi)) |
|
2806 |
||
2807 |
! Clear memory of arrays being designed
|
|
2808 |
do f = 1, nfields |
|
2809 |
if(getmat(f)) then |
|
2810 |
call zero(A_m(f)) |
|
2811 |
end if
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2812 |
call zero(rhs(f)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2813 |
end do
|
2814 |
||
2815 |
! does the density field need upwind values?
|
|
2816 |
do f = 1, nfields |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2817 |
if(include_density) then |
2818 |
call allocate(tdensity_upwind(f), mesh_sparsity, name=int2str(f)//"TDensityUpwindValues") |
|
2819 |
call allocate(oldtdensity_upwind(f), mesh_sparsity, name=int2str(f)//"OldTDensityUpwindValues") |
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
2820 |
if(need_upwind_values(tdensity_options(f))) then |
2821 |
if(have_option(trim(tfield(f)%ptr%option_path)//'/prognostic/equation[0]/density[0]/discretisation_options')) then |
|
2822 |
call find_upwind_values(state, x_tfield, tdensity(f)%ptr, tdensity_upwind(f), & |
|
2823 |
oldtdensity(f)%ptr, oldtdensity_upwind(f), & |
|
2824 |
option_path=trim(tfield(f)%ptr%option_path)//'/prognostic/equation[0]/density[0]/discretisation_options') |
|
2825 |
else
|
|
2826 |
call find_upwind_values(state, x_tfield, tdensity(f)%ptr, tdensity_upwind(f), & |
|
2827 |
oldtdensity(f)%ptr, oldtdensity_upwind(f) & |
|
2828 |
)
|
|
2829 |
end if
|
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2830 |
|
2831 |
else
|
|
2832 |
||
2833 |
call zero(tdensity_upwind(f)) |
|
2834 |
call zero(oldtdensity_upwind(f)) |
|
2835 |
||
2836 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2837 |
end if
|
2838 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2839 |
call allocate(tfield_upwind(f), mesh_sparsity, name=int2str(f)//"TFieldUpwindValues") |
2840 |
call allocate(oldtfield_upwind(f), mesh_sparsity, name=int2str(f)//"OldTFieldUpwindValues") |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2841 |
! does the field need upwind values
|
1645
by cwilson
Hopefully resolving mantis issue 858 by completely reverting r13781 (as the functionality it aimed to supply was already supplied by r13416) and instead implementing the remaining pieces of the puzzle by allowing discretisation options to be specified beneath the name of the density coefficient field (for funky equation types only - ConservationOfMass... etc.). |
2842 |
if(need_upwind_values(tfield_options(f))) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
2843 |
|
2844 |
call find_upwind_values(state, x_tfield, tfield(f)%ptr, tfield_upwind(f), & |
|
2845 |
oldtfield(f)%ptr, oldtfield_upwind(f)) |
|
2846 |
||
2847 |
else
|
|
2848 |
||
2849 |
call zero(tfield_upwind(f)) |
|
2850 |
call zero(oldtfield_upwind(f)) |
|
2851 |
||
2852 |
end if
|
|
2853 |
||
2854 |
! some temporal discretisation options for clarity
|
|
2855 |
ptheta(f) = tfield_options(f)%ptheta |
|
2856 |
beta(f) = tfield_options(f)%beta |
|
2857 |
||
2858 |
end do
|
|
2859 |
|
|
2860 |
call couple_upwind_values(tfield_upwind, oldtfield_upwind, tfield_options) |
|
2861 |
||
2862 |
! loop over elements
|
|
2863 |
element_loop: do ele=1, element_count(tfield(1)%ptr) |
|
2864 |
x_ele=ele_val(x, ele) |
|
2865 |
x_f=ele_val_at_quad(x, ele, x_cvshape) |
|
2866 |
u_f=ele_val_at_quad(advu, ele, u_cvshape) |
|
2867 |
nodes=>ele_nodes(tfield(1)%ptr, ele) |
|
2868 |
x_nodes=>ele_nodes(x_tfield, ele) |
|
2869 |
if((tfield_options(1)%upwind_scheme==CV_UPWINDVALUE_PROJECT_POINT).or.& |
|
2870 |
(tfield_options(1)%upwind_scheme==CV_UPWINDVALUE_PROJECT_GRAD)) then |
|
2871 |
upwind_nodes=>x_nodes |
|
2872 |
else
|
|
2873 |
upwind_nodes=>nodes |
|
2874 |
end if
|
|
2875 |
||
2876 |
! find determinant and unorientated normal
|
|
2877 |
call transform_cvsurf_to_physical(x_ele, x_cvshape, & |
|
2878 |
detwei, normal, cvfaces) |
|
2879 |
||
2880 |
cfl_ele = ele_val(cfl_no, ele) |
|
2881 |
||
2882 |
sum_tfield_ele = 0.0 |
|
2883 |
sum_oldtfield_ele = 0.0 |
|
2884 |
do f = 1, nfields |
|
2885 |
tfield_ele(f,:) = ele_val(tfield(f)%ptr, ele) |
|
2886 |
oldtfield_ele(f,:) = ele_val(oldtfield(f)%ptr, ele) |
|
2887 |
||
2888 |
do f2 = f, nfields |
|
2889 |
sum_tfield_ele(f2,:) = sum_tfield_ele(f2,:) + tfield_ele(f,:) |
|
2890 |
sum_oldtfield_ele(f2,:) = sum_oldtfield_ele(f2,:) + oldtfield_ele(f,:) |
|
2891 |
end do
|
|
2892 |
||
2893 |
tdensity_ele(f,:) = ele_val(tdensity(f)%ptr, ele) |
|
2894 |
oldtdensity_ele(f,:) = ele_val(oldtdensity(f)%ptr, ele) |
|
2895 |
end do
|
|
2896 |
||
2897 |
notvisited=.true. |
|
2898 |
||
2899 |
! loop over nodes within this element
|
|
2900 |
nodal_loop_i: do iloc = 1, tfield(1)%ptr%mesh%shape%loc |
|
2901 |
||
2902 |
! loop over cv faces internal to this element
|
|
2903 |
face_loop: do face = 1, cvfaces%faces |
|
2904 |
||
2905 |
! is this a face neighbouring iloc?
|
|
2906 |
if(cvfaces%neiloc(iloc, face) /= 0) then |
|
2907 |
oloc = cvfaces%neiloc(iloc, face) |
|
2908 |
||
2909 |
! loop over gauss points on face
|
|
2910 |
quadrature_loop: do gi = 1, cvfaces%shape%ngi |
|
2911 |
||
2912 |
! global gauss pt index
|
|
2913 |
ggi = (face-1)*cvfaces%shape%ngi + gi |
|
2914 |
||
2915 |
! have we been here before?
|
|
2916 |
if(notvisited(ggi)) then |
|
2917 |
notvisited(ggi)=.false. |
|
2918 |
||
2919 |
! correct the orientation of the normal so it points away from iloc
|
|
2920 |
normgi=orientate_cvsurf_normgi(node_val(x_tfield, x_nodes(iloc)),x_f(:,ggi),normal(:,ggi)) |
|
2921 |
||
2922 |
! calculate u.n
|
|
2923 |
udotn=dot_product(u_f(:,ggi), normgi(:)) |
|
2924 |
||
2925 |
inflow = (udotn<=0.0) |
|
2926 |
||
2927 |
income = merge(1.0,0.0,inflow) |
|
2928 |
||
2929 |
field_loop: do f = 1, nfields |
|
2930 |
! calculate the iterated pivot value (so far only does first order upwind)
|
|
2931 |
! which will be subtracted out from the rhs such that with an increasing number
|
|
2932 |
! of iterations the true implicit lhs pivot is cancelled out (if it converges!)
|
|
2933 |
tfield_pivot_val = income*tfield_ele(f, oloc) + (1.-income)*tfield_ele(f, iloc) |
|
2934 |
||
2935 |
! evaluate the nonlinear face value that will go into the rhs
|
|
2936 |
! this is the value that you choose the discretisation for and
|
|
2937 |
! that will become the dominant term once convergence is achieved
|
|
2938 |
||
2939 |
call evaluate_face_val(tfield_face_val(f), oldtfield_face_val(f), & |
|
2940 |
iloc, oloc, ggi, upwind_nodes, & |
|
2941 |
t_cvshape, & |
|
2942 |
tfield_ele(f,:), oldtfield_ele(f,:), & |
|
2943 |
tfield_upwind(f), oldtfield_upwind(f), & |
|
2944 |
inflow, cfl_ele, & |
|
2945 |
tfield_options(f), save_pos=upwind_pos) |
|
2946 |
||
2947 |
if(f>1) then |
|
2948 |
|
|
2949 |
call couple_face_value(tfield_face_val(f), oldtfield_face_val(f), & |
|
2950 |
sum(tfield_face_val(1:f-1)), sum(oldtfield_face_val(1:f-1)), & |
|
2951 |
tfield_ele(f,:), oldtfield_ele(f,:), & |
|
2952 |
sum_tfield_ele(f-1,:), sum_oldtfield_ele(f-1,:), & |
|
2953 |
tfield_upwind(f), oldtfield_upwind(f), & |
|
2954 |
inflow, iloc, oloc, upwind_nodes, cfl_ele, & |
|
2955 |
tfield_options(f), save_pos=upwind_pos) |
|
2956 |
||
2957 |
end if
|
|
2958 |
||
2959 |
! perform the time discretisation on the combined tdensity tfield product
|
|
2960 |
tfield_theta_val=theta_val(iloc, oloc, & |
|
2961 |
tfield_face_val(f), & |
|
2962 |
oldtfield_face_val(f), & |
|
2963 |
tfield_options(f)%theta, dt, udotn, & |
|
2964 |
x_ele, tfield_options(f)%limit_theta, & |
|
2965 |
tfield_ele(f,:), oldtfield_ele(f,:), & |
|
2966 |
ftheta=ftheta) |
|
2967 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
2968 |
if(include_density) then |
2969 |
! do the same for the density but save some effort if it's just a dummy
|
|
2970 |
select case (tdensity(f)%ptr%field_type) |
|
2971 |
case(FIELD_TYPE_CONSTANT) |
|
2972 |
||
2973 |
tdensity_face_val = tdensity_ele(f,iloc) |
|
2974 |
oldtdensity_face_val = oldtdensity_ele(f,iloc) |
|
2975 |
||
2976 |
case default |
|
2977 |
||
2978 |
call evaluate_face_val(tdensity_face_val, oldtdensity_face_val, & |
|
2979 |
iloc, oloc, ggi, upwind_nodes, & |
|
2980 |
t_cvshape,& |
|
2981 |
tdensity_ele(f,:), oldtdensity_ele(f,:), & |
|
2982 |
tdensity_upwind(f), oldtdensity_upwind(f), & |
|
2983 |
inflow, cfl_ele, & |
|
2984 |
tdensity_options(f), save_pos = upwind_pos) |
|
2985 |
||
2986 |
end select
|
|
2987 |
||
2988 |
tdensity_theta_val=theta_val(iloc, oloc, & |
|
2989 |
tdensity_face_val, & |
|
2990 |
oldtdensity_face_val, & |
|
2991 |
tdensity_options(f)%theta, dt, udotn, & |
|
2992 |
x_ele, tdensity_options(f)%limit_theta, & |
|
2993 |
tdensity_ele(f,:), oldtdensity_ele(f,:)) |
|
2994 |
||
2995 |
! if we need the matrix then assemble it now
|
|
2996 |
if(getmat(f)) then |
|
2997 |
call addto(A_m(f), nodes(iloc), nodes(oloc), & |
|
2998 |
ptheta(f)*detwei(ggi)*udotn*income*tdensity_theta_val) |
|
2999 |
call addto(A_m(f), nodes(oloc), nodes(iloc), & |
|
3000 |
ptheta(f)*detwei(ggi)*(-udotn)*(1.-income)*tdensity_theta_val) ! notvisited |
|
3001 |
||
3002 |
call addto_diag(A_m(f), nodes(iloc), & |
|
3003 |
ptheta(f)*detwei(ggi)*udotn*(1.0-income)*tdensity_theta_val & |
|
3004 |
-ftheta*(1.-beta(f))*detwei(ggi)*udotn*tdensity_theta_val) |
|
3005 |
call addto_diag(A_m(f), nodes(oloc), & |
|
3006 |
ptheta(f)*detwei(ggi)*(-udotn)*income*tdensity_theta_val & |
|
3007 |
-ftheta*(1.-beta(f))*detwei(ggi)*(-udotn)*tdensity_theta_val) ! notvisited |
|
3008 |
||
3009 |
end if
|
|
3010 |
||
3011 |
! assemble the rhs
|
|
3012 |
call addto(rhs(f), nodes(iloc), & |
|
3013 |
ptheta(f)*udotn*detwei(ggi)*tdensity_theta_val*tfield_pivot_val & |
|
3014 |
- udotn*detwei(ggi)*tfield_theta_val*tdensity_theta_val & |
|
3015 |
+ (1.-ftheta)*(1.-beta(f))*detwei(ggi)*udotn*tdensity_theta_val*oldtfield_ele(f,iloc)) |
|
3016 |
call addto(rhs(f), nodes(oloc), & |
|
3017 |
ptheta(f)*(-udotn)*detwei(ggi)*tdensity_theta_val*tfield_pivot_val & |
|
3018 |
- (-udotn)*detwei(ggi)*tfield_theta_val*tdensity_theta_val & |
|
3019 |
+ (1.-ftheta)*(1.-beta(f))*detwei(ggi)*(-udotn)*tdensity_theta_val*oldtfield_ele(f,oloc)) ! notvisited |
|
3020 |
else
|
|
3021 |
! if we need the matrix then assemble it now
|
|
3022 |
if(getmat(f)) then |
|
3023 |
call addto(A_m(f), nodes(iloc), nodes(oloc), & |
|
3024 |
ptheta(f)*detwei(ggi)*udotn*income) |
|
3025 |
call addto(A_m(f), nodes(oloc), nodes(iloc), & |
|
3026 |
ptheta(f)*detwei(ggi)*(-udotn)*(1.-income)) ! notvisited |
|
3027 |
||
3028 |
call addto_diag(A_m(f), nodes(iloc), & |
|
3029 |
ptheta(f)*detwei(ggi)*udotn*(1.0-income)*tdensity_theta_val & |
|
3030 |
-ftheta*(1.-beta(f))*detwei(ggi)*udotn) |
|
3031 |
call addto_diag(A_m(f), nodes(oloc), & |
|
3032 |
ptheta(f)*detwei(ggi)*(-udotn)*income*tdensity_theta_val & |
|
3033 |
-ftheta*(1.-beta(f))*detwei(ggi)*(-udotn)) ! notvisited |
|
3034 |
||
3035 |
end if
|
|
3036 |
||
3037 |
! assemble the rhs
|
|
3038 |
call addto(rhs(f), nodes(iloc), & |
|
3039 |
ptheta(f)*udotn*detwei(ggi)*tfield_pivot_val & |
|
3040 |
- udotn*detwei(ggi)*tfield_theta_val & |
|
3041 |
+ (1.-ftheta)*(1.-beta(f))*detwei(ggi)*udotn*oldtfield_ele(f,iloc)) |
|
3042 |
call addto(rhs(f), nodes(oloc), & |
|
3043 |
ptheta(f)*(-udotn)*detwei(ggi)*tfield_pivot_val & |
|
3044 |
- (-udotn)*detwei(ggi)*tfield_theta_val & |
|
3045 |
+ (1.-ftheta)*(1.-beta(f))*detwei(ggi)*(-udotn)*oldtfield_ele(f,oloc)) ! notvisited |
|
3046 |
||
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3047 |
end if
|
3048 |
||
3049 |
end do field_loop |
|
3050 |
||
3051 |
end if ! notvisited |
|
3052 |
end do quadrature_loop |
|
3053 |
end if ! neiloc |
|
3054 |
end do face_loop |
|
3055 |
end do nodal_loop_i |
|
3056 |
end do element_loop |
|
3057 |
||
3058 |
! allocate memory for assembly
|
|
3059 |
allocate(x_ele_bdy(x%dim,face_loc(x,1)), & |
|
3060 |
detwei_bdy(x_cvbdyshape%ngi), & |
|
3061 |
normal_bdy(x%dim, x_cvbdyshape%ngi), & |
|
3062 |
u_bdy_f(advu%dim, u_cvbdyshape%ngi), & |
|
3063 |
tdensity_ele_bdy(nfields,face_loc(tdensity(1)%ptr,1)), & |
|
3064 |
oldtdensity_ele_bdy(nfields,face_loc(oldtdensity(1)%ptr,1)), & |
|
3065 |
tfield_ele_bdy(nfields,face_loc(tfield(1)%ptr,1)), & |
|
3066 |
oldtfield_ele_bdy(nfields,face_loc(oldtfield(1)%ptr,1)), & |
|
3067 |
ghost_tdensity_ele_bdy(nfields,face_loc(tdensity(1)%ptr,1)), & |
|
3068 |
ghost_oldtdensity_ele_bdy(nfields,face_loc(oldtdensity(1)%ptr,1)), & |
|
3069 |
ghost_tfield_ele_bdy(nfields,face_loc(tfield(1)%ptr,1)), & |
|
3070 |
ghost_oldtfield_ele_bdy(nfields,face_loc(oldtfield(1)%ptr,1))) |
|
3071 |
allocate(tfield_bc_type(nfields, surface_element_count(tfield(1)%ptr)), & |
|
3072 |
tdensity_bc_type(nfields, surface_element_count(tdensity(1)%ptr)), & |
|
3073 |
nodes_bdy(face_loc(tfield(1)%ptr,1))) |
|
3074 |
||
3075 |
do f = 1, nfields |
|
3076 |
! get the fields over the surface containing the bcs
|
|
3077 |
call get_entire_boundary_condition(tfield(f)%ptr, (/ & |
|
3078 |
"weakdirichlet", & |
|
1668
by cwilson
Changing the keyword boundary condition type 'periodic' to 'internal' to avoid confusion. Also if an internal bc is found an error is no longer thrown by get_entire_boundary_condition, instead the prescribed bc is respected and the fact that it may be on a periodic boundary is ignored. As with Stephan's commit this should NOT be taken as an indication that internal bcs work. |
3079 |
"internal ", & |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3080 |
"zero_flux "/), tfield_bc(f), tfield_bc_type(f,:)) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3081 |
call get_entire_boundary_condition(tdensity(f)%ptr, (/"weakdirichlet"/), tdensity_bc(f), tdensity_bc_type(f,:)) |
3082 |
end do
|
|
3083 |
||
3084 |
! loop over the surface elements
|
|
3085 |
surface_element_loop: do sele = 1, surface_element_count(tfield(1)%ptr) |
|
3086 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3087 |
if(any(tfield_bc_type(:,sele)==BC_TYPE_INTERNAL)) cycle |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3088 |
|
3089 |
ele = face_ele(x, sele) |
|
3090 |
x_ele = ele_val(x, ele) |
|
3091 |
x_ele_bdy = face_val(x, sele) |
|
3092 |
nodes_bdy=face_global_nodes(tfield(1)%ptr, sele) |
|
3093 |
||
3094 |
! calculate the determinant and orientated normal
|
|
3095 |
call transform_cvsurf_facet_to_physical(x_ele, x_ele_bdy, & |
|
3096 |
x_cvbdyshape, normal_bdy, detwei_bdy) |
|
3097 |
||
3098 |
u_bdy_f=face_val_at_quad(advu, sele, u_cvbdyshape) |
|
3099 |
||
3100 |
do f = 1, nfields |
|
3101 |
! deal with bcs for tfield
|
|
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3102 |
if(tfield_bc_type(f,sele)==BC_TYPE_WEAKDIRICHLET) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3103 |
ghost_tfield_ele_bdy(f,:)=ele_val(tfield_bc(f), sele) |
3104 |
else
|
|
3105 |
ghost_tfield_ele_bdy(f,:)=face_val(tfield(f)%ptr, sele) |
|
3106 |
end if
|
|
3107 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3108 |
if(tfield_bc_type(f,sele)==BC_TYPE_WEAKDIRICHLET) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3109 |
ghost_oldtfield_ele_bdy(f,:)=ele_val(tfield_bc(f), sele) ! not considering time varying bcs yet |
3110 |
else
|
|
3111 |
ghost_oldtfield_ele_bdy(f,:)=face_val(oldtfield(f)%ptr, sele) |
|
3112 |
end if
|
|
3113 |
||
3114 |
tfield_ele_bdy(f,:)=face_val(tfield(f)%ptr, sele) |
|
3115 |
oldtfield_ele_bdy(f,:)=face_val(oldtfield(f)%ptr, sele) |
|
3116 |
||
3117 |
! deal with bcs for tdensity
|
|
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3118 |
if(tdensity_bc_type(f,sele)==BC_TYPE_WEAKDIRICHLET) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3119 |
ghost_tdensity_ele_bdy(f,:)=ele_val(tdensity_bc(f), sele) |
3120 |
else
|
|
3121 |
ghost_tdensity_ele_bdy(f,:)=face_val(tdensity(f)%ptr, sele) |
|
3122 |
end if
|
|
3123 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3124 |
if(tdensity_bc_type(f,sele)==BC_TYPE_WEAKDIRICHLET) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3125 |
ghost_oldtdensity_ele_bdy(f,:)=ele_val(tdensity_bc(f), sele) ! not considering time varying bcs yet |
3126 |
else
|
|
3127 |
ghost_oldtdensity_ele_bdy(f,:)=face_val(oldtdensity(f)%ptr, sele) |
|
3128 |
end if
|
|
3129 |
||
3130 |
tdensity_ele_bdy(f,:)=face_val(tdensity(f)%ptr, sele) |
|
3131 |
oldtdensity_ele_bdy(f,:)=face_val(oldtdensity(f)%ptr, sele) |
|
3132 |
||
3133 |
end do
|
|
3134 |
||
3135 |
! loop over the nodes on this surface element
|
|
3136 |
surface_nodal_loop_i: do iloc = 1, tfield(1)%ptr%mesh%faces%shape%loc |
|
3137 |
||
3138 |
! loop over the faces in this surface element
|
|
3139 |
surface_face_loop: do face = 1, cvfaces%sfaces |
|
3140 |
||
3141 |
! is this face a neighbour of iloc?
|
|
3142 |
if(cvfaces%sneiloc(iloc,face)/=0) then |
|
3143 |
||
3144 |
! loop over the gauss pts on this face
|
|
3145 |
surface_quadrature_loop: do gi = 1, cvfaces%shape%ngi |
|
3146 |
||
3147 |
! global gauss point index
|
|
3148 |
ggi = (face-1)*cvfaces%shape%ngi + gi |
|
3149 |
||
3150 |
! u.n
|
|
3151 |
udotn_bdy=dot_product(u_bdy_f(:,ggi), normal_bdy(:,ggi)) |
|
3152 |
||
3153 |
if(udotn_bdy>0) then |
|
3154 |
income=0.0 ! flow leaving the domain |
|
3155 |
else
|
|
3156 |
income=1.0 ! flow entering the domain |
|
3157 |
end if
|
|
3158 |
||
3159 |
! as we're on the boundary it's not possible to use high order methods so just
|
|
3160 |
! default to the pivotted solution method (first order upwinding)
|
|
3161 |
! if the flow is incoming then use the bc ghost values
|
|
3162 |
! if the flow is outgoing then use the surface nodes value
|
|
3163 |
||
3164 |
surface_field_loop: do f = 1, nfields |
|
3165 |
||
3408.1.98
by Christian Jacobs
When checking the tfield_bc_type in Field_Equations_CV.F90, we now compare against the more meaningful integer parameters BC_TYPE_WEAKDIRICHLET (=1), BC_TYPE_NEUMANN (=2), etc. |
3166 |
if((tfield_bc_type(f,sele)==BC_TYPE_ZEROFLUX)) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3167 |
! zero_flux
|
3168 |
udotn = 0.0 |
|
3169 |
else
|
|
3170 |
udotn=udotn_bdy |
|
3171 |
end if
|
|
3172 |
||
3173 |
! for tfield
|
|
3174 |
tfield_face_val(f) = income*ghost_tfield_ele_bdy(f,iloc) + (1.-income)*tfield_ele_bdy(f,iloc) |
|
3175 |
oldtfield_face_val(f) = income*ghost_oldtfield_ele_bdy(f,iloc) + (1.-income)*oldtfield_ele_bdy(f,iloc) |
|
3176 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
3177 |
if(include_density) then |
3178 |
! for tdensity
|
|
3179 |
tdensity_face_val = income*ghost_tdensity_ele_bdy(f,iloc) + (1.-income)*tdensity_ele_bdy(f,iloc) |
|
3180 |
oldtdensity_face_val = income*ghost_oldtdensity_ele_bdy(f,iloc) + (1.-income)*oldtdensity_ele_bdy(f,iloc) |
|
3181 |
||
3182 |
tdensity_theta_val = tdensity_options(f)%theta*tdensity_face_val + (1.-tdensity_options(f)%theta)*oldtdensity_face_val |
|
3183 |
||
3184 |
! assemble matrix
|
|
3185 |
if(getmat(f)) then |
|
3186 |
call addto_diag(A_m(f), nodes_bdy(iloc), & |
|
3187 |
ptheta(f)*detwei_bdy(ggi)*udotn*(1.-income)*tdensity_theta_val & ! if iloc is the donor we can do this implicitly |
|
3188 |
- ptheta(f)*(1.-beta(f))*detwei_bdy(ggi)*udotn_bdy*tdensity_theta_val) |
|
3189 |
end if
|
|
3190 |
||
3191 |
! assemble rhs
|
|
3192 |
call addto(rhs(f), nodes_bdy(iloc), & |
|
3193 |
-ptheta(f)*udotn*detwei_bdy(ggi)*income*tdensity_theta_val*ghost_tfield_ele_bdy(f,iloc) & ! but we can't if it's the downwind |
|
3194 |
-(1.-ptheta(f))*udotn*detwei_bdy(ggi)*tdensity_theta_val*oldtfield_face_val(f) & |
|
3195 |
+(1.-ptheta(f))*(1.-beta(f))*udotn_bdy*detwei_bdy(ggi)*tdensity_theta_val*oldtfield_ele_bdy(f,iloc)) |
|
3196 |
else
|
|
3197 |
! assemble matrix
|
|
3198 |
if(getmat(f)) then |
|
3199 |
call addto_diag(A_m(f), nodes_bdy(iloc), & |
|
3200 |
ptheta(f)*detwei_bdy(ggi)*udotn*(1.-income) & ! if iloc is the donor we can do this implicitly |
|
3201 |
- ptheta(f)*(1.-beta(f))*detwei_bdy(ggi)*udotn_bdy) |
|
3202 |
end if
|
|
3203 |
||
3204 |
! assemble rhs
|
|
3205 |
call addto(rhs(f), nodes_bdy(iloc), & |
|
3206 |
-ptheta(f)*udotn*detwei_bdy(ggi)*income*ghost_tfield_ele_bdy(f,iloc) & ! but we can't if it's the downwind |
|
3207 |
-(1.-ptheta(f))*udotn*detwei_bdy(ggi)*oldtfield_face_val(f) & |
|
3208 |
+(1.-ptheta(f))*(1.-beta(f))*udotn_bdy*detwei_bdy(ggi)*oldtfield_ele_bdy(f,iloc)) |
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3209 |
end if
|
3210 |
||
3211 |
end do surface_field_loop |
|
3212 |
||
3213 |
end do surface_quadrature_loop |
|
3214 |
||
3215 |
end if ! sneiloc |
|
3216 |
||
3217 |
end do surface_face_loop |
|
3218 |
||
3219 |
end do surface_nodal_loop_i |
|
3220 |
||
3221 |
end do surface_element_loop |
|
3222 |
||
3223 |
deallocate(x_ele_bdy, detwei_bdy, normal_bdy, u_bdy_f) |
|
3224 |
deallocate(nodes_bdy) |
|
3225 |
deallocate(tdensity_ele_bdy, oldtdensity_ele_bdy, tfield_ele_bdy, oldtfield_ele_bdy) |
|
3226 |
deallocate(ghost_tdensity_ele_bdy, ghost_oldtdensity_ele_bdy, & |
|
3227 |
ghost_tfield_ele_bdy, ghost_oldtfield_ele_bdy) |
|
3228 |
||
3229 |
deallocate(tfield_bc_type, tdensity_bc_type) |
|
3230 |
do f = 1, nfields |
|
3231 |
call deallocate(tfield_bc(f)) |
|
3232 |
call deallocate(tdensity_bc(f)) |
|
3233 |
||
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
3234 |
if(include_density) then |
3235 |
call deallocate(tdensity_upwind(f)) |
|
3236 |
call deallocate(oldtdensity_upwind(f)) |
|
3237 |
end if
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3238 |
|
3239 |
call deallocate(tfield_upwind(f)) |
|
3240 |
call deallocate(oldtfield_upwind(f)) |
|
3241 |
end do
|
|
3242 |
||
3243 |
deallocate(x_ele, x_f, detwei, normal, normgi, u_f) |
|
3244 |
deallocate(cfl_ele, tfield_ele, oldtfield_ele, tdensity_ele, oldtdensity_ele) |
|
3245 |
deallocate(notvisited) |
|
3246 |
||
3247 |
end subroutine assemble_coupled_advection_m_cv |
|
3248 |
!************************************************************************
|
|
3249 |
!************************************************************************
|
|
3250 |
! subroutines dealing with the writing of the advection_convergence files
|
|
3251 |
subroutine initialise_advection_convergence(state) |
|
3252 |
||
3253 |
type(state_type), dimension(:), intent(in) :: state |
|
3254 |
||
3255 |
integer :: nfiles |
|
3256 |
||
3257 |
logical, save :: initialised=.false. |
|
3258 |
||
3259 |
integer :: column, i, j, fileno |
|
3260 |
character(len=254) :: buffer |
|
3261 |
character(len=FIELD_NAME_LEN) :: material_phase_name, field_name |
|
3262 |
||
3263 |
if(initialised) return |
|
3264 |
initialised=.true. |
|
3265 |
||
3266 |
nfiles = option_count("/material_phase/scalar_field/prognostic/output/convergence_file") |
|
3267 |
||
3268 |
allocate(conv_unit(nfiles)) |
|
3269 |
allocate(sfield_list(nfiles)) |
|
3270 |
||
3271 |
if(nfiles==0) return |
|
3272 |
||
3273 |
fileno = 0 |
|
3274 |
do i = 1, size(state) |
|
3275 |
material_phase_name=trim(state(i)%name) |
|
3276 |
||
3277 |
do j = 1, size(state(i)%scalar_fields) |
|
3278 |
||
3279 |
if(have_option(trim(state(i)%scalar_fields(j)%ptr%option_path)//& |
|
3280 |
"/prognostic/output/convergence_file")) then |
|
3281 |
field_name=trim(state(i)%scalar_fields(j)%ptr%name) |
|
3282 |
||
3283 |
fileno=fileno+1 |
|
3284 |
||
3285 |
if(fileno>nfiles) then |
|
3286 |
ewrite(-1,*) 'fileno = ', fileno, 'nfiles = ', nfiles |
|
1695
by cwilson
A commit full of things that don't work yet... |
3287 |
! this shouldn't happen
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3288 |
FLAbort("More fields think they want a convergence file than expected.") |
3289 |
end if
|
|
3290 |
||
3291 |
sfield_list(fileno) = trim(material_phase_name)//& |
|
3292 |
"__"//trim(field_name) |
|
3293 |
||
3294 |
! open and write a file (if its the first processor)
|
|
3295 |
if(getprocno() == 1) then |
|
3296 |
conv_unit(fileno) = free_unit() |
|
3297 |
open(unit=conv_unit(fileno), file=trim(sfield_list(fileno))//".convergence", & |
|
3298 |
action="write") |
|
3299 |
||
3300 |
||
3301 |
write(conv_unit(fileno), '(a)') "<header>" |
|
3302 |
||
3303 |
column=0 |
|
3304 |
! Initial columns are elapsed time, dt, global iteration and advective iteration
|
|
3305 |
column=column+1 |
|
3306 |
buffer=field_tag(name="ElapsedTime", column=column, statistic="value") |
|
3307 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3308 |
column=column+1 |
|
3309 |
buffer=field_tag(name="dt", column=column, statistic="value") |
|
3310 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3311 |
column=column+1 |
|
3312 |
buffer=field_tag(name="Iteration", column=column, statistic="value") |
|
3313 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3314 |
column=column+1 |
|
3315 |
buffer=field_tag(name="Subcycle", column=column, statistic="value") |
|
3316 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3317 |
column=column+1 |
|
3318 |
buffer=field_tag(name="AdvectionIteration", column=column, statistic="value") |
|
3319 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3320 |
||
3321 |
column=column+1 |
|
3322 |
buffer=field_tag(name=trim(field_name), column=column, statistic="error", material_phase_name=trim(material_phase_name)) |
|
3323 |
write(conv_unit(fileno), '(a)') trim(buffer) |
|
3324 |
||
3325 |
write(conv_unit(fileno), '(a)') "</header>" |
|
3326 |
||
3327 |
end if
|
|
3328 |
||
3329 |
end if
|
|
3330 |
end do
|
|
3331 |
end do
|
|
3332 |
||
3333 |
if(fileno/=nfiles) then |
|
1695
by cwilson
A commit full of things that don't work yet... |
3334 |
! something's gone wrong
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3335 |
ewrite(-1,*) 'fileno = ', fileno, 'nfiles = ', nfiles |
3336 |
FLAbort("Fewer fields thought they wanted a convergence file than expected.") |
|
3337 |
end if
|
|
3338 |
||
3339 |
end subroutine initialise_advection_convergence |
|
3340 |
||
3892.1.11
by Brendan Tollit
Change the variable lumpedmass to cv_mass in the cv stats as this is what it is. |
3341 |
subroutine test_and_write_advection_convergence(field, nlfield, coordinates, cv_mass, filename, & |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3342 |
time, dt, it, subcyc, adv_it, & |
3343 |
error) |
|
3344 |
||
3345 |
type(scalar_field), intent(inout) :: field, nlfield |
|
3346 |
type(vector_field), intent(in) :: coordinates |
|
3892.1.11
by Brendan Tollit
Change the variable lumpedmass to cv_mass in the cv stats as this is what it is. |
3347 |
type(scalar_field), intent(in) :: cv_mass |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3348 |
character(len=*), intent(in) :: filename |
3349 |
real, intent(in) :: time, dt |
|
3350 |
integer, intent(in) :: it, subcyc, adv_it |
|
3351 |
||
3352 |
real, intent(out) :: error |
|
3353 |
||
3354 |
logical :: write_convergence_file |
|
3355 |
character(len=10) :: format, iformat |
|
3356 |
integer :: fileno |
|
3357 |
||
3358 |
integer :: convergence_norm |
|
3359 |
||
3360 |
convergence_norm = convergence_norm_integer(trim(field%option_path)//& |
|
3361 |
"/prognostic/temporal_discretisation/control_volumes/number_advection_iterations/tolerance") |
|
3362 |
||
3363 |
error = 0.0 |
|
3364 |
call field_con_stats(field, nlfield, error, & |
|
3892.1.11
by Brendan Tollit
Change the variable lumpedmass to cv_mass in the cv stats as this is what it is. |
3365 |
convergence_norm, coordinates, cv_mass) |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3366 |
|
3367 |
format='(e15.6e3)' |
|
3368 |
iformat='(i4)' |
|
3369 |
||
3370 |
write_convergence_file = .false. |
|
3371 |
fileno=find_fileno(filename) |
|
3372 |
if(fileno/=0) then |
|
3373 |
write_convergence_file = .true. |
|
3374 |
end if
|
|
3375 |
||
3376 |
if(write_convergence_file) then |
|
3377 |
if(getprocno() == 1) then |
|
3378 |
write(conv_unit(fileno), format, advance="no") time |
|
3379 |
write(conv_unit(fileno), format, advance="no") dt |
|
3380 |
write(conv_unit(fileno), iformat, advance="no") it |
|
3381 |
write(conv_unit(fileno), iformat, advance="no") subcyc |
|
3382 |
write(conv_unit(fileno), iformat, advance="no") adv_it |
|
3383 |
write(conv_unit(fileno), format, advance="no") error |
|
3384 |
write(conv_unit(fileno),'(a)') "" ! end of line |
|
3385 |
end if
|
|
3386 |
end if
|
|
3387 |
||
3388 |
end subroutine test_and_write_advection_convergence |
|
3389 |
||
3390 |
pure function find_fileno(filename) result(fileno) |
|
3391 |
||
3392 |
integer :: fileno |
|
3393 |
character(len=*), intent(in) :: filename |
|
3394 |
||
3395 |
integer :: i |
|
3396 |
||
3397 |
fileno = 0 |
|
3398 |
||
3399 |
do i = 1, size(sfield_list) |
|
3400 |
if(trim(filename)==trim(sfield_list(i))) then |
|
3401 |
fileno = i |
|
3402 |
return
|
|
3403 |
end if
|
|
3404 |
end do
|
|
3405 |
||
3406 |
end function find_fileno |
|
3407 |
! end of convergence file subroutines
|
|
3408 |
!************************************************************************
|
|
3409 |
!************************************************************************
|
|
3410 |
! control volume options checking
|
|
3411 |
subroutine field_equations_cv_check_options |
|
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
3412 |
integer :: nmat, nfield, m, f |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3413 |
character(len=OPTION_PATH_LEN) :: mat_name, field_name, diff_scheme |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
3414 |
integer :: weakdirichlet_count |
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3415 |
logical :: cv_disc, mmat_cv_disc, diff, conv_file, subcycle, cv_temp_disc, tolerance, explicit |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3416 |
real :: theta, p_theta |
3417 |
||
3418 |
nmat = option_count("/material_phase") |
|
3419 |
||
3420 |
do m = 0, nmat-1 |
|
3421 |
call get_option("/material_phase["//int2str(m)//"]/name", mat_name) |
|
3422 |
nfield = option_count("/material_phase["//int2str(m)//"]/scalar_field") |
|
3423 |
do f = 0, nfield-1 |
|
3424 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3425 |
"]/name", field_name) |
|
3426 |
cv_disc=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3427 |
"]/prognostic/spatial_discretisation/control_volumes") |
|
3428 |
mmat_cv_disc=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3429 |
"]/prognostic/spatial_discretisation/coupled_cv") |
|
3430 |
diff=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3431 |
"]/prognostic/tensor_field::Diffusivity") |
|
3432 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3433 |
"]/prognostic/spatial_discretisation/control_volumes/diffusion_scheme[0]/name", & |
|
3434 |
diff_scheme, default="None") |
|
3435 |
conv_file=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3436 |
"]/prognostic/output/convergence_file") |
|
3437 |
||
3438 |
cv_temp_disc=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3439 |
"]/prognostic/temporal_discretisation/control_volumes") |
|
3440 |
tolerance=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3441 |
"]/prognostic/temporal_discretisation/control_volumes/number_advection_iterations/tolerance") |
|
3442 |
subcycle=((have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3443 |
"]/prognostic/temporal_discretisation/control_volumes/maximum_courant_number_per_subcycle")).or.& |
|
3444 |
(have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3445 |
"]/prognostic/temporal_discretisation/control_volumes/number_advection_subcycles"))) |
|
3446 |
explicit=have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3447 |
"]/prognostic/explicit") |
|
3448 |
||
3449 |
weakdirichlet_count=option_count("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3450 |
"]/prognostic/boundary_conditions/type[0]/apply_weakly") |
|
3451 |
||
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3452 |
if(mmat_cv_disc) then |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3453 |
if(diff) then |
3454 |
ewrite(-1,*) "Options checking field "//& |
|
3455 |
trim(field_name)//" in material_phase "//& |
|
3456 |
trim(mat_name)//"." |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3457 |
ewrite(-1,*) "Use control volume discretisation if you want diffusion." |
1120
by cwilson
A first sweep of tidying up the control volume code (not including the coupled cv code, which still needs some work). |
3458 |
FLExit("Multiple coupled control volume discretisation not compatible with Diffusivity") |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3459 |
end if
|
3460 |
|
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3461 |
if(.not.have_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
3462 |
"]/prognostic/priority")) then |
|
3463 |
FLExit("Coupled control volume discretisation requires a priority option.") |
|
3464 |
end if
|
|
3465 |
|
|
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3466 |
if(explicit) then |
3467 |
|
|
3468 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3469 |
"]/prognostic/temporal_discretisation/theta", theta) |
|
3470 |
if (theta/=0.0) then |
|
3471 |
ewrite(-1,*) "Options checking field "//& |
|
3472 |
trim(field_name)//" in material_phase "//& |
|
3473 |
trim(mat_name)//"." |
|
3474 |
FLExit("Explicit coupled control volume discretisations must use temporal_discretisation/theta = 0.0") |
|
3475 |
end if
|
|
3476 |
|
|
3477 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3478 |
"]/prognostic/temporal_discretisation/control_volumes/pivot_theta", p_theta, default=1.0) |
|
3479 |
if (p_theta/=0.0) then |
|
3480 |
ewrite(-1,*) "Options checking field "//& |
|
3481 |
trim(field_name)//" in material_phase "//& |
|
3482 |
trim(mat_name)//"." |
|
3483 |
FLExit("Explicit coupled control volume discretisations must use temporal_discretisation/control_volumes/pivot_theta = 0.0") |
|
3484 |
end if
|
|
3485 |
|
|
3486 |
end if
|
|
3487 |
elseif(cv_disc) then |
|
3488 |
if(diff) then |
|
3489 |
select case(diff_scheme) |
|
3490 |
case("ElementGradient") |
|
3491 |
if(weakdirichlet_count>0) then |
|
3492 |
ewrite(-1,*) "Options checking field "//& |
|
3493 |
trim(field_name)//" in material_phase "//& |
|
3494 |
trim(mat_name)//"." |
|
3495 |
ewrite(-1,*) "ElementGradient diffusion scheme not compatible with weak dirichlet boundary conditions!" |
|
3496 |
ewrite(-1,*) "Use strong dirichlet boundary conditions or switch the diffusion scheme to BassiRebay." |
|
3497 |
ewrite(-1,*) "Sorry and Good Luck!" |
|
3498 |
FLExit("ElementGradient diffusion scheme not compatible with weak dirichlet boundary conditions") |
|
3499 |
end if
|
|
3500 |
end select
|
|
3501 |
end if
|
|
3502 |
if(explicit) then |
|
3503 |
|
|
3504 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3505 |
"]/prognostic/temporal_discretisation/theta", theta) |
|
3506 |
if (theta/=0.0) then |
|
3507 |
ewrite(-1,*) "Options checking field "//& |
|
3508 |
trim(field_name)//" in material_phase "//& |
|
3509 |
trim(mat_name)//"." |
|
3510 |
FLExit("Explicit control volume discretisations must use temporal_discretisation/theta = 0.0") |
|
3511 |
end if
|
|
3512 |
|
|
3513 |
call get_option("/material_phase["//int2str(m)//"]/scalar_field["//int2str(f)//& |
|
3514 |
"]/prognostic/temporal_discretisation/control_volumes/pivot_theta", p_theta, default=1.0) |
|
3515 |
if (p_theta/=0.0) then |
|
3516 |
ewrite(-1,*) "Options checking field "//& |
|
3517 |
trim(field_name)//" in material_phase "//& |
|
3518 |
trim(mat_name)//"." |
|
3519 |
FLExit("Explicit control volume discretisations must use temporal_discretisation/control_volumes/pivot_theta = 0.0") |
|
3520 |
end if
|
|
3521 |
|
|
3522 |
end if
|
|
3523 |
else
|
|
3524 |
if(conv_file) then |
|
3525 |
ewrite(-1,*) "Options checking field "//& |
|
3526 |
trim(field_name)//" in material_phase "//& |
|
3527 |
trim(mat_name)//"." |
|
3528 |
FLExit("Only pure control volume and coupled_cv discretisations can output a convergence file") |
|
3529 |
end if
|
|
3530 |
if(cv_temp_disc) then |
|
3531 |
ewrite(-1,*) "Options checking field "//& |
|
3532 |
trim(field_name)//" in material_phase "//& |
|
3533 |
trim(mat_name)//"." |
|
380
by cwilson
Merging the compressible branch back into the trunk again. This is mostly to do with compressible stuff so hopefully orthogonal to most people but there are a few changes that will affect people/people may want to shout at me about. A short summary of these follows but full details of all the changes can be found in the revision logs 12624, 12623, 12587, 12514, 12470, 12469, 12467, 12464, 12463, 12361, 12359, 12358, 12357, 12355, 12354, 12352, 12341, 12334, 12333, 12317, 12296, 12295, 12294, 11647, 11635, 11634, 11628, 11587, 11534, 11533, 11532, 11528, 11525 and 11524. |
3534 |
FLExit("Only control volume or coupled_cv discretisations can use control_volume temporal discretisations") |
1
by hhiester
deleting initialisation as none of tools are used any longer. |
3535 |
end if
|
3536 |
if(explicit) then |
|
3537 |
ewrite(-1,*) "Options checking field "//& |
|
3538 |
trim(field_name)//" in material_phase "//& |
|
3539 |
trim(mat_name)//"." |
|
3540 |
FLExit("Only pure control volume or coupled_cv discretisations can solve explicitly") |
|
3541 |
end if
|
|
3542 |
end if
|
|
3543 |
||
3544 |
end do
|
|
3545 |
end do
|
|
3546 |
||
3547 |
end subroutine field_equations_cv_check_options |
|
3548 |
! end of control volume options checking
|
|
3549 |
!************************************************************************
|
|
3550 |
||
3551 |
end module field_equations_CV |