example_volume_1.f90 Source File


This file depends on

sourcefile~~example_volume_1.f90~~EfferentGraph sourcefile~example_volume_1.f90 example_volume_1.f90 sourcefile~forcad.f90 forcad.f90 sourcefile~example_volume_1.f90->sourcefile~forcad.f90 sourcefile~forcad_nurbs_curve.f90 forcad_nurbs_curve.f90 sourcefile~forcad.f90->sourcefile~forcad_nurbs_curve.f90 sourcefile~forcad_nurbs_surface.f90 forcad_nurbs_surface.f90 sourcefile~forcad.f90->sourcefile~forcad_nurbs_surface.f90 sourcefile~forcad_nurbs_volume.f90 forcad_nurbs_volume.f90 sourcefile~forcad.f90->sourcefile~forcad_nurbs_volume.f90 sourcefile~forcad_utils.f90 forcad_utils.f90 sourcefile~forcad.f90->sourcefile~forcad_utils.f90 sourcefile~forcad_nurbs_curve.f90->sourcefile~forcad_utils.f90 sourcefile~forcad_nurbs_surface.f90->sourcefile~forcad_utils.f90 sourcefile~forcad_nurbs_volume.f90->sourcefile~forcad_utils.f90

Source Code

!> This program demonstrates the usage of a NURBS (Non-Uniform Rational B-Spline) volume object to create  and finalize a NURBS volume.
!> It sets up control points, weights, and knot vectors for all three dimensions, generates the volume, and exports the control points and the volume to VTK files.

