explicit_term_abstract.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)
!-----------------------------------------------------------------------------------------------------------------------------------
module explicit_term_abstract_class
    !! author: Stefan Mijin 
    !! 
    !! Houses abstract explicit term interfaces

    use data_kinds                     ,only: rk, ik
    use runtime_constants              ,only: debugging, assertions
    use god_objects                    ,only: Object
    use assertion_utility              ,only: assert, assertIdentical, assertPure
    use support_types                  ,only: RealArray ,IntArray ,StringArray
    use variable_list_class            ,only: VariableList
    use variable_container_class       ,only: VariableContainer
    use term_abstract_class            ,only: Term
    use operator_abstract_class        ,only: Operator
    use modelbound_data_abstract_class ,only: ModelboundData
    use model_surrogate_class          ,only: ModelSurrogate

    implicit none
    private
    
    type ,public :: ExplicitTermIndexingData
        !! Indexing data used by the default abstract explicit term

        integer(ik)         ,allocatable ,dimension(:) :: reqVarIndices !! Indices of variables required by the multiplicative function
        character(:)        ,allocatable               :: evolvedVarName !! Name of evolved variable
        character(:)        ,allocatable               :: operatedVarName !! Name of variable to which the term's operator should be applied
        
    end type

    type ,public ,extends(term) ,abstract :: ExplicitTerm
        !! Abstract term providing basic interfaces for build terms used in explicit timestepping

        real(rk)            ,allocatable ,dimension(:) ,private :: multConst !! Multiplicative constant with size conforming to the variable being evolved
        real(rk)                                       ,private :: normalizationConst = real(1.0d0,kind=rk) !! Normalization constant of this term 

        type(ExplicitTermIndexingData)                 ,private :: indexingData !! Indexing data used by this term 
        
        class(Operator)     ,allocatable               ,private :: termOperator !! Optional operator used by this term

        contains

        procedure ,public  :: setOperator
        procedure ,public  :: setNormalizationConst
        procedure ,public  :: getNormalizationConst
        procedure ,public  :: setReqVars
        procedure ,public  :: setEvolvedAndOperatedVar
        procedure ,public  :: evaluate => evaluateExpTerm

        procedure ,public  :: getMultConst
        procedure ,public  :: setMultConst

        procedure ,private :: multFun => unityFun
        procedure ,public  :: update => simpleUpdate

        procedure ,public  :: getVarName => getEvolvedVarName

    end type ExplicitTerm
!-----------------------------------------------------------------------------------------------------------------------------------
    interface 
!-----------------------------------------------------------------------------------------------------------------------------------
    module subroutine simpleUpdate(this,varCont,modelData,hostModel) 
        !! Default update function - just calls update on Operator if allocated

        class(ExplicitTerm)             ,intent(inout)  :: this
        type(VariableContainer)         ,intent(in)     :: varCont !! Variable container used in update 
        class(ModelboundData) ,optional ,intent(in)     :: modelData !! Reference model data - unused
        class(ModelSurrogate) ,optional ,intent(in)     :: hostModel !! Host model - unused

    end subroutine simpleUpdate
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function unityFun(this,varCont,indexingData) result(res)
        !! Default multiplicative function - returns a real vector of ones based on evolvedVarName. In general should use passed
        !! variable container and indexing data to construct a vector conforming to the evolved variable

        class(ExplicitTerm)             ,intent(in)   :: this
        type(VariableContainer)         ,intent(in)   :: varCont
        type(ExplicitTermIndexingData)  ,intent(in)   :: indexingData

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

    end function unityFun
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module subroutine setOperator(this,op) 
        !! Setter for termOperator

        class(ExplicitTerm)       ,intent(inout)  :: this
        class(Operator)           ,intent(in)     :: op

    end subroutine setOperator
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module subroutine setNormalizationConst(this,norm) 
        !! Setter for normalizationConst

        class(ExplicitTerm)       ,intent(inout)  :: this
        real(rk)                  ,intent(in)     :: norm

    end subroutine setNormalizationConst
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function getNormalizationConst (this) result(norm)
        !! Getter for normalizationConst

        class(ExplicitTerm)  ,intent(in) :: this
        real(rk)                         :: norm

    end function getNormalizationConst
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module subroutine setReqVars(this,reqVars,varCont) 
        !! Set variable names required by the multiplicative function and find their indices in variable container

        class(ExplicitTerm)               ,intent(inout)  :: this
        type(StringArray) ,dimension(:)   ,intent(in)     :: reqVars
        type(VariableContainer)           ,intent(in)     :: varCont

    end subroutine setReqVars
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module subroutine setEvolvedAndOperatedVar(this,evolvedVarName,operatedVarName) 
        !! Set evolved and operated (if applicable) variable names

        class(ExplicitTerm)       ,intent(inout)  :: this
        character(*)              ,intent(in)     :: evolvedVarName
        character(*)   ,optional  ,intent(in)     :: operatedVarName

    end subroutine setEvolvedAndOperatedVar
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function evaluateExpTerm (this,varCont) result(res)
        !! Evaluates the term as multConst * multFun [* operatorTerm%actOn(<operatedVar>)] depending on whether the Operator is allocated

        class(ExplicitTerm)                  ,intent(in) :: this
        type(VariableContainer)              ,intent(in) :: varCont
        real(rk) ,allocatable ,dimension(:)              :: res

    end function evaluateExpTerm
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module subroutine setMultConst(this,multConst) 
        !! Setter for multConst

        class(ExplicitTerm)           ,intent(inout)  :: this
        real(rk)        ,dimension(:) ,intent(in)     :: multConst

    end subroutine setMultConst
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function getMultConst (this) result(multConst)
        !! Getter for multConst

        class(ExplicitTerm)                          ,intent(in) :: this
        real(rk)          ,allocatable ,dimension(:)             :: multConst

    end function getMultConst
!-----------------------------------------------------------------------------------------------------------------------------------
    pure module function getEvolvedVarName(this) result(name)
        !! Get name of the evolved variable of this term

        class(ExplicitTerm)                  ,intent(in) :: this
        character(:) ,allocatable                        :: name

    end function getEvolvedVarName
!-----------------------------------------------------------------------------------------------------------------------------------
    end interface
!-----------------------------------------------------------------------------------------------------------------------------------
 end module explicit_term_abstract_class
!-----------------------------------------------------------------------------------------------------------------------------------