A routine to obtain tracked data.
This routine will return all requested variables in the tracking object me and return it for all elements of the subtree in the res field.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_varMap_type) | :: | varMap |
varMap from tem_tracking_instance_type |
|||
type(tem_subTree_type) | :: | subTree |
subTree from tem_tracking_instance_type |
|||
type(tem_varSys_type), | intent(in) | :: | varsys |
Variable system describing available data. |
||
type(treelmesh_type), | intent(in) | :: | mesh |
Mesh definition of the input data. |
||
type(tem_time_type), | intent(in) | :: | time |
Time information for the current data. |
||
integer, | intent(in) | :: | nDofs |
Number of degrees of freedom. |
||
real(kind=rk), | intent(out) | :: | res(:) |
Tracked data, has to match the subtree definition. The memory layout is like this: 1. All variable components 2. nDofs 3. nElems (subtree%nElems) |
subroutine tem_tracking_getData(varMap, subTree, varSys, mesh, time, nDofs, & & res) !> varMap from tem_tracking_instance_type type(tem_varMap_type) :: varMap !> subTree from tem_tracking_instance_type type(tem_subTree_type) :: subTree !> Variable system describing available data. type(tem_varsys_type), intent(in) :: varsys !> Mesh definition of the input data. type(treelmesh_type), intent(in) :: mesh !> Time information for the current data. type(tem_time_type), intent(in) :: time !> Number of degrees of freedom. integer, intent(in) :: nDofs !> Tracked data, has to match the subtree definition. !! !! The memory layout is like this: !! 1. All variable components !! 2. nDofs !! 3. nElems (subtree%nElems) real(kind=rk), intent(out) :: res(:) ! -------------------------------------------------------------------- ! integer :: maxComponents integer :: nComponents integer :: compOff integer :: elemOff integer :: nElems integer :: nScalars, nVars integer :: elemSize integer :: nChunks integer :: chunksize integer :: nChunkElems integer :: res_size integer :: buf_start, buf_end integer :: e_start, d_start, t_start integer :: iElem, iChunk, iDoF, iVar integer :: varpos real(kind=rk), allocatable :: tmpdat(:) ! -------------------------------------------------------------------- ! nElems = subTree%nElems nScalars = varMap%nScalars nVars = varMap%varpos%nVals ! Need to obtain the data variable for variable, and store it in an ! intermediate array, because all components should be put together in the ! res array. ! The temporary array therefore needs to be sufficiently large to store the ! maximal number of components. maxComponents = maxval(varSys%method%val(varMap%varPos & & %val(:nVars))%nComponents ) ! Number of elements to fit into a single chunk. chunkSize = min( io_buffer_size / (maxComponents*nDofs), nElems ) ! Size of a single element elemsize = nScalars*nDofs if ( (nElems > 0) .and. (chunkSize == 0) ) then write(logUnit(0),*) 'The chosen io_buffer_size of ', io_buffer_size write(logUnit(0),*) 'is too small for outputting ', maxComponents write(logUnit(0),*) 'scalar values with ', nDofs write(logUnit(0),*) 'degrees of freedom!' write(logUnit(0),*) 'Please increase the io_buffer_size to at least ', & & real(maxComponents*nDofs) / real(131072), ' MB!' call tem_abort() end if ! Using a temporary array to store the variables and transfer them to res ! in the correct ordering afterwards. allocate(tmpdat(chunkSize*maxComponents*nDofs)) nChunks = 0 if (chunkSize > 0) then nChunks = ceiling( real(nElems, kind=rk) & & / real(chunkSize, kind=rk) ) end if chunks: do iChunk=1,nChunks elemOff = ((iChunk-1)*chunkSize) nChunkElems = min(chunkSize, nElems - elemOff) buf_start = elemOff + 1 buf_end = elemOff + nChunkElems compOff = 0 vars: do iVar=1,varMap%varPos%nVals varpos = varMap%varPos%val(iVar) nComponents = varSys%method%val(varPos)%nComponents res_size = nChunkElems * nDofs * nComponents ! derive the quantities for all the elements in the current chunk call varSys%method%val(varpos)%get_element( & & varSys = varSys, & & elemPos = subtree%map2global( & & buf_start:buf_end), & & time = time, & & tree = mesh, & & nElems = nChunkElems, & & nDofs = nDofs, & & res = tmpdat(:res_size) ) do iElem=1,nChunkElems e_start = (elemOff+iElem-1)*elemsize t_start = (iElem-1)*nComponents*nDofs do iDof=1,nDofs d_start = (iDof-1)*nScalars + compOff res( (e_start+d_start+1) : (e_start+d_start+nComponents) ) & & = tmpdat( t_start + (iDof-1)*nComponents + 1 & & :t_start + iDof*nComponents ) end do end do ! Increase the component offset for the next variables. compOff = compOff + nComponents end do vars end do chunks end subroutine tem_tracking_getData