program example3_volume

    use forcad, only: rk, nurbs_volume

    implicit none
    type(nurbs_volume) :: nurbs              !! Declare a NURBS volume object
    real(rk), allocatable :: Xc(:,:), Wc(:)  !! Arrays for control points and weights
    real(rk) :: knot1(4), knot2(4), knot3(4) !! Arrays for knot vectors in all three dimensions

    !-----------------------------------------------------------------------------
    ! Setting up the NURBS volume
    !-----------------------------------------------------------------------------

    !> Define the control points for the NURBS volume
    Xc = generate_Xc(5.0_rk)

    !> Define weights for the control points (optional)
    allocate(Wc(size(Xc,1)), source=1.0_rk)
    Wc(2) = 5.0_rk

    !> Define knot vectors for all three dimensions
    knot1 = [0.0_rk, 0.0_rk, 1.0_rk, 1.0_rk]
    knot2 = [0.0_rk, 0.0_rk, 1.0_rk, 1.0_rk]
    knot3 = [0.0_rk, 0.0_rk, 1.0_rk, 1.0_rk]

    !> Set knot vectors, control points, and weights for the NURBS volume object
    !> Wc is optional.
    call nurbs%set(knot1, knot2, knot3, Xc, Wc)

    !> Deallocate local arrays
    deallocate(Xc, Wc)

    !> Export the control points to a VTK file
    call nurbs%export_Xc('vtk/nurbs_volume_Xc.vtk')

    !-----------------------------------------------------------------------------
    ! Creating the NURBS volume
    !-----------------------------------------------------------------------------

    !> Generate the NURBS volume with resolutions of 20, 20, and 20 in the three dimensions
    call nurbs%create(20, 20, 20)

    !> Export the generated volume to a VTK file
    call nurbs%export_Xg('vtk/nurbs_volume_Xg.vtk')

    !-----------------------------------------------------------------------------
    ! Visualization using PyVista
    ! Note: PyVista is required for visualization. Install it using `pip install pyvista`
    !-----------------------------------------------------------------------------

    !> Show the control geometry and geometry using PyVista
    call nurbs%show('vtk/nurbs_volume_Xc.vtk','vtk/nurbs_volume_Xg.vtk')

    !-----------------------------------------------------------------------------
    ! Refinements
    !-----------------------------------------------------------------------------

    !> Print size of knot vectors
    print*, size(nurbs%get_knot(1))
    print*, size(nurbs%get_knot(2))
    print*, size(nurbs%get_knot(3))

    !> Insert knots 0.25 and 0.75 in all three directions
    call nurbs%insert_knots(1, [0.25_rk, 0.75_rk], [1,1]) ! direction 1
    call nurbs%insert_knots(2, [0.25_rk, 0.75_rk], [1,1]) ! direction 2
    call nurbs%insert_knots(3, [0.25_rk, 0.75_rk], [1,1]) ! direction 3

    !> Print size of knot vectors after inserting knots
    print*, size(nurbs%get_knot(1))
    print*, size(nurbs%get_knot(2))
    print*, size(nurbs%get_knot(3))

    !> Print degrees
    print*, nurbs%get_degree()

    !> Elevate degree by 2 in all three directions
    call nurbs%elevate_degree(1, 2) ! direction 1
    call nurbs%elevate_degree(2, 2) ! direction 2
    call nurbs%elevate_degree(3, 2) ! direction 3

    !> Print degrees after elevating
    print*, nurbs%get_degree()

    !> Print size of knot vectors
    print*, size(nurbs%get_knot(1))
    print*, size(nurbs%get_knot(2))
    print*, size(nurbs%get_knot(3))

    call nurbs%remove_knots(1, [0.25_rk, 0.75_rk], [1,1]) ! direction 1
    call nurbs%remove_knots(2, [0.25_rk, 0.75_rk], [1,1]) ! direction 2
    call nurbs%remove_knots(3, [0.25_rk, 0.75_rk], [1,1]) ! direction 3

    !> Print size of knot vectors after removing knots
    print*, size(nurbs%get_knot(1))
    print*, size(nurbs%get_knot(2))
    print*, size(nurbs%get_knot(3))

    !> Generate the refined NURBS volume with resolutions of 40, 40, and 40 in the three dimensions
    call nurbs%create()

    !> Export updated control points to a VTK file
    call nurbs%export_Xc('vtk/nurbs_volume_Xc2.vtk')

    !> Export the refined generated volume to a VTK file
    call nurbs%export_Xg('vtk/nurbs_volume_Xg2.vtk')

    !-----------------------------------------------------------------------------
    ! Visualization using PyVista
    ! Note: PyVista is required for visualization. Install it using `pip install pyvista`
    !-----------------------------------------------------------------------------

    !> Show the control geometry and geometry using PyVista
    call nurbs%show('vtk/nurbs_volume_Xc2.vtk','vtk/nurbs_volume_Xg2.vtk')

    !-----------------------------------------------------------------------------
    ! Transformations
    !-----------------------------------------------------------------------------

    !> Rotate the control points
    call nurbs%rotate_Xc(alpha=-45.0_rk, beta=0.0_rk, theta=90.0_rk)

    !> Rotate the generated curve
    call nurbs%rotate_Xg(alpha=-45.0_rk, beta=0.0_rk, theta=90.0_rk)

    !> Translate the control points
    call nurbs%translate_Xc([1.0_rk, 2.0_rk, -3.0_rk])

    !> Translate the generated curve
    call nurbs%translate_Xg([1.0_rk, 2.0_rk, -3.0_rk])

    !> Export the transformed control points to a VTK file
    call nurbs%export_Xc('vtk/nurbs_volume_Xc3.vtk')

    !> Export the transformed generated volume to a VTK file
    call nurbs%export_Xg('vtk/nurbs_volume_Xg3.vtk')

    !-----------------------------------------------------------------------------
    ! Visualization using PyVista
    ! Note: PyVista is required for visualization. Install it using `pip install pyvista`
    !-----------------------------------------------------------------------------

    !> Show the control geometry and geometry using PyVista
    call nurbs%show('vtk/nurbs_volume_Xc3.vtk','vtk/nurbs_volume_Xg3.vtk')

    !-----------------------------------------------------------------------------
    ! Extract faces
    !-----------------------------------------------------------------------------

    !> first compute and set the connectivities of volume elements
    call nurbs%set_elem(nurbs%cmp_elem())

    !> get the connectivity of the face1 of the first element
    print*, 'Face 1 of element 1:', nurbs%cmp_elemFace(elem=1, face=1)
    print*, 'Face 2 of element 1:', nurbs%cmp_elemFace(elem=1, face=2)
    print*, 'Face 3 of element 1:', nurbs%cmp_elemFace(elem=1, face=3)
    print*, 'Face 4 of element 1:', nurbs%cmp_elemFace(elem=1, face=4)
    print*, 'Face 5 of element 1:', nurbs%cmp_elemFace(elem=1, face=5)
    print*, 'Face 6 of element 1:', nurbs%cmp_elemFace(elem=1, face=6)

    !> get the degree of the faces
    print*, 'Degree of face 1:', nurbs%cmp_degreeFace(face=1)
    print*, 'Degree of face 2:', nurbs%cmp_degreeFace(face=2)
    print*, 'Degree of face 3:', nurbs%cmp_degreeFace(face=3)
    print*, 'Degree of face 4:', nurbs%cmp_degreeFace(face=4)
    print*, 'Degree of face 5:', nurbs%cmp_degreeFace(face=5)
    print*, 'Degree of face 6:', nurbs%cmp_degreeFace(face=6)
    
    !-----------------------------------------------------------------------------
    ! Finalizing
    !-----------------------------------------------------------------------------

    !> Finalize the NURBS volume object
    call nurbs%finalize()

contains

    !-----------------------------------------------------------------------------
    function generate_Xc(L) result(control_points)
        implicit none
        real(rk), intent(in) :: L
        real(rk), allocatable :: control_points(:,:)
        real(rk) :: L2
        L2 = L / 2.0_rk
        allocate(control_points(8, 3))
        control_points(1,:) = [ L2, -L2,  L2]
        control_points(2,:) = [ L2, -L2, -L2]
        control_points(3,:) = [-L2, -L2,  L2]
        control_points(4,:) = [-L2, -L2, -L2]
        control_points(5,:) = [ L2,  L2,  L2]
        control_points(6,:) = [ L2,  L2, -L2]
        control_points(7,:) = [-L2,  L2,  L2]
        control_points(8,:) = [-L2,  L2, -L2]
    end function
    !-----------------------------------------------------------------------------

end program example3_volume