Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IntLoad.f90
Go to the documentation of this file.
1 
2 !!****
3 !!
4 !! NAME
5 !! IntLoad
6 !!
7 !! FUNCTION
8 !! This subroutine constructs the internal thermal load vector for this
9 !! processor by multiplying its part of the stiffness or capacitance matrix by
10 !! the global temperature vector.
11 !!
12 !! INPUTS
13 !! ndim -- The size of one dimension of the global stiffness or capacitance matrix
14 !! nrows -- The number of rows that are assigned to this processor
15 !! nnz -- The number of nonzeros in this processor's part of the stiffness or capacitance matrix
16 !! nstart -- The global index of the first row assigned to this processor
17 !! rp -- The row mapping vector
18 !! cval -- The collumn mapping vector
19 !! aval -- The nonzero values in this processor's part of the stiffness or capacitance matrix
20 !! tempin -- The part of the global temperature vector that's assigned to this processor
21 !!
22 !! OUTPUTS
23 !! rint -- The part of the global internal thermal load vector that's assigned to this processor
24 !!
25 !! USES
26 !! MPI
27 !!
28 !!****
29 
30 SUBROUTINE intload(ndim,nrows,nnz,nstart,rp,cval,aval,tempin,rint)
31 
32  USE precision
33  USE implicit_global
35 
36  IMPLICIT NONE
37 
38  include 'mpif.h'
39 
40  ! ... Input variables
41  INTEGER :: ndim, nrows, nnz, nstart
42  INTEGER, DIMENSION(nrows+1) :: rp
43  INTEGER, DIMENSION(nnz) :: cval
44  REAL(kind=wp), DIMENSION(nnz) :: aval
45  REAL(kind=wp), DIMENSION(nrows) :: tempin
46 
47  ! ... Output variables
48  REAL(kind=wp), DIMENSION(nrows) :: rint
49 
50  ! ... Internal variables
51  REAL(kind=wp), DIMENSION(ndim) :: temptemp
52  INTEGER, ALLOCATABLE, DIMENSION(:) :: numtempfrom
53  REAL(kind=wp), ALLOCATABLE, DIMENSION(:) :: bufsnd
54  INTEGER :: i, j, k, m, counter1, counter2
55  REAL(kind=wp) :: tempval
56  INTEGER, ALLOCATABLE, DIMENSION(:) :: req_rcv, req_snd
57  INTEGER, ALLOCATABLE, DIMENSION(:,:) :: stat_rcv, stat_snd
58 
59 
60  ! ... Communicate how many pieces of temp to send to each other proc
61  IF ( nprocs > 1) THEN
62 
63  CALL mpi_barrier(rocstar_communicator,ierr)
64  ALLOCATE(req_rcv(1:nprocs))
65  ALLOCATE(req_snd(1:nprocs))
66  ALLOCATE(stat_snd(1:mpi_status_size,1:nprocs))
67  ALLOCATE(stat_rcv(1:mpi_status_size,1:nprocs))
68  ALLOCATE(numtempfrom(1:nprocs))
69  DO i = 1, nprocs
70  req_rcv(i) = 0
71  req_snd(i) = 0
72  DO j = 1, mpi_status_size
73  stat_rcv(j,i) = 0
74  stat_snd(j,i) = 0
75  ENDDO
76  ENDDO
77  DO i = 1, nprocs
78  IF (i-1 /= myid) THEN
79  CALL mpi_irecv(numtempfrom(i),1, &
80  mpi_integer,i-1,10,rocstar_communicator, &
81  req_rcv(i),ierr)
82  ENDIF
83  ENDDO
84  DO i = 1, nprocs
85  IF (i-1 /= myid) THEN
86 
87  CALL mpi_send(nrows,1,mpi_integer, &
88  i-1,10,rocstar_communicator,ierr)
89  ENDIF
90  ENDDO
91  CALL mpi_waitall(nprocs,req_rcv,stat_rcv,ierr)
92 
93  DEALLOCATE(req_rcv)
94  DEALLOCATE(req_snd)
95  DEALLOCATE(stat_snd)
96  DEALLOCATE(stat_rcv)
97 
98 
99 
100 
101  ! ... Communicate temperature to all the other procs
102  ! ... receive
103  CALL mpi_barrier(rocstar_communicator,ierr)
104  ALLOCATE(req_rcv(1:nprocs))
105  ALLOCATE(req_snd(1:nprocs))
106  ALLOCATE(stat_snd(1:mpi_status_size,1:nprocs))
107  ALLOCATE(stat_rcv(1:mpi_status_size,1:nprocs))
108  DO i = 1, nprocs
109  req_rcv(i) = 0
110  req_snd(i) = 0
111  DO j = 1, mpi_status_size
112  stat_rcv(j,i) = 0
113  stat_snd(j,i) = 0
114  ENDDO
115  ENDDO
116  ALLOCATE(frmproc(1:nprocs))
117  DO i = 1, nprocs
118  ! ... if processor i is not this processor (i=1=processor 0)
119  IF (i-1 /= myid) THEN
120  ! ... Allocate a buffer of size 2 times the number of nodes from
121  ! ... processor j. The buffer is orgnized as {node #, temp, node #, temp...}
122  ALLOCATE(frmproc(i)%rcvbuf(1:2*int(numtempfrom(i))))
123  CALL mpi_irecv(frmproc(i)%rcvbuf(1),2*int(numtempfrom(i)), &
124  mpi_double_precision,i-1,10,rocstar_communicator, &
125  req_rcv(i),ierr)
126  ENDIF
127  ENDDO
128 
129  ! ... send
130  DO i = 1, nprocs
131  IF (i-1 /= myid) THEN
132  ! ... if processor i is not this processor
133  ! ... allocate a buffer 2 times the number of the nodes
134  ! ... on this processor to send to processor i
135  ALLOCATE(bufsnd(1:2*lnumnp))
136  counter1 = 0
137  DO j = 1, gnumnp
138  ! ... if global node j belongs to this processor
139  ! ... then the corresponding temperature is copied
140  ! ... to a buffer to go to processor i
141  IF ((global2local(j) /= -1) .AND. (nodeproc(global2local(j)) == myid)) THEN
142  ! ... if global node j belongs to this processor
143  ! ... then counter1 determines the index in tempin where
144  ! ... the corresponding temperature is stored
145  counter1 = counter1 + 1
146  bufsnd(2*counter1-1) = j
147  bufsnd(2*counter1) = tempin(counter1)
148  ENDIF
149  ENDDO
150  ! ... send the buffer of length 2*nodes on this processor
151  ! ... to processor (i-1).
152  CALL mpi_send(bufsnd,2*nrows,mpi_double_precision, &
153  i-1,10,rocstar_communicator,ierr)
154  DEALLOCATE(bufsnd)
155  ENDIF
156  ENDDO
157  CALL mpi_waitall(nprocs,req_rcv,stat_rcv,ierr)
158 
159  DEALLOCATE(req_rcv)
160  DEALLOCATE(req_snd)
161  DEALLOCATE(stat_snd)
162  DEALLOCATE(stat_rcv)
163 
164  ENDIF
165 
166  ! ... create a global temperature vector
167  DO i = 1, gnumnp
168  ! ... if global node i belongs to this processor
169  ! ... then the corresponding temperature is copied
170  ! ... in from the input array tempin
171  IF ((global2local(i) /= -1) .AND. (nodeproc(global2local(i)) == myid)) THEN
172  temptemp( i ) = tempin( i - (nstart-1))
173  ELSE
174  ! ... if global node i does not belong to this processor
175  ! ... then find which processor it does belong to
176  ! ... and get the temperature from the buffer received from
177  ! ... that processor
178  DO j = 1, nprocs
179  IF (j-1 /= myid) THEN
180  ! ... loop through the number of temperature values from processor j
181  DO m = 1, numtempfrom(j)
182  ! ... frmproc(j)%rcvbuf(2*m-1) is where the node number
183  ! ... is stored for the temperature value stored at
184  ! ... frmproc(j)%rcvbuf(2*m)
185  IF (int(frmproc(j)%rcvbuf(2*m-1)) == i) THEN
186  temptemp( i ) = frmproc(j)%rcvbuf(2*m)
187  ENDIF
188  ENDDO
189  ENDIF
190  ENDDO
191  ENDIF
192  ENDDO
193  IF (nprocs > 1) DEALLOCATE(frmproc)
194 
195 
196 
197  ! ... Multiply the input matrix by the temperature to find internal load
198  CALL comp_row_vecmult(gnumnp,nrows,nnz,nstart,rp,cval,aval,temptemp,rint)
199 
200 END SUBROUTINE intload
FT m(int i, int j) const
j indices k indices k
Definition: Indexing.h:6
subroutine comp_row_vecmult(gndim, nrows1, nnz1, nstart1, rp1, cval1, aval1, vec, ans)
blockLoc i
Definition: read.cpp:79
subroutine intload(ndim, nrows, nnz, nstart, rp, cval, aval, tempin, rint)
Definition: IntLoad.f90:30
j indices j
Definition: Indexing.h:6