PhysicalFieldClass.f90 Source File


Contents


Source Code

module PhysicalFieldClass
    use ArrayClass
    use IOClass
    use LinearSolverClass
    implicit none


    type :: PhysicalField_
        character(len=:),allocatable,public:: name
        real(real64),allocatable ,public:: scalar(:)
        real(real64),allocatable ,public:: vector(:,:)
        real(real64),allocatable ,public:: tensor(:,:,:)
        integer(int32) :: attribute=0 ! node=1, element=2, gausspoint=3
        integer(int32) :: datastyle=0 !scalar=1, vector=2, tensor=3
    contains

        procedure,pass :: importPhysicalFieldScalar
        procedure,pass :: importPhysicalFieldVector
        procedure,pass :: importPhysicalFieldTensor
        generic,public :: import => importPhysicalFieldScalar,&
            importPhysicalFieldVector,&
            importPhysicalFieldTensor
        procedure :: clear => clearPhysicalField
        procedure :: init => clearPhysicalField
        procedure :: remove => clearPhysicalField
        procedure :: msh => mshPhysicalField

    end type
contains

subroutine importPhysicalFieldScalar(obj,scalar,name)
    class(PhysicalField_),intent(inout) :: obj
    real(real64),intent(in) :: scalar(:)
    character(*),intent(in) :: name

    obj % name   = "untitled"
    obj % scalar = scalar
    obj % name   = name

end subroutine

subroutine importPhysicalFieldVector(obj,vector,name)
    class(PhysicalField_),intent(inout) :: obj
    real(real64),intent(in) :: vector(:,:)
    character(*),intent(in) :: name

    obj % name   = "untitled"
    obj % vector = vector
    obj % name   = name
    
end subroutine


subroutine importPhysicalFieldtensor(obj,tensor,name)
    class(PhysicalField_),intent(inout) :: obj
    real(real64),intent(in) :: tensor(:,:,:)
    character(*),intent(in) :: name

    obj % name   = "untitled"
    obj % tensor = tensor
    obj % name   = name
    
end subroutine


subroutine clearPhysicalField(obj)
    class(PhysicalField_),intent(inout) :: obj

    if(allocated(obj%scalar) )then
        deallocate(obj%scalar)
    endif
    if(allocated(obj%vector) )then
        deallocate(obj%vector)
    endif
    if(allocated(obj%tensor) )then
        deallocate(obj%tensor)
    endif
    obj%name = "untitled"
end subroutine
! ########################################################

