MaterialPropClass.f90 Source File


Contents

Source Code


Source Code

module MaterialPropClass
    use, intrinsic :: iso_fortran_env
    use MeshClass
    implicit none

    type :: MaterialProp_
        type(Mesh_) :: Mesh
        real(real64),allocatable:: meshPara(:,:)

        real(real64) ::x_max,x_min,y_max,y_min,z_max,z_min,t_max,t_min
        integer(int32) :: Mcount
        
        integer(int32) :: layer
        character(200) :: Name= " "


        real(real64),allocatable::MatPara(:,:)
        integer(int32) :: NumOfMatPara
        integer(int32) :: NumOfMaterial    
        
        character*40 :: MaterialType= " "

        character*70 :: ErrorMsg= " "
    contains
        procedure :: Init => initializeMaterial
        procedure :: export => exportMaterialProp
        procedure :: save => saveMaterialProp
        procedure :: Delete => DeallocateMaterialProp
        procedure :: create => createMaterialProp
        procedure :: set => setMaterialProp
        procedure :: gmsh => gmshMaterialProp
        procedure :: show => showMaterialProp
        procedure :: getValues => getValuesMaterialProp
        procedure :: remove => removeMaterialProp
        procedure :: open => openMaterialProp
        
    end type MaterialProp_

contains

