LoginSignup
5
1

More than 3 years have passed since last update.

modern fortran+MPIでマルチフィジクスをやる際のクラス構造(もとい構想)

Last updated at Posted at 2019-12-20

こんばんは@soybeanです。
Fortranアドベントカレンダーの記事を拝読していて、大変勉強になります。皆様、ありがとうございます。

さて、21日目はfortranとMPIでマルチフィジクスソルバーを開発する際のクラス構造設計について議論してみたいと思います。

Who am I?

農学分野のPh.D. candidateです。土質材料ー植物間の力学的相互作用について研究しています。手法としては、構造計算や数値流体力学、計算接触力学あたりを使って現象の理解と予測を行ってきました。
加えて、植物の形態が複雑であり計算不可が大きいため、PCクラスタを構築し運用しています。

Abstract

マルチフィジクス解析のプログラムを自作する場合に、プログラムの設計は悩ましい問題です。特に、メッシュ、個々の物理場、およびソルバーを、計算リソースの不要な消費を避け、スケーラブルで、可読性を失わない形でまとめるためには多大な試行錯誤が求められます。本項では、やってみなはれ精神に基づき、すべての場の離散化を有限要素法で行う場合を想定した、マルチフィジクス解析プログラムのクラス構造を作ってみました。また、MPIへの適応性も議論します。方法として、単一の初期値境界値問題に対応したFEMDomainクラスというクラス、およびFEMDomainクラス同士の弱連成解析のターゲットとなるFEMIfaceクラスを定義します。ここで、1つのFEMDomainインスタンスは、あらゆる単一の(強連成の)初期値境界値問題について、FEMで離散化され近似解を求める際に必要十分な情報を格納できます。また、FEMIfaceインスタンスはあらゆる複数の(弱連成の)初期値境界値問題について、同様に必要十分な情報を格納できます。ここに、FEMDomainクラスは、Meshクラス(節点座標、要素コネクティビティ、要素材料番号)、MaterialPropクラス(材料パラメータ)、Boundaryクラス(境界条件、初期条件)、ShapeFunctionクラス(形状関数)、ControlParameterクラス(誤差判定に使用するパラメータ、解析ステップ数)を包含(コンポジション)しています。FEMIfaceクラスは、FEMDomainへのポインター等を包含(コンポジション)しています。実際に動かすと、各ソルバーは、強連成ソルバーであればFEMDomainインスタンスを、弱連成ソルバーであればFEMIfaceインスタンスを受け取り、連立方程式へと展開し、物理場を更新したのち、更新された情報をそれぞれ上書きすることで、全体場の更新を行い、マルチフィジクス解析を完了します。あとは、より上位のプログラムで、ソルバーを呼び出す順番を記述すれば、強連成と弱連成の入り混じった解析を行えました。スケーラビリティに関しては、ソルバーを順に呼び出すループを並列化して、FEMDomainの並列読み込みと並列更新を行うことで、MPIを用いた並列計算を実装できます。加えて、大規模計算にあたっては領域分割を行い、個々のsub領域をFEMDomainに、領域のコネクティビティ情報をFEMIfaceに格納することで、MPIを利用できます。以上により、解くべきマルチフィジクス問題をFEMDomain/FEMIfaceの両クラスのインスタンス群に分解・分類することで、計算リソースの節約、スケーラビリティおよび可読性を両立できると考えました。

1. Introduction

マルチフィジクス解析のプログラムを自作する場合に、プログラムの設計は悩ましい問題です。特に、メッシュ、個々の物理場、およびソルバーを、計算リソースの不要な消費を避け、スケーラブルで、可読性を失わない形でまとめるためには多大な試行錯誤が求められます。本項では、やってみなはれ精神に基づき、すべての場の離散化を有限要素法で行う場合を想定した、マルチフィジクス解析プログラムのクラス構造を作ってみました。また、MPIへの適応性も議論します。

2. Material and Method