! ########################################################
! export physical field by gmsh (.msh)
subroutine mshPhysicalField(obj,name,caption)
    class(PhysicalField_),intent(inout) :: obj
    character(*),intent(in) :: name
    character(*),optional,intent(in) ::caption
    character(200) :: cap
    integer(int32) :: nb_scalar_points,nb_vector_points,nb_tensor_points,i,j
    real(real64),allocatable :: tensor(:,:), eigenVector(:,:)
    type(IO_) :: f
    ! doc: http://gmsh.info/doc/texinfo/gmsh.html#MSH-file-format-version-2-_0028Legacy_0029
    if(present(caption) ) then
        cap=trim(caption)
    else
        cap="untitled"
    endif
    if(.not.allocated(obj%scalar) )then
        nb_scalar_points = 0
    else
        nb_scalar_points =size(obj%scalar,1)
    endif
    if(.not.allocated(obj%vector) )then
        nb_vector_points = 0
    else
        nb_vector_points =size(obj%vector,1)
    endif
    
    if(.not.allocated(obj%tensor) )then
        nb_tensor_points = 0
    else
        nb_tensor_points =size(obj%tensor,1)
    endif
    
    ! まずはスカラー
    if(nb_scalar_points/=0 .and. obj%attribute==1)then
        call f%open(trim(name)//"_node_scalar.msh" )
        write(f%fh,'(a)' ) "$MeshFormat"
        write(f%fh,'(a)' ) "2.2 0 8"
        write(f%fh,'(a)' ) "$EndMeshFormat"
        write(f%fh,'(a)' ) "$NodeData"
        write(f%fh,'(a)' ) "1" ! one string tag
        write(f%fh,'(a)' ) trim(cap) ! the name of the view
        write(f%fh,'(a)' ) "1" ! one real tag
        write(f%fh,'(a)' ) "0.0" ! time value
        write(f%fh,'(a)' ) "3"   ! three integer tag
        write(f%fh,'(a)' ) "0"   ! the timestep (starts from 0)
        write(f%fh,'(a)' ) "1"! 1-component (scalar) field
        write(f%fh,'(a)' ) trim(str(size(obj%scalar,1) ) )
        do i=1,size(obj%scalar,1)
            write(f%fh,'(a)' ) trim(str(i))//" "//trim(str(obj%scalar(i)))
        enddo
        write(f%fh,'(a)' ) "$EndNodeData"
        call f%close()
    endif
    ! 次にベクトル
    if(nb_vector_points/=0 .and. obj%attribute==1)then
        call f%open(trim(name)//"_node_vector.msh" )
        write(f%fh,'(a)' ) "$MeshFormat"
        write(f%fh,'(a)' ) "2.2 0 8"
        write(f%fh,'(a)' ) "$EndMeshFormat"
        write(f%fh,'(a)' ) "$NodeData"
        write(f%fh,'(a)' ) "1" ! one string tag
        write(f%fh,'(a)' ) trim(cap) ! the name of the view
        write(f%fh,'(a)' ) "1" ! one real tag
        write(f%fh,'(a)' ) "0.0" ! time value
        write(f%fh,'(a)' ) "3"   ! three integer tag
        write(f%fh,'(a)' ) "0"   ! the timestep (starts from 0)
        write(f%fh,'(a)' ) trim(str(size(obj%vector,2)))! n-component (vector) field
        write(f%fh,'(a)' ) trim(str(size(obj%vector,1) ) )
        do i=1,size(obj%vector,1)
            write(f%fh,'(a)',advance="no" ) trim(str(i))//" "
            do j=1,size(obj%vector,2)-1
                write(f%fh,'(a)',advance="no" ) trim(str(obj%vector(i,j)))//" "
            enddo
            j=size(obj%vector,2)
            write(f%fh,'(a)',advance="yes" ) trim(str(obj%vector(i,j)))
        enddo
        write(f%fh,'(a)' ) "$EndNodeData"
        call f%close()
    endif

    ! for element-data

    if(nb_scalar_points/=0 .and. obj%attribute==2)then
        call f%open(trim(name)//"_elem_scalar.msh" )
        write(f%fh,'(a)' ) "$MeshFormat"
        write(f%fh,'(a)' ) "2.2 0 8"
        write(f%fh,'(a)' ) "$EndMeshFormat"
        write(f%fh,'(a)' ) "$ElementData"
        write(f%fh,'(a)' ) "1" ! one string tag
        write(f%fh,'(a)' ) trim(cap) ! the name of the view
        write(f%fh,'(a)' ) "1" ! one real tag
        write(f%fh,'(a)' ) "0.0" ! time value
        write(f%fh,'(a)' ) "3"   ! three integer tag
        write(f%fh,'(a)' ) "0"   ! the timestep (starts from 0)
        write(f%fh,'(a)' ) "1"! 1-component (scalar) field
        write(f%fh,'(a)' ) trim(str(size(obj%scalar,1) ) )
        do i=1,size(obj%scalar,1)
            write(f%fh,'(a)' ) trim(str(i))//" "//trim(str(obj%scalar(i)))
        enddo
        write(f%fh,'(a)' ) "$EndElementData"
        call f%close()
    endif
    ! 次にベクトル
    if(nb_vector_points/=0 .and. obj%attribute==2)then
        call f%open(trim(name)//"_elem_vector.msh" )
        write(f%fh,'(a)' ) "$MeshFormat"
        write(f%fh,'(a)' ) "2.2 0 8"
        write(f%fh,'(a)' ) "$EndMeshFormat"
        write(f%fh,'(a)' ) "$ElementData"
        write(f%fh,'(a)' ) "1" ! one string tag
        write(f%fh,'(a)' ) trim(cap) ! the name of the view
        write(f%fh,'(a)' ) "1" ! one real tag
        write(f%fh,'(a)' ) "0.0" ! time value
        write(f%fh,'(a)' ) "3"   ! three integer tag
        write(f%fh,'(a)' ) "0"   ! the timestep (starts from 0)
        write(f%fh,'(a)' ) trim(str(size(obj%vector,2)))! n-component (vector) field
        write(f%fh,'(a)' ) trim(str(size(obj%vector,1) ) )
        do i=1,size(obj%vector,1)
            write(f%fh,'(a)',advance="no" ) trim(str(i))//" "
            do j=1,size(obj%vector,2)-1
                write(f%fh,'(a)',advance="no" ) trim(str(obj%vector(i,j)))//" "
            enddo
            j=size(obj%vector,2)
            write(f%fh,'(a)',advance="yes" ) trim(str(obj%vector(i,j)))
        enddo
        write(f%fh,'(a)' ) "$EndElementData"
        call f%close()
    endif

    ! テンソルの場合は実装中;
    if(nb_tensor_points/=0 .and. obj%attribute==3)then
        ! テンソルかつガウス点に定義(応力テンソルなど)
        ! 方針 >> 平均化して要素ごとに1つの主応力ベクトル図をかく
        i = size(obj%tensor,2)
        j = size(obj%tensor,3)
        if(i/=j)then
            print *, "mshFEMDomain >> ERROR >> size(obj%tensor,3)/=size(obj%tensor,2)"
            return
        endif
        allocate(tensor(i,j) )
        if(i==2)then
            call eigen_2d(tensor,eigenVector)
        elseif(i==3)then
            allocate(eigenVector(3,3))
            eigenVector(:,:) = eigen_3d(tensor)
        else
            print *, "ERROR :: mshPhysicalField for more dimension than 4-D>> not implemented yet."
            stop
        endif
    endif

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

end module