!----------------------------------------------------------------------------------------------------------------------------------- ! 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 (explicit_term_abstract_class) explicit_term_abstract_procedures !! author: Stefan Mijin !! !! Contains module procedures associated with the abstract explicit term class implicit none !----------------------------------------------------------------------------------------------------------------------------------- contains !----------------------------------------------------------------------------------------------------------------------------------- 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 if (assertions) then call assert(this%isDefined(),"Attempted to update undefined explicit term object") call assert(varCont%isDefined(),"Attempted to update explicit term object by passing undefined variable container") end if if (allocated(this%termOperator)) call this%termOperator%update(varCont) 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 if (assertions) then call assertPure(this%isDefined(),"Called unityFun with undefined explicit term object") call assertPure(varCont%isDefined(),"Called unityFun by passing undefined variable container") end if allocate(res,mold=varCont%variables(varCont%getVarIndex(indexingData%evolvedVarName))%entry) res = real(1.0d00,kind=rk) end function unityFun !----------------------------------------------------------------------------------------------------------------------------------- pure module subroutine setOperator(this,op) !! Setter for termOperator class(ExplicitTerm) ,intent(inout) :: this class(Operator) ,intent(in) :: op if (allocated(this%termOperator)) deallocate(this%termOperator) allocate(this%termOperator,source=op) end subroutine setOperator !----------------------------------------------------------------------------------------------------------------------------------- pure module subroutine setNormalizationConst(this,norm) !! Setter for normalizationConst class(ExplicitTerm) ,intent(inout) :: this real(rk) ,intent(in) :: norm this%normalizationConst = 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 integer(ik) :: i if (assertions) & call assertPure(varCont%isDefined(),"Called setReqVars for explicit term by passing undefined variable container") allocate(this%indexingData%reqVarIndices(size(reqVars))) do i = 1, size(reqVars) this%indexingData%reqVarIndices(i) = varCont%getVarIndex(reqVars(i)%string) end do 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 this%indexingData%evolvedVarName = evolvedVarName if (present(operatedVarName)) then this%indexingData%operatedVarName = operatedVarName else this%indexingData%operatedVarName = evolvedVarName end if 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 if (assertions) then call assertPure(this%isDefined(),"Attempted to evaluate undefined explicit term") call assertPure(varCont%isDefined(),& "Attempted to calculate explicit term by passing undefined variable container") end if res = this%multConst * this%multFun(varCont,this%indexingData) if (allocated(this%termOperator)) & res = res * this%termOperator%actOn(varCont%variables(varCont%getVarIndex(this%indexingData%operatedVarName))%entry) end function evaluateExpTerm !----------------------------------------------------------------------------------------------------------------------------------- pure module subroutine setMultConst(this,multConst) !! Setter for multConst class(ExplicitTerm) ,intent(inout) :: this real(rk) ,dimension(:) ,intent(in) :: multConst this%multConst = multConst end subroutine setMultConst !----------------------------------------------------------------------------------------------------------------------------------- pure module function getMultConst (this) result(multConst) !! Getter for multConst class(ExplicitTerm) ,intent(in) :: this real(rk) ,allocatable ,dimension(:) :: multConst if (assertions) call assertPure(this%isDefined(),"Attempted to get multiplicative constants from undefined explicit term") multConst = this%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 if (assertions) call assertPure(this%isDefined(),"Attempted to get evolved variable name from undefined explicit term") name = this%indexingData%evolvedVarName end function getEvolvedVarName !----------------------------------------------------------------------------------------------------------------------------------- !----------------------------------------------------------------------------------------------------------------------------------- end submodule explicit_term_abstract_procedures !-----------------------------------------------------------------------------------------------------------------------------------