方法として、単一の初期値境界値問題に対応したFEMDomainクラスというクラス、



    type::FEMDomain_
        type(ShapeFunction_)    :: ShapeFunction
        type(Mesh_)             :: Mesh
        type(MaterialProp_)     :: MaterialProp
        type(Boundary_)         :: Boundary
        type(ControlParameter_) :: ControlPara
        real(real64) :: RealTime
        character*200 :: FilePath
        character*200 :: FileName
        character*9 :: Dtype
        character*20 :: SolverType
        character*200 :: Category1 
        character*200 :: Category2
        character*200 :: Category3
        integer(int32) :: timestep
    contains
        procedure,public :: Init   => InitializeFEMDomain
        procedure,public :: Delete => DeallocateFEMDomain
        procedure,public :: Export => ExportFEMDomain
        procedure,public :: Import => ImportFEMDomain
        procedure,public :: ImportMesh => ImportMeshFEMDomain

        procedure,public :: Resize => resizeFEMDomain
        procedure,public :: Merge  => MergeFEMDomain
        procedure,public :: AddDBoundCondition => AddDBoundCondition
        procedure,public :: AddNBoundCondition => AddNBoundCondition
        procedure,public :: AddTBoundCondition => AddTBoundCondition
        procedure,public :: AddMaterialID => AddMaterialID
        procedure,public :: SetDataType => SetDataType
        procedure,public :: SetSolver => SetSolver 
        procedure,public :: SetName => SetName 
        procedure,public :: SetUp      => SetUpFEMDomain
        procedure,public :: InitDBC => InitDBC
        procedure,public :: InitNBC => InitNBC
        procedure,public :: InitTBC => InitTBC
        procedure,public :: AddNBC => AddNBCFEMDomain 
        procedure :: MeltingSkelton => MeltingSkeltonFEMDomain
        procedure,public :: SetControlPara =>  SetControlParaFEMDomain
        procedure,public :: GmshPlotMesh => GmshPlotMesh
        procedure,public :: GmshPlotContour => GmshPlotContour
        procedure,public :: GmshPlotVector => GmshPlotVector 
        procedure,public :: GmshPlotContour2D => GmshPlotContour2D
        procedure,public :: GnuplotPlotContour  => GnuplotPlotContour   
        procedure,public :: GnuplotExportStress => GnuplotExportStress  
        procedure,public :: getDBCVector => getDBCVectorFEMDomain
        procedure,public :: move => moveFEMDomain
        procedure,public :: rotate => rotateFEMDomain
        procedure,public :: meshing => meshingFEMDomain
        procedure,public :: convertMeshType => convertMeshTypeFEMDomain

        ! for debug
        procedure,public :: CheckConnectivity => CheckConnedctivityFEMDomain

    end type FEMDomain_

