~grm08/fluidity/hilbert-for-pyop2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
!    Copyright (C) 2006 Imperial College London and others.
!
!    Please see the AUTHORS file in the main source directory for a full list
!    of copyright holders.
!
!    Prof. C Pain
!    Applied Modelling and Computation Group
!    Department of Earth Science and Engineering
!    Imperial College London
!
!    amcgsoftware@imperial.ac.uk
!
!    This library is free software; you can redistribute it and/or
!    modify it under the terms of the GNU Lesser General Public
!    License as published by the Free Software Foundation,
!    version 2.1 of the License.
!
!    This library is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
!    Lesser General Public License for more details.
!
!    You should have received a copy of the GNU Lesser General Public
!    License along with this library; if not, write to the Free Software
!    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
!    USA

#include "fdebug.h"

module reserve_state_module
  !!< This module creates a reserve_state into which additional external meshes
  !!< (other than CoordinateMesh) are put in.  All the fields associated with
  !!< them are also saved. After an adapt, all this information is reinserted
  !!< into state
  
  use fields
  use global_parameters, only: OPTION_PATH_LEN
  use spud
  use state_module
  
  implicit none
  
  private
  
  type (state_type), dimension(:), save, allocatable :: reserve_state
    
  public :: no_reserved_meshes, create_reserve_state, restore_reserved_meshes, &
    & restore_reserved_fields, deallocate_reserve_state
  
contains

  function no_reserved_meshes()
    logical :: no_reserved_meshes
    
    if(allocated(reserve_state)) then
      no_reserved_meshes = mesh_count(reserve_state(1)) == 0
    else
      no_reserved_meshes = .true.
    end if
  
  end function no_reserved_meshes

  subroutine create_reserve_state(state)
    !!< Create a reserve state, and point it to any additional meshes that were
    !!< imported (not the CoordinateMesh), and any fields that are associated
    !!< with them. exclude_from_mesh_adaptivity must be switched on for this to
    !!< work.
    
    type (state_type), dimension(:), intent(in) :: state
    
    type (scalar_field) :: sfield
    type (vector_field) :: vfield
    type (tensor_field) :: tfield   
    type (mesh_type)    :: mesh
    integer i,j
    
    if(.not. allocated(reserve_state)) allocate(reserve_state(size(state)))
    
    !Loop over all meshes, insert those that are to be excluded into reserve_state
    mesh_loop: do i = 1, mesh_count(state(1))
       mesh = extract_mesh(state(1), i)
       if(have_option(trim(mesh%option_path) // "/exclude_from_mesh_adaptivity")) then
         call insert(reserve_state, mesh, mesh%name)
       end if
    end do mesh_loop
    
    if(no_reserved_meshes()) return
    
    !Loop over states, inserting all fields that are associated with the meshes inserted in
    !the previous mesh loop.
    state_loop: do i = 1,size(state)
       scalar_loop: do j = 1, scalar_field_count(state(i))
         sfield = extract_scalar_field(state(i), j)
         if(has_mesh(reserve_state(i), sfield%mesh%name)) then
           call insert(reserve_state(i), sfield, sfield%name)
         end if
       end do scalar_loop
       vector_loop: do j = 1, vector_field_count(state(i))
         vfield = extract_vector_field(state(i), j)
         if(has_mesh(reserve_state(i), vfield%mesh%name)) then
           call insert(reserve_state(i), vfield, vfield%name)
         end if
       end do vector_loop
       tensor_loop: do j = 1, tensor_field_count(state(i))
         tfield = extract_tensor_field(state(i), j)
         if(has_mesh(reserve_state(i), tfield%mesh%name)) then
           call insert(reserve_state(i), tfield, tfield%name)
         end if
       end do tensor_loop
    end do state_loop
    
  end subroutine create_reserve_state
  
  subroutine restore_reserved_meshes(state)
    !!< This subroutine re-inserts the mesh information saved by reserve_state
    !!< back into state.
    
    type (state_type) , intent(inout), dimension(:) :: state
    type (mesh_type)    :: mesh
    integer i
    
    !if there are no associated meshes... skip this routine
    if(no_reserved_meshes()) return
    
    !Loop over all meshes, reinserting them into state.
    mesh_loop: do i = 1, mesh_count(reserve_state(1))
      mesh = extract_mesh(reserve_state(1), i)
      call insert(state, mesh, mesh%name)
    end do mesh_loop
    
  end subroutine restore_reserved_meshes
  
  subroutine restore_reserved_fields(state)
    !!< This subroutine re-inserts the field information saved by reserve_state
    !!< back into state.
    
    type (state_type) , intent(inout), dimension(:) :: state
    type (scalar_field) :: sfield
    type (vector_field) :: vfield
    type (tensor_field) :: tfield   
    integer i,j
    
    !if there are no associated meshes... skip this routine
    if (no_reserved_meshes()) return
    
    !Loop over reserve_state, reinserting all fields into state.
    state_loop: do i = 1,size(reserve_state)
       scalar_loop: do j = 1, scalar_field_count(reserve_state(i))
         sfield = extract_scalar_field(reserve_state(i), j)
         call insert(state(i), sfield, sfield%name)
       end do scalar_loop
       vector_loop: do j = 1, vector_field_count(reserve_state(i))
         vfield = extract_vector_field(reserve_state(i), j)
         call insert(state(i), vfield, vfield%name)
       end do vector_loop
       tensor_loop: do j = 1, tensor_field_count(reserve_state(i))
         tfield = extract_tensor_field(reserve_state(i), j)
         call insert(state(i), tfield, tfield%name)
       end do tensor_loop
    end do state_loop
    
  end subroutine restore_reserved_fields
  
  subroutine deallocate_reserve_state()
    integer i
    
    if(allocated(reserve_state)) then
       do i=1,size(reserve_state)
          call deallocate(reserve_state(i))
       end do
       deallocate(reserve_state)
    end if
    
  end subroutine deallocate_reserve_state

end module reserve_state_module