Initialize the convergence subtreee
Identify, how many and which elements exist on my local process and are requested from the convergences Empty convergence are removed, so the convergence(:) might be re-allocated
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(tem_convergence_type), | intent(inout), | allocatable | :: | me(:) |
convergence descriptions |
|
type(treelmesh_type), | intent(in) | :: | tree |
Global mesh from which the elements are identified and then stored to sub-meshes inside the convergences |
||
type(tem_varSys_type), | intent(in) | :: | varSys |
solver-provided variable systems |
||
type(tem_BC_prop_type), | intent(in) | :: | bc_prop |
bc property that used to identify elements of certain BCs |
||
type(tem_comm_env_type), | intent(in) | :: | globProc |
Process description to use. |
||
type(tem_stencilHeader_type), | intent(in), | optional | :: | stencil |
stencil used to create subTree of boundary type |
|
integer, | intent(in), | optional | :: | nDofs |
The number of dofs for each scalar variable of the equation system |
subroutine tem_init_convergence( me, tree, varSys, bc_prop, globProc,& & stencil, nDofs ) ! -------------------------------------------------------------------- ! !> convergence descriptions type(tem_convergence_type),intent(inout), allocatable :: me(:) !> Global mesh from which the elements are identified and then stored to !! sub-meshes inside the convergences type(treelmesh_type), intent(in) :: tree !> bc property that used to identify elements of certain BCs type( tem_bc_prop_type ), intent(in) :: bc_prop !> solver-provided variable systems type(tem_varSys_type), intent(in) :: varSys !> Process description to use. type(tem_comm_env_type), intent(in) :: globProc !> stencil used to create subTree of boundary type type(tem_stencilHeader_type), optional, intent(in) :: stencil !> The number of dofs for each scalar variable of the equation system integer, intent(in), optional :: nDofs ! -------------------------------------------------------------------- ! integer :: iConv, nConv, nVars integer :: nChunks, chunkSize, nElems, maxComponents, nPoints ! temporary convergence array type( tem_convergence_type ),allocatable :: tempConv(:) ! -------------------------------------------------------------------- ! call tem_horizontalSpacer(fUnit=logUnit(1)) write(logUnit(1),*) 'Setting up the convergence infrastructure' nConv = 0 ! Allocate the temporary convergence allocate(tempConv(size(me))) do iConv = 1, size(me) write(logUnit(10),"(A,I0)") 'Initializing convergence object ', iConv ! map variables ! create convergence variable position in the global varSys call tem_create_varMap( varname = me(iConv)%header%varname, & & varSys = varSys, & & varMap = me(iConv)%varMap ) ! @todo KM: If variable not found in varSys then skip that variable ! reduction and condition info while copying convergence ! ! Terminate if number of variables to check for convergence does not ! match with variables found in varMap if (me(iConv)%varMap%varPos%nVals /= me(iConv)%header%nRequestedVars) then write(logUnit(1),*) 'Error: Mapping Convergences variables' write(logUnit(1),*) 'Variables defined in convergence '// & & 'table ', iConv, ' are not found in varSys' call tem_abort() end if ! ----------------------------------------------------------------------- ! identify convergence elements ! ----------------------------------------------------------------------- call tem_create_subTree_of( inTree = tree, & & bc_prop = bc_prop, & & stencil = stencil, & & subTree = me( iConv )%subTree, & & storePnts = me (iConv )%header%useGetPoint, & & inShape = me( iConv )%header%geometry ) ! get rid of the empty convergence in order ! to avoid empty writes to disk if ( me(iConv)%subTree%useGlobalMesh ) then ! set convergence communicator me(iConv)%proc = globProc nConv = nConv + 1 tempConv( nConv ) = me( iConv ) else if ( me(iConv)%subTree%nElems > 0 ) then nConv = nConv + 1 ! Increase number of log ! set convergence communicator me(iConv)%proc%comm = me(iConv)%subTree%global%comm me(iConv)%proc%rank = me(iConv)%subTree%global%myPart me(iConv)%proc%comm_size = me(iConv)%subTree%global%nParts me(iConv)%proc%root = 0 ! Copy all entries from the log derived type to the temporary one. ! this might not work on all compilers!! ! This assignment is realized by operator overloader Copy_convergence tempConv( nConv ) = me( iConv ) end if ! useGlobalMesh end do ! nConv deallocate(me) allocate( me(nConv) ) do iConv = 1, nConv ! Copy the stuff from the temporary track me(iConv) = tempConv(iConv) ! number of variables in varMap nVars = me(iConv)%varMap%varPos%nVals ! nDofs is valid only for get_element if (me(iConv)%header%useGetPoint) then me(iConv)%nDofs = 1 else if (present(nDofs)) then ! out_config%nDofs is set to -1 if unspecied ! in the config file. In this case all the dof's ! should be dumped if (me(iConv)%header%nDofs < 0) then me(iConv)%nDofs = nDofs else ! Otherwise the number of dofs dumped should ! be what's specified in the config me(iConv)%nDofs = me(iConv)%header%nDofs end if else me(iConv)%nDofs = 1 end if end if if (me(iConv)%subTree%useGlobalMesh) then nElems = tree%nElems nPoints = tree%nElems else nElems = me(iConv)%subTree%nElems nPoints = me(iConv)%subTree%nPoints end if ! max nComponent in current convergence variables maxComponents = maxval(varSys%method%val(me(iConv)%varMap & & %varPos%val(:nVars))%nComponents) if (me(iConv)%header%useGetPoint) then chunkSize = min(io_buffer_size/maxComponents, nPoints) else chunkSize = min(io_buffer_size/(maxComponents*me(iConv)%nDofs), nElems) end if if ( (nElems > 0) .and. (chunkSize == 0) ) then write(logUnit(0),*)'Error in init_convergence: ' write(logUnit(0),*) 'The chosen io_buffer_size of ', io_buffer_size write(logUnit(0),*) 'is too small for evaluating ', maxComponents write(logUnit(0),*) 'scalar values' write(logUnit(0),*) 'Please increase the io_buffer_size to at & & least ', real(maxComponents*me(iConv)%nDofs) / real(131072), ' MB!' call tem_abort() end if nChunks = 0 if (chunkSize>0) then if (me(iConv)%header%useGetPoint) then nChunks = ceiling(real(nPoints, kind=rk)/real(chunkSize, kind=rk)) else nChunks = ceiling(real(nElems, kind=rk)/real(chunkSize, kind=rk)) end if else nChunks = 0 end if me(iConv)%nChunks = nChunks me(iConv)%chunkSize = chunkSize me(iConv)%nChecks = 0 ! Initialize reduction call tem_reduction_spatial_init( & & me = me(iConv)%redSpatial, & & redSpatial_config = me(iConv)%header%redSpatial_config, & & varSys = varSys, & & varPos = me(iConv)%varMap%varPos%val(:nVars) ) ! Allocate some arrays allocate( me(iConv)%lastState( me(iConv)%header%nLastVals, & & me(iConv)%varMap%nScalars ) ) me(iConv)%lastState = huge( me(iConv)%lastState(1,1) ) & & / real( me(iConv)%header%nLastVals, kind=rk ) end do deallocate(tempConv) call tem_horizontalSpacer(fUnit=logUnit(1)) end subroutine tem_init_convergence