およびFEMDomainクラス同士の弱連成解析のターゲットとなるFEMIfaceクラスを定義します。



    type,extends(FEMDomain_) :: FEMDomainPointer_
        type(FEMDomain_),pointer :: FEMDomainp

    end type


    type :: FEMIface_
        type(ShapeFunction_)    :: ShapeFunction1,ShapeFunction2
        type(Mesh_)             :: Mesh1,Mesh2 ! Mesh[12]%ElemNod is a LOCAL node pointer, not a DIRECT pointer for each domains
        type(MaterialProp_)     :: MaterialProp
        type(ControlParameter_) :: ControlPara
        type(FEMDomainPointer_),allocatable :: FEMDomains(:)
        real(real64),allocatable     :: NTN_NodCoord(:,:)
        real(real64),allocatable     :: NTS_NodCoord(:,:)
        real(real64),allocatable     :: STS_NodCoord(:,:)
        real(real64),allocatable     :: NTN_Val(:,:)
        real(real64),allocatable     :: NTS_Val(:,:)
        real(real64),allocatable     :: STS_Val(:,:)
        integer(int32),allocatable     :: NTN_ElemNod(:,:)
        integer(int32),allocatable     :: NTS_ElemNod(:,:)
        integer(int32),allocatable     :: STS_ElemNod(:,:)
        integer(int32),allocatable     :: NTN_Active(:)
        integer(int32),allocatable     :: NTS_Active(:)
        integer(int32),allocatable     :: STS_Active(:)
        real(real64),allocatable     :: NTN_Value(:,:)
        real(real64),allocatable     :: NTS_Value(:,:)
        real(real64),allocatable     :: STS_Value(:,:)
        integer(int32),allocatable     :: NTS_SegmentID(:,:)
        integer(int32),allocatable     :: GloNodPoint1(:,:),GloNodPoint2(:,:)

        integer(int32)                 :: DomainID1
        integer(int32)                 :: DomainID2
        integer(int32)                 :: DomainID3
        integer(int32)                 :: TimeStep
        integer(int32)                 :: NumOfImportedDomain
        character*200           :: FilePathDomain1
        character*200           :: FilePathDomain2
        character*200           :: FilePath

        character*200 :: FileNameDomain1
        character*200 :: FileNameDomain2
        character*200 :: FileName
        character*9   :: Dtype
        character*20  :: SolverType


    contains 
        procedure :: Init => InitializeFEMIface
        procedure :: setFEMDomain => setFEMDomainFEMIface 
        procedure :: Delete => DeallocateFEMIface
        procedure :: Import => ImportFEMIface
        procedure :: GetFEMIface => GetFEMIfaceFromFEMDomains
        procedure :: Export => ExportFEMIface
        procedure :: GmshPlotMesh => GmshPlotMeshFEMIface
        procedure :: GmshPlotNTS  => GmshPlotNTSFEMIface
        procedure :: GetNTNelement => GetNTNelement
        procedure :: GetNTSelement => GetNTSelement
        procedure :: GetGlobalNodePointer => GetGlobalNodePointerNTS
        procedure :: updateTimestep => updateTimestepIface
    end type

ここで、1つのFEMDomainインスタンスは、あらゆる単一の(強連成の)初期値境界値問題について、FEMで離散化され近似解を求める際に必要十分な情報を格納できます。また、FEMIfaceインスタンスはあらゆる複数の(弱連成の)初期値境界値問題について、同様に必要十分な情報を格納できます。

ここに、FEMDomainクラスは、

