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