! ###########################################################################
subroutine openMaterialProp(obj,path,name)
    class(MaterialProp_),intent(inout)::obj
    character(*),intent(in) :: path
    character(*),optional,intent(in) :: name
    type(IO_) :: f

    if(present(name) )then
        call f%open(trim(path)//"/"//trim(adjustl(name))//"/","Material",".prop")
        call obj%Mesh%open(path=trim(path)//"/"//trim(adjustl(name)),name="Mesh")
        call openArray(f%fh,obj%meshPara)
        read(f%fh,*) obj%x_max
        read(f%fh,*) obj%x_min
        read(f%fh,*) obj%y_max
        read(f%fh,*) obj%y_min
        read(f%fh,*) obj%z_max
        read(f%fh,*) obj%z_min
        read(f%fh,*) obj%t_max
        read(f%fh,*) obj%t_min
        read(f%fh,*) obj%Mcount
        read(f%fh,*) obj%layer
        read(f%fh, '(A)' ) obj%Name
        call openArray(f%fh, obj%MatPara)
        read(f%fh,*) obj%NumOfMatPara
        read(f%fh,*) obj%NumOfMaterial    
        read(f%fh, '(A)') obj%MaterialType
        read(f%fh, '(A)') obj%ErrorMsg
        call f%close()
    else
        call execute_command_line("mkdir -p "//trim(path)//"/Material")
        call f%open(trim(path)//"/Material/","Material",".prop")
        call obj%Mesh%open(path=trim(path)//"/"//"Material",name="Mesh")
        call openArray(f%fh,obj%meshPara)
        read(f%fh,*) obj%x_max
        read(f%fh,*) obj%x_min
        read(f%fh,*) obj%y_max
        read(f%fh,*) obj%y_min
        read(f%fh,*) obj%z_max
        read(f%fh,*) obj%z_min
        read(f%fh,*) obj%t_max
        read(f%fh,*) obj%t_min
        read(f%fh,*) obj%Mcount
        read(f%fh,*) obj%layer
        read(f%fh, '(A)' ) obj%Name
        call openArray(f%fh, obj%MatPara)
        read(f%fh,*) obj%NumOfMatPara
        read(f%fh,*) obj%NumOfMaterial    
        read(f%fh, '(A)') obj%MaterialType
        read(f%fh, '(A)') obj%ErrorMsg
        call f%close()
    endif



end subroutine
! ###########################################################################

! ###########################################################################
subroutine removeMaterialProp(obj)
    class(MaterialProp_),intent(inout) :: obj

    call obj%Mesh%remove()
    if(allocated( obj%meshPara))then
        deallocate(obj%meshPara)
    endif

    obj%x_max=0.0d0
    obj%x_min=0.0d0
    obj%y_max=0.0d0
    obj%y_min=0.0d0
    obj%z_max=0.0d0
    obj%z_min=0.0d0
    obj%t_max=0.0d0
    obj%t_min=0.0d0
    obj%Mcount=1
    obj%layer=1
    obj%Name=" "


    if(allocated(obj%MatPara))then
        deallocate(obj%MatPara)
    endif

    obj%NumOfMatPara=1
    obj%NumOfMaterial    =1
    
    obj%MaterialType=" "
    obj%ErrorMsg=" "

end subroutine
! ###########################################################################

! ###########################################################################
subroutine createMaterialProp(obj,Name,x_max,x_min,y_max,y_min,z_max,z_min,t_max,t_min,&
    ParaValue,Layer)
    class(MaterialProp_),intent(inout) :: obj
    character(*),optional,intent(in) :: Name
    real(real64),optional,intent(in) :: x_max,x_min,y_max,y_min,z_max,z_min,t_max,t_min
    real(real64),optional,intent(in) :: ParaValue
    integer(int32),optional,intent(in) :: Layer
    if(present(Name) )then
        obj%Name=trim(adjustl(name))
    else
        obj%Name="NoName"
    endif
    call obj%set(x_max=x_max,x_min=x_min,y_max=y_max,y_min=y_min,z_max=z_max,&
        z_min=z_min,t_max=t_max,t_min=t_min,ParaValue=ParaValue,Layer=Layer)
        
end subroutine
! ###########################################################################


! ###########################################################################
subroutine saveMaterialProp(obj,path,name)
    class(MaterialProp_),intent(inout)::obj
    character(*),intent(in) :: path
    character(*),optional,intent(in) :: name
    type(IO_) :: f

    if(present(name) )then
        call execute_command_line("mkdir -p "//trim(path)//"/"//trim(adjustl(name)))
        call f%open(trim(path)//"/"//trim(adjustl(name))//"/","Material",".prop")
        call obj%Mesh%save(path=trim(path)//"/"//trim(adjustl(name)),name="Mesh")
        call writeArray(f%fh, obj%meshPara)
        write(f%fh,*) obj%x_max
        write(f%fh,*) obj%x_min
        write(f%fh,*) obj%y_max
        write(f%fh,*) obj%y_min
        write(f%fh,*) obj%z_max
        write(f%fh,*) obj%z_min
        write(f%fh,*) obj%t_max
        write(f%fh,*) obj%t_min
        write(f%fh,*) obj%Mcount
        write(f%fh,*) obj%layer
        write(f%fh, '(A)' ) trim(obj%Name)
        call writeArray(f%fh, obj%MatPara)
        write(f%fh,*) obj%NumOfMatPara
        write(f%fh,*) obj%NumOfMaterial    
        write(f%fh, '(A)') trim(obj%MaterialType)
        write(f%fh, '(A)') trim(obj%ErrorMsg)
        call f%close()
    else
        call execute_command_line("mkdir -p "//trim(path)//"/Material")
        call f%open(trim(path)//"/Material/","Material",".prop")
        call obj%Mesh%save(path=trim(path)//"/"//"Material",name="Mesh")
        call writeArray(f%fh, obj%meshPara)
        write(f%fh,*) obj%x_max
        write(f%fh,*) obj%x_min
        write(f%fh,*) obj%y_max
        write(f%fh,*) obj%y_min
        write(f%fh,*) obj%z_max
        write(f%fh,*) obj%z_min
        write(f%fh,*) obj%t_max
        write(f%fh,*) obj%t_min
        write(f%fh,*) obj%Mcount
        write(f%fh,*) obj%layer
        write(f%fh, '(A)' ) trim(obj%Name)
        call writeArray(f%fh, obj%MatPara)
        write(f%fh,*) obj%NumOfMatPara
        write(f%fh,*) obj%NumOfMaterial    
        write(f%fh, '(A)') trim(obj%MaterialType)
        write(f%fh, '(A)') trim(obj%ErrorMsg)
        call f%close()
    endif

end subroutine
! ###########################################################################


! ###########################################################################
subroutine exportMaterialProp(obj,restart,path)
    class(MaterialProp_),intent(inout)::obj
    logical,optional,intent(in) :: restart
    character(*),intent(in) :: path
    type(IO_) :: f

    if(present(restart) )then
        call execute_command_line("mkdir -p "//trim(path)//"/Material")
        call f%open(trim(path)//"/Material/","Material",".prop")
        call obj%Mesh%export(path=trim(path)//"/Material",restart=.true.)
        write(f%fh,*) obj%meshPara(:,:)
        write(f%fh,*) obj%x_max
        write(f%fh,*) obj%x_min
        write(f%fh,*) obj%y_max
        write(f%fh,*) obj%y_min
        write(f%fh,*) obj%z_max
        write(f%fh,*) obj%z_min
        write(f%fh,*) obj%t_max
        write(f%fh,*) obj%t_min
        write(f%fh,*) obj%Mcount
        write(f%fh,*) obj%layer
        write(f%fh, '(A)' ) trim(obj%Name)
        write(f%fh,*) obj%MatPara(:,:)
        write(f%fh,*) obj%NumOfMatPara
        write(f%fh,*) obj%NumOfMaterial    
        write(f%fh, '(A)') trim(obj%MaterialType)
        write(f%fh, '(A)') trim(obj%ErrorMsg)
        call f%close()
    endif

end subroutine
! ###########################################################################


! ###########################################################################
subroutine showMaterialProp(obj)
    class(MaterialProp_),intent(inout) :: obj
    integer(int32) :: i,j,n

    n=size(obj%Mesh%ElemNod,1)

    print *, trim(obj%Name)
    do i=1,n
        if(i==n)then
            print *, "  L _ Zone #",i,"Parameters : ",obj%meshPara(i,:)
        else
            print *, "  | - Zone #",i,"Parameters : ",obj%meshPara(i,:)
        endif
    enddo

end subroutine showMaterialProp
! ###########################################################################

! ###########################################################################
subroutine setMaterialProp(obj,x_max,x_min,y_max,y_min,z_max,z_min,t_max,t_min,ParaValue,Layer)
    class(MaterialProp_),intent(inout) :: obj
    real(real64),optional,intent(in) :: x_max,x_min,y_max,y_min,z_max,z_min,t_max,t_min
    real(real64),optional,intent(in) :: ParaValue
    integer(int32) :: i,j,n,m,valsize
    integer(int32),optional,intent(in) :: Layer
    
    obj%Layer=input(default=1, option=Layer)
    valsize=1
    if(.not. allocated(obj%mesh%NodCoord) )then
        allocate(obj%mesh%NodCoord(8,3))
        allocate(obj%mesh%ElemNod(1,8))
        allocate(obj%meshPara(1,valsize))
        obj%Mcount=1
    endif
    obj%x_max=input(default=10000000.0d0,option=x_max)
    obj%x_min=input(default=-10000000.0d0 ,option=x_min)
    obj%y_max=input(default=10000000.0d0,option=y_max)
    obj%y_min=input(default=-10000000.0d0 ,option=y_min)
    obj%z_max=input(default=10000000.0d0,option=z_max)
    obj%z_min=input(default=-10000000.0d0 ,option=z_min)
    obj%t_max=input(default=10000000.0d0,option=t_max)
    obj%t_min=input(default=0.0d0 ,option=t_min)

    if(obj%Mcount==1 )then
        obj%mesh%NodCoord(1,1) = obj%x_min
        obj%mesh%NodCoord(1,2) = obj%y_min
        obj%mesh%NodCoord(1,3) = obj%z_min

        obj%mesh%NodCoord(2,1) = obj%x_max
        obj%mesh%NodCoord(2,2) = obj%y_min
        obj%mesh%NodCoord(2,3) = obj%z_min

        obj%mesh%NodCoord(3,1) = obj%x_max
        obj%mesh%NodCoord(3,2) = obj%y_max
        obj%mesh%NodCoord(3,3) = obj%z_min

        obj%mesh%NodCoord(4,1) = obj%x_min
        obj%mesh%NodCoord(4,2) = obj%y_max
        obj%mesh%NodCoord(4,3) = obj%z_min

        obj%mesh%NodCoord(5,1) = obj%x_min
        obj%mesh%NodCoord(5,2) = obj%y_min
        obj%mesh%NodCoord(5,3) = obj%z_max

        obj%mesh%NodCoord(6,1) = obj%x_max
        obj%mesh%NodCoord(6,2) = obj%y_min
        obj%mesh%NodCoord(6,3) = obj%z_max

        obj%mesh%NodCoord(7,1) = obj%x_max
        obj%mesh%NodCoord(7,2) = obj%y_max
        obj%mesh%NodCoord(7,3) = obj%z_max

        obj%mesh%NodCoord(8,1) = obj%x_min
        obj%mesh%NodCoord(8,2) = obj%y_max
        obj%mesh%NodCoord(8,3) = obj%z_max


        do i=1,8
            obj%mesh%ElemNod(1,i)=i
        enddo
        obj%meshPara(1,1)=input(default=0.0d0,option=ParaValue)
        !if(present(Values) )then
        !    obj%meshPara(1,:)=values
        !endif
        obj%Mcount=obj%Mcount+1
    else
        n=size(obj%mesh%ElemNod,1)
        do i=1,8
            call extendArray(mat=obj%mesh%NodCoord,extend1stColumn=.true.)
        enddo
        call extendArray(mat=obj%meshPara,extend1stColumn=.true.)
        call extendArray(mat=obj%mesh%ElemNod,extend1stColumn=.true.)
        obj%Mcount=obj%Mcount+1
        obj%mesh%NodCoord( n*8 + 1,1) = obj%x_min
        obj%mesh%NodCoord( n*8 + 1,2) = obj%y_min
        obj%mesh%NodCoord( n*8 + 1,3) = obj%z_min
        
        obj%mesh%NodCoord( n*8 + 2,1) = obj%x_max
        obj%mesh%NodCoord( n*8 + 2,2) = obj%y_min
        obj%mesh%NodCoord( n*8 + 2,3) = obj%z_min

        obj%mesh%NodCoord( n*8 + 3,1) = obj%x_max
        obj%mesh%NodCoord( n*8 + 3,2) = obj%y_max
        obj%mesh%NodCoord( n*8 + 3,3) = obj%z_min

        obj%mesh%NodCoord( n*8 + 4,1) = obj%x_min
        obj%mesh%NodCoord( n*8 + 4,2) = obj%y_max
        obj%mesh%NodCoord( n*8 + 4,3) = obj%z_min

        obj%mesh%NodCoord( n*8 + 5,1) = obj%x_min
        obj%mesh%NodCoord( n*8 + 5,2) = obj%y_min
        obj%mesh%NodCoord( n*8 + 5,3) = obj%z_max

        obj%mesh%NodCoord( n*8 + 6,1) = obj%x_max
        obj%mesh%NodCoord( n*8 + 6,2) = obj%y_min
        obj%mesh%NodCoord( n*8 + 6,3) = obj%z_max

        obj%mesh%NodCoord( n*8 + 7,1) = obj%x_max
        obj%mesh%NodCoord( n*8 + 7,2) = obj%y_max
        obj%mesh%NodCoord( n*8 + 7,3) = obj%z_max

        obj%mesh%NodCoord( n*8 + 8,1) = obj%x_min
        obj%mesh%NodCoord( n*8 + 8,2) = obj%y_max
        obj%mesh%NodCoord( n*8 + 8,3) = obj%z_max
        
        obj%meshPara(1+n,1)=input(default=0.0d0,option=ParaValue)
        do i=1,8
            obj%mesh%ElemNod(1+n,i)=i+n*8
        enddo
        !if(present(Values) )then
        !    obj%meshPara(1+n,:)=values
        !endif


    endif
    
end subroutine setMaterialProp
! ###########################################################################



!###############################################
subroutine gmshMaterialProp(obj, Name, Tag)
    class(MaterialProp_),intent(inout) :: obj
    character(*),optional,intent(in) :: Name,Tag
    real(real64),allocatable :: ElemValue(:,:)
    integer(int32) :: i


    if( obj%Mesh%empty() .eqv. .true. )then
        print *, "ERROR gmshMaterialProp :: No Material. is installed. "
        return
    endif
    allocate(ElemValue(size(obj%MeshPara,1),1 ))
    do i=1,size(obj%MeshPara,2)
        ElemValue(:,1)=obj%MeshPara(:,i)
        if(present(tag) )then
            call obj%Mesh%gmsh(Name=Name//"Material",ElemValue=ElemValue,&
                OptionalContorName=trim(Tag))
        else
            call obj%Mesh%gmsh(Name=Name//"Material",ElemValue=ElemValue,&
                OptionalContorName="Material Value :: ID = "//trim(adjustl(fstring(i))))
        endif
    enddo
    deallocate(ElemValue)
        

end subroutine gmshMaterialProp
!###############################################


!##################################################
subroutine DeallocateMaterialProp(obj)
    class(MaterialProp_),intent(inout)::obj

    if(allocated(obj%MatPara) )then
        deallocate(obj%MatPara)
    endif
    obj%ErrorMsg = "All objectes in MaterialPropClass are deallocated."

end subroutine DeallocateMaterialProp
!##################################################




!##################################################
subroutine initializeMaterial(obj,MaterialParameters)
    class(MaterialProp_),intent(inout)::obj
    real(real64),allocatable,optional,intent(inout) :: MaterialParameters(:,:)
    if(.not.allocated(obj%MatPara))then
        obj%ErrorMsg="ERROR :: MaterialPropClass%Initialize >>.not.allocated(MatPara)"
        print *,"ERROR :: MaterialPropClass%Initialize >>.not.allocated(MatPara)"
    endif
    if(present(MaterialParameters) )then
        if(.not.allocated(MaterialParameters) )then
            print *, "ERROR :: initializeMaterial >> MaterialParameters(:,:) not allocated."
            return
        else
            if(allocated(obj%MatPara) )then
                deallocate(obj%MatPara)
            endif
            obj%NumOfMatPara = size(MaterialParameters,1)
            obj%NumOfMaterial = size(MaterialParameters,2)
            allocate( obj%MatPara(obj%NumOfMatPara,obj%NumOfMaterial  ) )
            obj%MatPara(:,:) = MaterialParameters(:,:)
        endif
        return
    endif

    if(.not.allocated(obj%MatPara) )then
        print *, "ERROR :: initializeMaterial >> please import obj%MatPara"
    endif
    obj%NumOfMatPara  = size(obj%MatPara,1)
    obj%NumOfMaterial = size(obj%MatPara,2)
end subroutine initializeMaterial
!##################################################



!##################################################
subroutine ImportMatPara(obj,mat_para)
    class(MaterialProp_),intent(inout)::obj
    real(real64),intent(in)::mat_para(:,:)
    
    if(allocated(obj%MatPara) )then
        deallocate(obj%MatPara)
    endif
    allocate(obj%MatPara(size(mat_para,1),size(mat_para,2) ) )
    obj%MatPara(:,:)=mat_para(:,:)

    obj%NumOfMatPara=size(mat_para,1)
    obj%NumOfMaterial=size(mat_para,2)

end subroutine ImportMatPara
!##################################################


!##################################################
subroutine MergeMaterialProp(inobj1,inobj2,outobj)
    class(MaterialProp_),intent(in)::inobj1,inobj2
    class(MaterialProp_),intent(out)::outobj
    integer num1,num2,num3,i


    ! ========= Merge nodes  ============
    num1=size(inobj1%MatPara,1)
    num2=size(inobj2%MatPara,1)
    num3=size(inobj2%MatPara,2)
    if(num3 /= size(inobj1%MatPara,1) )then
        outobj%ErrorMsg="MergeMaterialProp >> num3 /= inobj1%MatPara,1"
    endif
    allocate(outobj%MatPara(num1+num2, num3))
    do i=1,num1
        outobj%MatPara(i,:)=inobj1%MatPara(i,:)
    enddo
    do i=1,num2
        outobj%MatPara(i+num1,:)=inobj2%MatPara(i,:)
    enddo
    outobj%NumOfMatPara=inobj1%NumOfMatPara
    outobj%NumOfMaterial=inobj1%NumOfMaterial+inobj1%NumOfMaterial
    ! ========= Merge nodes  ============
    
    
end subroutine MergeMaterialProp
!##################################################



!##################################################
subroutine ShowMatPara(obj)
    class(MaterialProp_),intent(in)::obj

    integer i

    do i=1,size(obj%MatPara,1)
        print *, "obj%MatPara : ",obj%MatPara(i,:)
    enddo

end subroutine ShowMatPara
!##################################################

!##################################################
subroutine getValuesMaterialProp(obj,mesh,Values)
    class(MaterialProp_),intent(in):: obj
    type(Mesh_),intent(in) :: mesh
    type(Rectangle_) ::rect,mrect
    real(real64),allocatable,intent(inout) :: Values(:)
    integer(int32) :: i,j,k,l,n,dim_num,elem_num

    n=size(mesh%NodCoord,1)
    dim_num=size(mesh%NodCoord,2)
    elem_num=size(mesh%ElemNod,1)
    if(.not. allocated(Values) )then
        allocate(Values(elem_num) )
    elseif(size(Values) /= elem_num)then
        print *, "ERROR :: getValuesMaterialProp >> size(Values) /= elem_num"
        print *, size(Values),elem_num
        deallocate(Values)
        allocate(Values(elem_num) )
        Values(:)=0.0d0
        print *, size(Values),elem_num
    endif
    

    allocate(rect%NodCoord(size(obj%Mesh%ElemNod,2),size(obj%Mesh%NodCoord,2)) )
	allocate(mrect%NodCoord(size(obj%Mesh%ElemNod,2),size(obj%Mesh%NodCoord,2)) )
		
    do i=1,size(Mesh%ElemNod,1)
        do j=1,size(Mesh%ElemNod,2)
            rect%NodCoord(j,:)=Mesh%NodCoord(Mesh%ElemNod(i,j),:)
        enddo
        ! for all materials, check material parameters
		! for each zones, check in-out
        ! import nodal coordinate
        do k=1,size(obj%Mesh%ElemNod,1)
		    do l=1,size(obj%Mesh%ElemNod,2)
		    	n=obj%Mesh%ElemNod(k,l)
		    	mrect%NodCoord(l,:)=obj%Mesh%NodCoord(n,:)
		    enddo
		    ! check in-out
		    if(rect%contact(mrect) .eqv. .true. )then
		    	! in
		    	Values(i)=obj%meshPara(k,1)
		    else
		    	cycle
            endif
        enddo
    enddo

end subroutine getValuesMaterialProp
!##################################################
end module MaterialPropClass