Meshクラス(節点座標、要素コネクティビティ、要素材料番号)、


    type:: Mesh_
        real(8),allocatable::NodCoord(:,:)
        real(8),allocatable::NodCoordInit(:,:)
        integer,allocatable::ElemNod(:,:)

        integer,allocatable::FacetElemNod(:,:)
        integer,allocatable::NextFacets(:,:)
        integer,allocatable::SurfaceLine2D(:)
        integer,allocatable::ElemMat(:)
        integer,allocatable::SubMeshNodFromTo(:,:)
        integer,allocatable::SubMeshElemFromTo(:,:)
        integer,allocatable::SubMeshSurfFromTo(:,:)
        integer :: surface

        !for Interfaces
        integer,allocatable::GlobalNodID(:)

        character*70::ElemType
        character*70 ErrorMsg
    contains
        procedure :: Init => InitializeMesh
        procedure :: Delete => DeallocateMesh
        procedure :: Copy => CopyMesh
        procedure :: import => importMeshObj 
        procedure :: ImportElemNod => ImportElemNod
        procedure :: ImportNodCoord => ImportNodCoord
        procedure :: ImportElemMat => ImportElemMat

        procedure :: resize => resizeMeshobj
        procedure :: GetFacetElement => GetFacetElement
        procedure :: GetSurface => GetSurface
        procedure :: GetInterface => GetInterface
        procedure :: GetInterfaceElemNod => GetInterfaceElemNod
        procedure :: GetBoundingBox     => GetBoundingBox
        procedure :: GetFacetElemInsideBox => GetFacetElemInsideBox
        procedure :: GetInterSectBox => GetInterSectBox
        procedure :: GetNextFacets => GetNextFacets
        procedure :: MergeMesh => MergeMesh
        procedure :: ExportElemNod => ExportElemNod
        procedure :: ExportNodCoord => ExportNodCoord
        procedure :: ExportSurface2D => ExportSurface2D
        procedure :: DisplayMesh => DisplayMesh 
        procedure :: ShowMesh => ShowMesh 
        procedure :: MeltingSkelton => MeltingSkeltonMesh 
        procedure :: getNumOfDomain => getNumOfDomainMesh
        procedure :: SortFacet    => SortFacetMesh 
        procedure :: Meshing    => MeshingMesh
        procedure :: getCircumscribedCircle => getCircumscribedCircleMesh
        procedure :: getCircumscribedTriangle => getCircumscribedTriangleMesh
        procedure :: removeCircumscribedTriangle => removeCircumscribedTriangleMesh

        procedure :: DelauneygetNewNode => DelauneygetNewNodeMesh 
        procedure :: DelauneygetNewTriangle => DelauneygetNewTriangleMesh 
        procedure :: DelauneyremoveOverlaps => DelauneyremoveOverlapsMesh 
        procedure :: RemoveFailedTriangle => RemoveFailedTriangleMesh
        procedure :: GetElemType => GetElemTypeMesh 

        procedure :: convertMeshType => ConvertMeshTypeMesh
        procedure :: convertTetraToHexa => convertTetraToHexaMesh 
        procedure :: convertTriangleToRectangular => convertTriangleToRectangularMesh 
        procedure :: removeOverlappedNode =>removeOverlappedNodeMesh
    end type Mesh_

MaterialPropクラス(材料パラメータ)



    type :: MaterialProp_
        real(real64),allocatable::MatPara(:,:)
        integer(int32) :: NumOfMatPara
        integer(int32) :: NumOfMaterial    

        character*40 :: MaterialType

        character*70 ErrorMsg
    contains
        procedure :: Init => initializeMaterial
        procedure :: Delete => DeallocateMaterialProp
    end type MaterialProp_


Boundaryクラス(境界条件、初期条件)、



    type::Boundary_
        real(real64),allocatable::DBoundVal(:,:)
        real(real64),allocatable::NBoundVal(:,:)  
        real(real64),allocatable::TBoundVal(:,:)  
        real(real64),allocatable::TBoundElemGpVal(:,:,:)      

        real(real64),allocatable::DBoundValInc(:,:)
        real(real64),allocatable::NBoundValInc(:,:)  
        real(real64),allocatable::TBoundValInc(:,:)

        integer(int32),allocatable::DBoundNodID(:,:)
        integer(int32),allocatable::NBoundNodID(:,:)
        integer(int32),allocatable::TBoundNodID(:,:)
        integer(int32),allocatable::TBoundElemID(:)

        integer(int32),allocatable::DBoundNum(:)
        integer(int32),allocatable::NBoundNum(:)
        integer(int32),allocatable::TBoundNum(:)
        integer(int32),allocatable::TBoundElemNum(:)


        character*70 :: ErrorMsg
    contains
        procedure :: Init => InitializeBoundary
        procedure :: Delete => DeallocateBoundary
        procedure :: CheckDataType => CheckDatatypeBoundary
        procedure :: RemoveOverlap => DeleteOverlapBoundary
        procedure :: ImportDBound => ImportDBound
        procedure :: ImportNBound => ImportNBound
        procedure :: MergeDBound => MergeDBound
        procedure :: MergeNBound => MergeNBound

        procedure :: removeDBC => removeDBCBoundary        
        procedure :: removeNBC => removeNBCBoundary
        procedure :: removeTBC => removeTBCBoundary        
    end type Boundary_


