511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
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 Engineeringp
|
|
9 |
! Imperial College London
|
|
10 |
!
|
|
2392
by tmb1
Changing isntances of Chris' person email address to the group |
11 |
! amcgsoftware@imperial.ac.uk
|
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
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 |
||
28 |
#include "fdebug.h"
|
|
29 |
||
30 |
subroutine differentiate_vtu(input_filename, input_filename_len, output_filename, output_filename_len, input_fieldname, input_fieldname_len) |
|
31 |
||
615
by maddison
Build fixes for Intel |
32 |
! these 5 need to be on top and in this order, so as not to confuse silly old intel compiler
|
33 |
use quadrature |
|
34 |
use elements |
|
35 |
use sparse_tools |
|
36 |
use fields |
|
37 |
use state_module |
|
38 |
!
|
|
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
39 |
use field_derivatives |
40 |
use fldebug |
|
41 |
use state_module |
|
42 |
use vtk_interfaces |
|
43 |
||
44 |
implicit none
|
|
45 |
|
|
46 |
integer, intent(in) :: input_filename_len |
|
47 |
integer, intent(in) :: output_filename_len |
|
48 |
integer, intent(in) :: input_fieldname_len |
|
49 |
character(len = input_filename_len), intent(in) :: input_filename |
|
50 |
character(len = output_filename_len), intent(in) :: output_filename |
|
51 |
character(len = input_fieldname_len), intent(in) :: input_fieldname |
|
52 |
||
53 |
integer :: dim, i, j, nfields |
|
54 |
logical :: allocated |
|
55 |
type(mesh_type), pointer :: mesh |
|
56 |
type(scalar_field) :: masslump |
|
57 |
type(scalar_field), dimension(:), allocatable :: s_fields |
|
58 |
type(scalar_field), pointer :: s_field |
|
59 |
type(state_type) :: collapsed_state, state |
|
60 |
type(vector_field) :: field_grad |
|
61 |
type(vector_field), dimension(:), allocatable :: field_grads |
|
62 |
type(vector_field), pointer :: positions |
|
615
by maddison
Build fixes for Intel |
63 |
|
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
64 |
ewrite(1, *) "In differentiate_vtu" |
65 |
||
66 |
call vtk_read_state(trim(input_filename), state) |
|
67 |
||
68 |
positions => extract_vector_field(state, "Coordinate") |
|
69 |
dim = positions%dim |
|
70 |
mesh => extract_mesh(state, "Mesh") |
|
71 |
||
72 |
if(len_trim(input_fieldname) == 0) then |
|
73 |
call collapse_fields_in_state(state, collapsed_state) |
|
74 |
nfields = scalar_field_count(collapsed_state) |
|
75 |
allocate(s_fields(nfields)) |
|
76 |
do i = 1, scalar_field_count(collapsed_state) |
|
77 |
s_fields(i) = extract_scalar_field(collapsed_state, i) |
|
78 |
end do
|
|
79 |
allocate(field_grads(nfields)) |
|
80 |
do i = 1, nfields |
|
81 |
s_field => extract_scalar_field(collapsed_state, i) |
|
82 |
call allocate(field_grads(i), dim, mesh, trim(s_field%name) // "Gradient") |
|
83 |
end do
|
|
84 |
call deallocate(collapsed_state) |
|
85 |
||
86 |
select case(continuity(positions)) |
|
87 |
case(-1) |
|
88 |
do i = 1, ele_count(mesh) |
|
89 |
call solve_grad_ele(i, positions, s_fields, field_grads) |
|
90 |
end do
|
|
91 |
case(0) |
|
92 |
call allocate(masslump, mesh, "LumpedMass") |
|
93 |
call zero(masslump) |
|
94 |
do i = 1, nfields |
|
95 |
call zero(field_grads(i)) |
|
96 |
end do
|
|
97 |
|
|
98 |
do i = 1, ele_count(mesh) |
|
99 |
call assemble_grad_ele(i, positions, s_fields, masslump, field_grads) |
|
100 |
end do
|
|
101 |
|
|
102 |
do i = 1, nfields |
|
103 |
do j = 1, dim |
|
2445
by skramer
Changing the storage of vector_field from vfield%val(dim)%ptr(node) to vfield%val(dim,node). |
104 |
field_grads(i)%val(j,:) = field_grads(i)%val(j,:) / masslump%val |
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
105 |
end do
|
106 |
end do
|
|
107 |
call deallocate(masslump) |
|
108 |
case default |
|
109 |
ewrite(-1, *) "For continuity ", continuity(positions) |
|
110 |
FLAbort("Unrecognised continuity") |
|
111 |
end select
|
|
112 |
|
|
113 |
do i = 1, nfields |
|
114 |
call insert(state, field_grads(i), field_grads(i)%name) |
|
115 |
call deallocate(field_grads(i)) |
|
116 |
end do
|
|
117 |
deallocate(field_grads) |
|
118 |
deallocate(s_fields) |
|
119 |
else
|
|
120 |
s_field => extract_scalar_field(state, trim(input_fieldname), allocated = allocated) |
|
121 |
||
122 |
call allocate(field_grad, dim, mesh, trim(s_field%name) // "Gradient") |
|
123 |
call grad(s_field, positions, field_grad) |
|
124 |
call insert(state, field_grad, field_grad%name) |
|
125 |
call deallocate(field_grad) |
|
126 |
||
127 |
if(allocated) deallocate(s_field) |
|
128 |
end if
|
|
129 |
|
|
130 |
call vtk_write_state(output_filename, state = (/state/)) |
|
131 |
call deallocate(state) |
|
132 |
||
133 |
call print_references(0) |
|
134 |
||
135 |
ewrite(1, *) "Exiting differentate_vtu" |
|
615
by maddison
Build fixes for Intel |
136 |
|
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
137 |
contains
|
138 |
||
139 |
subroutine solve_grad_ele(ele, positions, fields, field_grads) |
|
140 |
integer, intent(in) :: ele |
|
141 |
type(vector_field), intent(in) :: positions |
|
142 |
type(scalar_field), dimension(:), intent(in) :: fields |
|
143 |
type(vector_field), dimension(size(fields)), intent(inout) :: field_grads |
|
144 |
||
145 |
integer :: i |
|
146 |
integer, dimension(:), pointer :: nodes |
|
147 |
real, dimension(ele_ngi(positions, ele)) :: detwei |
|
148 |
real, dimension(ele_loc(positions, ele), ele_loc(positions, ele)) :: little_mass |
|
149 |
real, dimension(ele_loc(positions, ele), size(fields) * positions%dim) :: little_rhs |
|
150 |
real, dimension(ele_loc(positions, ele), ele_ngi(positions, ele), positions%dim) :: dshape |
|
151 |
type(element_type), pointer :: shape |
|
152 |
|
|
153 |
shape => ele_shape(positions, ele) |
|
154 |
call transform_to_physical(positions, ele, shape, & |
|
155 |
& detwei = detwei, dshape = dshape) |
|
156 |
||
157 |
little_mass = shape_shape(shape, shape, detwei) |
|
158 |
do i = 1, size(fields) |
|
3118
by skramer
Changing the order of dimensions of the output of ele_grad_at_quads. |
159 |
little_rhs(:, (i - 1) * positions%dim + 1:i * positions%dim) = transpose(shape_vector_rhs(shape, ele_grad_at_quad(fields(i), ele, dshape), detwei)) |
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
160 |
end do
|
161 |
call solve(little_mass, little_rhs) |
|
162 |
||
163 |
nodes => ele_nodes(positions, ele) |
|
164 |
do i = 1, size(field_grads) |
|
165 |
call set(field_grads(i), nodes, little_rhs(:, (i - 1) * positions%dim + 1:i * positions%dim)) |
|
166 |
end do
|
|
167 |
|
|
168 |
end subroutine solve_grad_ele |
|
169 |
||
170 |
subroutine assemble_grad_ele(ele, positions, fields, masslump, rhs) |
|
171 |
integer, intent(in) :: ele |
|
172 |
type(vector_field), intent(in) :: positions |
|
173 |
type(scalar_field), dimension(:), intent(in) :: fields |
|
174 |
type(scalar_field), intent(inout) :: masslump |
|
175 |
type(vector_field), dimension(size(fields)), intent(inout) :: rhs |
|
176 |
||
177 |
integer :: i |
|
178 |
integer, dimension(:), pointer :: nodes |
|
179 |
real, dimension(ele_ngi(positions, ele)) :: detwei |
|
180 |
real, dimension(ele_loc(positions, ele), ele_ngi(positions, ele), positions%dim) :: dshape |
|
181 |
type(element_type), pointer :: shape |
|
182 |
|
|
183 |
shape => ele_shape(positions, ele) |
|
184 |
call transform_to_physical(positions, ele, shape, & |
|
185 |
& detwei = detwei, dshape = dshape) |
|
186 |
||
187 |
nodes => ele_nodes(positions, ele) |
|
188 |
call addto(masslump, nodes, sum(shape_shape(shape, shape, detwei), 2)) |
|
189 |
do i = 1, size(rhs) |
|
3118
by skramer
Changing the order of dimensions of the output of ele_grad_at_quads. |
190 |
call addto(rhs(i), nodes, shape_vector_rhs(shape, ele_grad_at_quad(fields(i), ele, dshape), detwei)) |
511
by maddison
Adding a tool to compute field gradients in a vtu. Primarily intended for the fast differentiation of large numbers of fields. |
191 |
end do
|
192 |
|
|
193 |
end subroutine assemble_grad_ele |
|
194 |
||
195 |
end subroutine differentiate_vtu |