da_dot_cv.inc
References to this file elsewhere.
1 real function da_dot_cv(cv_size, cv_size_domain, x, y, grid, mzs)
2
3 !-----------------------------------------------------------------------
4 ! Purpose: Forms the dot product of two vectors that are organized in the
5 ! format of a "cv_type".
6 !
7 ! Capable of producing bitwise-exact results for distributed-memory
8 ! parallel runs for testing. This feature is very slow and consumes
9 ! lots of memory.
10 !-----------------------------------------------------------------------
11
12 implicit none
13
14 integer, intent(in) :: cv_size ! Size of array (tile).
15 integer, intent(in) :: cv_size_domain ! Size of array (domain).
16 real, intent(in) :: x(cv_size) ! 1st vector.
17 real, intent(in) :: y(cv_size) ! 1st vector.
18 type(domain), intent(in) :: grid ! decomposed dimensions
19 integer, intent(in) :: mzs(:) ! mz for each variable
20 ! (to identify 2D arrays)
21
22 real, pointer :: xg(:), yg(:) ! Serial data arrays.
23 real :: dtemp1(1), dtemp1x ! Temporary.
24
25 if (trace_use) call da_trace_entry("da_dot_cv")
26
27 dtemp1(1) = 0.0
28
29 ! Bitwise-exact reduction preserves operation order of serial code for
30 ! testing, at the cost of much-increased run-time. Turn it off when not
31 ! testing. This will always be .false. for a serial run or
32 ! one-processor DM_PARALLEL run.
33
34 if (test_dm_exact) then
35
36 ! Collect local cv arrays x and y to globally-sized serially-ordered
37 ! arrays xg and yg. Note that xg and yg will only exist on the
38 ! monitor task.
39
40 if (rootproc) then
41 allocate(xg(1:cv_size_domain))
42 allocate(yg(1:cv_size_domain))
43 end if
44
45 call da_cv_to_global(cv_size, cv_size_domain, x, grid, mzs, xg)
46 call da_cv_to_global(cv_size, cv_size_domain, y, grid, mzs, yg)
47
48 if (rootproc) then
49 dtemp1(1) = da_dot(cv_size_domain, xg, yg)
50 deallocate(xg, yg)
51 end if
52
53 ! Broadcast result from monitor to other tasks.
54 call wrf_dm_bcast_real(dtemp1, 1)
55
56 else
57
58 dtemp1(1) = da_dot(cv_size, x, y)
59
60 if (.not. global) then
61 dtemp1x = dtemp1(1)
62 ! summation across processors:
63 dtemp1(1) = wrf_dm_sum_real(dtemp1x)
64 end if
65
66 end if
67
68 da_dot_cv = dtemp1(1)
69
70 if (trace_use) call da_trace_exit("da_dot_cv")
71
72 end function da_dot_cv
73
74