ShapeFunctionクラス(形状関数)、



    type::ShapeFunction_

        real(real64),allocatable::Nmat(:)
        real(real64),allocatable::dNdgzi(:,:)
        real(real64),allocatable::dNdgzidgzi(:,:)
        real(real64),allocatable::gzi(:)
        real(real64),allocatable::GaussPoint(:,:)
        real(real64),allocatable::GaussIntegWei(:)
        real(real64),allocatable::Jmat(:,:),JmatInv(:,:)
        real(real64),allocatable::ElemCoord(:,:)
        real(real64),allocatable::ElemCoord_n(:,:)
        real(real64),allocatable::du(:,:)

        real(real64) :: detJ

        integer(int32) :: NumOfNode
        integer(int32) :: NumOfOrder
        integer(int32) :: NumOfDim
        integer(int32) :: NumOfGp
        integer(int32) :: GpID
        integer(int32) :: ierr
        integer(int32) :: currentGpID

        character*70::ElemType
        character(len=60):: ErrorMsg
    contains
        procedure :: init => initShapeFunction
        procedure :: update => updateShapeFunction

        procedure :: SetType => SetShapeFuncType
        procedure :: GetAll  => GetAllShapeFunc
        procedure :: Deallocate => DeallocateShapeFunction
        procedure :: getType => getShapeFuncType 
        procedure :: GetGaussPoint => GetGaussPoint
    end type ShapeFunction_


ControlParameterクラス(誤差判定に使用するパラメータ、解析ステップ数)


    type::ControlParameter_
        real(real64) :: Tol
        integer(int32) :: SimMode
        integer(int32) :: ItrTol
        integer(int32) :: Timestep
    contains
        procedure,public :: SetControlPara => SetControlPara
    end type ControlParameter_



を包含(コンポジション)しています。FEMIfaceクラスは、FEMDomainへのポインター等を包含(コンポジション)しています。

3. Results and Discussion

実際に動かすプログラムは、非常にスッキリします。


program main
    use SimulatorClass

    implicit none ! 美しくない一文

    type(Field_),target     :: world
    integer,parameter       :: TotalStep=40
    real(8),parameter       :: time=1.0d0

    call world%Import()
    call Simulator(world,OptionalStep=TotalStep,OptionalTime=time)
    call world%Export()

end program 

Simulator内に格納された各ソルバーは、強連成ソルバーであればFEMDomainインスタンスを、弱連成ソルバーであればFEMIfaceインスタンスを受け取り、連立方程式へと展開し、物理場を更新したのち、更新された情報をそれぞれ上書きすることで、全体場の更新を行い、マルチフィジクス解析を完了します。

ここに、Simulatorクラスは各種ソルバーをコンポジットしているクラスです。



    type :: Simulator_
        type(DiffusionEq_) ,allocatable :: DiffusionEq_Array(:)
        type(FiniteDeform_),allocatable :: FiniteDeform_Array(:)
        type(MultiPhysics_)  ,allocatable :: MultiPhysics_Array(:)
        type(ContactMechanics_),allocatable :: ContactMechanics_Array(:)
    contains
        procedure :: Deploy => DeploySimulator
        procedure :: SetTime => SetSimulatorTime
        procedure :: Run => RunSimulation
        procedure :: Display => DisplaySimulation
    end type


ここに、Simulatorメソッドは、ソルバー群をFEMDomain/FEMIface群にデプロイし、時間を進めます。



subroutine Simulator(world,OptionalStep,OptionalTime,SolverType)
    class(Field_),target,intent(inout)   :: world
    type(Simulator_),target             :: sim
    type(MPI_) :: mpidata
    integer(int32),intent(in)  :: OptionalStep
    real(real64),intent(in)  :: OptionalTime
    character(*),optional,intent(in)::SolverType
    integer(int32)                 :: i,Step,ierr
    real(real64)                 :: time

    step=OptionalStep
    time=OptionalTime

    call sim%Deploy(world)
    call sim%SetTime(world,time,step)
    do i=1,step
        call sim%Run(world,i,SolverType=SolverType)
        call sim%Display(world,i)
    enddo

