fixed_ecs_transition_procedures.f90 Source File


Source Code

!-----------------------------------------------------------------------------------------------------------------------------------
! This file is part of ReMKiT1D.
!
! ReMKiT1D is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as 
! published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
!
! ReMKiT1D is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License along with ReMKiT1D. If not, see <https://www.gnu.org/licenses/>. 
!
! Copyright 2023 United Kingdom Atomic Energy Authority (stefan.mijin@ukaea.uk)
!-----------------------------------------------------------------------------------------------------------------------------------
submodule (fixed_ecs_transition_class) fixed_ecs_transition_procedures
!! author: Stefan Mijin 
!! 
!! Contains module procedures associated with the fixed energy and cross section transition class

implicit none

!-----------------------------------------------------------------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------------------------------------------------------------------
!-----------------------------------------------------------------------------------------------------------------------------------
pure module subroutine initFixedECSTransition(this,locNumX,inStates,outStates,energy,crossSection,distVarIndex,refVSpace, &
                                              fixedWIndex,momentumMoment, l1Index) 
    !! Initialization routine for FixedECSTransition object

    class(FixedECSTransition)          ,intent(inout)  :: this
    integer(ik)                        ,intent(in)     :: locNumX !! Local number of spatial cells
    integer(ik)  ,dimension(:)         ,intent(in)     :: inStates !! Pre-transition states
    integer(ik)  ,dimension(:)         ,intent(in)     :: outStates !! Post-transition states
    real(rk)                           ,intent(in)     :: energy !! Transition energy
    real(rk) ,dimension(:,:)           ,intent(in)     :: crossSection !! Cross-section harmonics
    integer(ik)                        ,intent(in)     :: distVarIndex !! Distribution function variable index
    type(VSpace) ,target               ,intent(inout)  :: refVSpace !! Target for the reference pointer
    integer(ik)                        ,intent(in)     :: fixedWIndex !! Index of the inelastic weigth array corresponding to this transition
    logical ,optional                  ,intent(in)     :: momentumMoment !! Set to true if the momentum rate should be calculated
    integer(ik) ,optional              ,intent(in)     :: l1Index !! Index of the l=1 harmonic - must be provided if calculating momentum rate

    real(rk) ,allocatable ,dimension(:) :: rateVec

    if (assertions .or. assertionLvl >= 0) then 
        call assertPure(refVSpace%isDefined(),&
        "Undefined target VSpace object passed to fixed energy/cross-section transition constructor")
        if (present(momentumMoment)) then 
            if (momentumMoment) call assertPure(present(l1Index),"When momentumMoment is set to true in FixedECSTransition &
            &cosntructor the l1Index must be provided")
        end if
    end if

    this%locNumX = locNumX 
    allocate(rateVec(locNumX))
    rateVec = 0 
    call this%setRate(rateVec)
    this%takeMomentumMoment = .false.
    this%distFunVarIndex = distVarIndex
    this%transitionEnergy = energy 
    if (present(momentumMoment)) then 
        if (momentumMoment) call this%setRateMomentum(rateVec)
        this%takeMomentumMoment = .true. 
        this%l1HarmonicInd = l1Index
    end if 

    call this%setStates(inStates,outStates)

    this%vSpaceRef => refVSpace 
    this%fixedWIndex = fixedWIndex

    call this%setCrossSection(crossSection)
    call this%setCSDim(1)

    call this%setIncludeElectronDensity(.true.)

    call this%makeDefined()


end subroutine initFixedECSTransition
!-----------------------------------------------------------------------------------------------------------------------------------
pure module function getEnergy(this) result(energyCost)
    !! Returns array representing energy cost of this transition 

    class(FixedECSTransition)            ,intent(in) :: this 
    real(rk) ,allocatable ,dimension(:)            :: energyCost

    if (assertions) call assertPure(this%isDefined(),"getEnergy called on undefined FixedECSTransition object")

    allocate(energyCost(1))
    energyCost = this%transitionEnergy

end function getEnergy
!-----------------------------------------------------------------------------------------------------------------------------------
module subroutine updateRates(this,varCont,hostModel,hostData,updatePriority)
    !! Update transition and moment exchange rate (if applicable)

    class(FixedECSTransition)       ,intent(inout)  :: this
    type(VariableContainer)         ,intent(in)     :: varCont !! Variable container used in update
    class(ModelSurrogate) ,optional ,intent(in)     :: hostModel !! Host model - unused
    class(ModelboundData) ,optional ,intent(in)     :: hostData !! Host data used to determine emitting cells for discrete cross-section
    integer(ik) ,optional           ,intent(in)     :: updatePriority !! Priority for this update call - unused

    real(rk) ,allocatable ,dimension(:) :: rateBuffer , emissionVec
    integer(ik) :: inferredHaloWidth

    if (assertions) then 
        call assert(this%isDefined(),"Attempted to update undefined FixedECSTransition object")
        call assert(varCont%isDefined(),"Attempted to update FixedECSTransition object using undefined variable container")
    end if

    select type (hostData)
        type is (ModelboundCRMData)
            emissionVec = hostData%getFixedEmissionVector(this%fixedWIndex)
        class default 
            error stop "incompatible modelbound data passed to FixedECSTransition update routine"
        end select

    rateBuffer = this%vSpaceRef%calculateMoment(varCont%variables(this%distFunVarIndex)%entry,1,1,&
                                                this%getCrossSectionCol(1)*emissionVec)
    
    inferredHaloWidth = (size(rateBuffer) - this%locNumX)/2
    call this%setRate(rateBuffer(1+inferredHaloWidth:this%locNumX+inferredHaloWidth)) !Remove halo before saving
    call this%setRateEnergy(rateBuffer(1+inferredHaloWidth:this%locNumX+inferredHaloWidth)*this%transitionEnergy) 

    if (this%takeMomentumMoment) then

        rateBuffer = this%vSpaceRef%calculateMoment(varCont%variables(this%distFunVarIndex)%entry,&
                                                    this%l1HarmonicInd,2,this%getCrossSectionCol(2)*emissionVec)

        call this%setRateMomentum(rateBuffer(1+inferredHaloWidth:this%locNumX+inferredHaloWidth)) !Remove halo before saving
        
    end if

end subroutine updateRates 
!-----------------------------------------------------------------------------------------------------------------------------------
elemental module subroutine finalizeFixedECSTransition(this) 
    !! Deallocate pointer component

    type(FixedECSTransition)                    ,intent(inout) :: this

    nullify(this%vSpaceRef)

end subroutine finalizeFixedECSTransition 
!-----------------------------------------------------------------------------------------------------------------------------------
end submodule fixed_ecs_transition_procedures
!-----------------------------------------------------------------------------------------------------------------------------------