standard_modeller_assembly_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 (standard_modeller_assembly) standard_modeller_assembly_procedures
!! author: Stefan Mijin  
!!
!! Contains the implementation of standard modeller assembly routines

implicit none

!-----------------------------------------------------------------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------------------------------------------------------------------
module subroutine initStandardModeller(modellerObj,envObj,normObj)
    !! Initialize standard modeller based on config file and normalization and environment objects

    type(Modeller)            ,intent(inout) :: modellerObj
    class(EnvironmentWrapper) ,intent(inout) :: envObj    
    class(Normalization)      ,intent(in)    :: normObj  

    type(CommunicationData)                  :: commData

    type(NamedStringArray)     ,dimension(4) :: stringArrayParams
    type(NamedString)          ,dimension(1) :: modelType
    type(NamedIntegerArray)    ,dimension(1) :: intArrayParams
    type(CompositeIntegrator)                :: integratorObj
    type(CustomModelBuilder)                 :: builderCustom

    type(CompositeManipulator) ,allocatable :: manipObj

    logical :: hasComm

    integer(ik) :: i

    if (assertions .or. assertionLvl >= 0) then 
        call assert(envObj%isDefined(),"Undefined environment wrapper passed to initStandardModeller")
        call assert(normObj%isDefined(),"Undefined normalization object passed to initStandardModeller")
    end if

    stringArrayParams(1)%name = keyModels//"."//keyTags
    allocate(stringArrayParams(1)%values(0))

    stringArrayParams(2)%name = keyMPI//"."//keyCommData//"."//keyVarsToBroadcast
    allocate(stringArrayParams(2)%values(0))

    stringArrayParams(3)%name = keyMPI//"."//keyCommData//"."//keyHaloVars
    allocate(stringArrayParams(3)%values(0))

    stringArrayParams(4)%name = keyMPI//"."//keyCommData//"."//keyScalarsToBroadcast
    allocate(stringArrayParams(4)%values(0))

    intArrayParams(1)%name = keyMPI//"."//keyCommData//"."//keyScalarsRoots
    allocate(intArrayParams(1)%values(0))

    call envObj%jsonCont%load(stringArrayParams)
    call envObj%jsonCont%load(intArrayParams)
    
    if (size(intArrayParams(1)%values) == 0 .and. size(stringArrayParams(4)%values) > 0) then 
        intArrayParams(1)%values = [(0,i=1,size(stringArrayParams(4)%values))]
    end if
    if (assertions .or. assertionLvl >= 0) then 
        call assert(size(stringArrayParams(1)%values) > 0,"No models detected by initStandardModeller")

        if (size(stringArrayParams(4)%values) > 0) then 
            call assert(size(intArrayParams(1)%values)==size(stringArrayParams(4)%values),intArrayParams(1)%name//" size must &
            &conform to size of "//stringArrayParams(4)%name)
        end if

    end if

    hasComm = size(stringArrayParams(2)%values) + size(stringArrayParams(3)%values) > 0

    if (hasComm) then
        commData%varsToBroadcast = stringArrayParams(2)%values
        commData%haloExchangeVars = stringArrayParams(3)%values
        commData%scalarsToBroadcast = stringArrayParams(4)%values
        commData%scalarRoots = intArrayParams(1)%values
    end if


    call printMessage("Initializing modeller")
    if (allocated(envObj%petscCont)) then 

        if (hasComm) then 
            call modellerObj%init(size(stringArrayParams(1)%values),envObj%externalVars,envObj%mpiCont,envObj%petscCont,commData)
        else
            call modellerObj%init(size(stringArrayParams(1)%values),envObj%externalVars,envObj%mpiCont,envObj%petscCont)
        end if 
        call printMessage("Calculating PETSc identity matrix")
        call modellerObj%calculateIdentityMat(envObj%indexingObj)

    else

        if (hasComm) then 
            call modellerObj%init(size(stringArrayParams(1)%values),envObj%externalVars,envObj%mpiCont,commData=commData)
        else
            call modellerObj%init(size(stringArrayParams(1)%values),envObj%externalVars,envObj%mpiCont)
        end if

    end if

    call printMessage("Initializing integrators")
    call initStandardIntegrator(integratorObj,envObj%externalVars,envObj%indexingObj,envObj%jsonCont,envObj%mpiCont)

    call modellerObj%setIntegrator(integratorObj)

    do i = 1,size(stringArrayParams(1)%values)
        modelType(1) = NamedString(keyModels//"."//stringArrayParams(1)%values(i)%string//"."//keyType,"")
        call envObj%jsonCont%load(modelType)
        select case (modelType(1)%value)
        case (keyCustomModel)
            call printMessage("Building model: "//stringArrayParams(1)%values(i)%string)
            call builderCustom%init(envObj,normObj,stringArrayParams(1)%values(i)%string)
            call builderCustom%addModelToModeller(modellerObj)
        case default 
            error stop "Unsupported model type detected by initStandardModeller"
        end select
    end do

    call initCompositeManipulatorFromJSON(manipObj,envObj,normObj)

    if (allocated(manipObj)) then 
        call modellerObj%setManipulator(manipObj)
    end if
    call printMessage("Assembling modeller")
    call modellerObj%assemble(withIdentityMat=allocated(envObj%petscCont))


end subroutine initStandardModeller
!-----------------------------------------------------------------------------------------------------------------------------------
end submodule standard_modeller_assembly_procedures
!-----------------------------------------------------------------------------------------------------------------------------------