end subroutine

ここに、FieldクラスはFEMDomain群とFEMIface群をコンポジットしているクラスです。




    type :: Field_
        type(FEMDomain_),allocatable::FEMDomainArray(:)
        type(FEMIface_) ,allocatable::FEMIfaceArray(:)
        type(FieldObjName_),allocatable::FieldList(:)
        integer(int32),allocatable::Timestep(:)
        real(real64),allocatable::RealTime(:)
        integer(int32) :: NumberOfObject,NumberOfIface

        character*200 :: FolderName
        character*200 :: DomainListName
        character*200 :: IfaceListName
    contains
        procedure :: Import => ImportField
        procedure :: show   => showField
        procedure :: Export => ExportField
        procedure :: Shift  => ShiftField

        procedure :: linkDomainToIface => linkDomainToIfaceField
    end type

ソルバー群のFieldインスタンスへのデプロイは、ポインタでポイントすることで行います。




subroutine DeploySimulator(sim,field)
    type(Field_),target,intent(inout)  :: field
    class(Simulator_),intent(inout) :: sim
    integer(int32) :: i,j,n,DomainNum,ierr

    if(.not.allocated(sim%DiffusionEq_Array) ) then
        call InitializeSimulator(sim,field)
    endif

    n=size(field%FEMDomainArray,1)
    DomainNum=n
    do i=1,n
        if(trim(field%FEMDomainArray(i)%SolverType)=="DiffusionEq_" )then
            sim%DiffusionEq_Array(i)%FEMDomain => field%FEMDomainArray(i)
        elseif(trim(field%FEMDomainArray(i)%SolverType)=="FiniteDeform_" )then
            sim%FiniteDeform_Array(i)%FEMDomain => field%FEMDomainArray(i)
        else
            print *, "DeploySolver >> Invalid Solver Name : ",trim(field%FEMDomainArray(i)%SolverType)
            stop
        endif
    enddo

    n=size(field%FEMIfaceArray,1)

    do i=1,n
        if(trim(field%FEMIfaceArray(i) %SolverType)=="SyncMesh_" .or. &
            trim(field%FEMIfaceArray(i)%SolverType)=="syncmesh_" )then
            sim%MultiPhysics_Array(i)%FEMIFace => field%FEMIfaceArray(i)

            do j=1, DomainNum
                if(trim(sim%MultiPhysics_Array(i)%FEMIFace%FileNameDomain1) == &
                    trim(field%FEMDomainArray(j)%FileName)  )then
                    sim%MultiPhysics_Array(i)%FEMDomain1 => field%FEMDomainArray(j)

                endif
                if(trim(sim%MultiPhysics_Array(i)%FEMIFace%FileNameDomain2) == &
                    trim(field%FEMDomainArray(j)%FileName)  )then
                    sim%MultiPhysics_Array(i)%FEMDomain2 => field%FEMDomainArray(j)
                endif
            enddo
        elseif(trim(field%FEMIfaceArray(i) %SolverType)=="ContactMechanics_" .or. &
            trim(field%FEMIfaceArray(i)%SolverType)=="contactmechanics_" )then
            sim%ContactMechanics_Array(i)%FEMIFace => field%FEMIfaceArray(i)
            do j=1, DomainNum
                if(trim(sim%ContactMechanics_Array(i)%FEMIFace%FileNameDomain1) == &
                    trim(field%FEMDomainArray(j)%FileName)  )then
                    sim%ContactMechanics_Array(i)%FEMDomain1 => field%FEMDomainArray(j)

                endif
                if(trim(sim%ContactMechanics_Array(i)%FEMIFace%FileNameDomain2) == &
                    trim(field%FEMDomainArray(j)%FileName)  )then

                    sim%ContactMechanics_Array(i)%FEMDomain2 => field%FEMDomainArray(j)
                endif
            enddo


        else
            print *, "DeploySolver >> Invalid Solver Name : ",trim(field%FEMIfaceArray(i) %SolverType)
            stop "debug"
        endif
    enddo
end subroutine




スケーラビリティに関しては、ソルバーを順に呼び出すループを並列化して、FEMDomainの並列読み込みと並列更新を行うことで、MPIを用いた並列計算を実装できます。加えて、大規模計算にあたっては領域分割を行い、個々のsub領域をFEMDomainに、領域のコネクティビティ情報をFEMIfaceに格納することで、MPIを利用できます。これらの詳細な実装については今後折をみて行いたいと考えています。

また、おまけとして、MPIを呼ぶためのクラスを作りました。



    type :: comment
        character*200 :: comment
    endtype

    type:: MPI_


        integer(int32) :: ierr
        integer(int32) :: MyRank
        integer(int32) :: PeTot
        integer(int32) :: Comm1
        integer(int32) :: Comm2
        integer(int32) :: Comm3
        integer(int32) :: Comm4
        integer(int32) :: Comm5
        integer(int32),allocatable::Comm(:),key(:)
        integer(int32),allocatable::Stack(:,:),localstack(:)
        integer(int32) :: LapTimeStep
        real(real64) :: stime
        real(real64) :: etime
        real(real64) :: laptime(1000)
        type(comment) :: comments(1000)

    contains
        procedure :: Start => StartMPI
        procedure :: Barrier => BarrierMPI
        procedure, Pass ::  readMPIInt
        procedure, Pass ::  readMPIReal
        generic ::  read =>   readMPIInt,readMPIReal

        procedure, Pass :: BcastMPIInt
        procedure, Pass :: BcastMPIReal
        generic  :: Bcast => BcastMPIInt, BcastMPIReal

        procedure, Pass :: GatherMPIInt 
        procedure, Pass :: GatherMPIReal 
        generic :: Gather => GatherMPIInt, GatherMPIReal 


        procedure, Pass :: ScatterMPIInt 
        procedure, Pass :: ScatterMPIReal 
        generic :: Scatter => ScatterMPIInt, ScatterMPIReal 


        procedure, Pass :: AllGatherMPIInt 
        procedure, Pass :: AllGatherMPIReal 
        generic :: AllGather => AllGatherMPIInt, AllGatherMPIReal 

        procedure, Pass :: AlltoAllMPIInt 
        procedure, Pass :: AlltoAllMPIReal 
        generic :: AlltoAll => AlltoAllMPIInt, AlltoAllMPIReal 


        procedure, Pass :: ReduceMPIInt 
        procedure, Pass :: ReduceMPIReal 
        generic :: Reduce => ReduceMPIInt, ReduceMPIReal 

        procedure, Pass :: AllReduceMPIInt 
        procedure, Pass :: AllReduceMPIReal 
        generic :: AllReduce => AllReduceMPIInt, AllReduceMPIReal 

        procedure :: createStack => createStackMPI
        procedure :: showStack   => showStackMPI
        procedure :: free  => freeMPI 
        procedure :: split => splitMPI 
        procedure :: copy  => copyMPI 
        procedure :: End => EndMPI
        procedure :: getLapTime => getLapTimeMPI
        procedure :: showLapTime => showLapTimeMPI
        procedure :: GetInfo => GetMPIInfo
    end type    


こちらのクラスを使うと、簡単にMPIできます。


program main
 use MPIClass
 implicit none

 type(MPI_)::mpid

 call mpid%start()

 print *, "My rank is :: ", mpid%MyRank

 call mpid%end()

end program 

4. Conclusion

以上により、解くべきマルチフィジクス問題をFEMDomain/FEMIfaceの両クラスのインスタンス群に分解・分類することで、計算リソースの節約、スケーラビリティおよび可読性を両立できると考えました。

Acknowledgements

Implementation

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1