G
YouTube TikTok Games
Skip to content
szaghiPublic

About

Vector algebra class for Fortran poor people

Topics

Resources

Contributing

Stars

29 stars

Watchers

5 watching

Forks

Repository files navigation

VecFor

Vector algebra for Fortran

GitHub tag GitHub issues CI coverage License

One vector type for three-dimensional Cartesian space, in pure Fortran 2008, written as you write the maths: a + b, 2 * a, a .dot. b, a .cross. b. Lengths, angles, face normals, distances, projections, rotations and mirrors, in single, double or quadruple precision, on whole arrays at once, and inside an OpenACC kernel.

a tetrahedron with its outward unit normals, a point q outside it and its foot on the slanted face

The tetrahedron of the tutorial: outward face normals, a point and its foot on a face. Every figure of the docs is computed by VecFor and drawn by foresight.

โž• The maths, as you write it
a + b, -a, 2 * a, a / 4, a .dot. b, a .cross. b, a .paral. n, a .ortho. n, R .matrix. a: numbers of any integer or real kind on either side, converted for you. Arithmetic
๐Ÿ“ Lengths, angles, directions
normL2, sq_norm, a unit vector in place or as a copy, a unit vector checked for a degenerate length, the angle between two vectors computed with atan2: accurate near 0 and 180 degrees; cross and dot products accurate when their terms cancel. Lengths and angles
๐Ÿ”บ Faces of a mesh
The normal of a triangle or a quadrilateral, as long as the face is large or of unit length: areas, outward normals, the volume of a body by the divergence theorem; the area of a triangle, the signed volume of a tetrahedron, the vector area of a polygon. Faces, area, volume
๐Ÿ“ Points, lines, planes
The distance from a line, the signed distance from a plane, the foot of a point on it, collinear and concyclic points with a tolerance; barycentric coordinates in a triangle or a tetrahedron, the closest point of a triangle. A point and the body
๐Ÿ”„ Rotations and mirrors
A rotation about any axis, a reflection across any plane, as a call or as a matrix computed once and applied to many vectors. Rotations and mirrors
๐Ÿงฎ Whole arrays at once
The operators and the functions are elemental: one call computes the normals of every face, or the distances of a million points. Many vectors at once
๐ŸŽš๏ธ Single, double, quadruple
vector_R4P, vector_R8P, vector_R16P, each with its versors and functions, from one use vecfor; true quadruple precision by default with gfortran and ifx (-DPENF_R16P). Precision
๐Ÿš€ On the GPU
A device-callable API for OpenACC kernels, the _dev routines: the vector operators, the rotation and mirror matrices, and the geometry (lengths, distances, face normals, measures, point location). On the GPU
๐Ÿ› ๏ธ Standard Fortran, small
Fortran 2008, one module to use, one small dependency (PENF, portable kinds) fetched by fobis fetch; built with FoBiS or Make. Installation
๐Ÿ”“ Multi-licensed
GPL v3 for FOSS projects; BSD 2-Clause, BSD 3-Clause or MIT for closed source and commercial ones: pick the license that fits. Copyrights

Full documentation ยท Gallery ยท Tutorial ยท Cookbook ยท API reference

Quick start

A triangle in space, its normal and area, an angle, a point above it, its distance and its foot. This is a whole program:

program quickstart
!< Quick start: a triangle in space, its normal and area, a point above it, its distance and its foot.
use penf, only : R8P
use vecfor, only : angle, ex, ey, ez, face_normal3, vector
implicit none
type(vector) :: a, b, c ! the corners of a triangle
type(vector) :: n       ! its normal
type(vector) :: q       ! a point
type(vector) :: foot    ! its projection onto the plane of the triangle

a = ex
b = ey
c = ez
n = face_normal3(pt1=a, pt2=b, pt3=c)                 ! as long as the triangle is large
call n%printf(prefix='normal   = ')
print '(A,F7.4)', 'area     = ', n%normL2()
print '(A,F7.4)', 'angle    = ', angle(b - a, c - a) * 180 / acos(-1._R8P)
q = 0.8_R8P * ex + 0.6_R8P * ey + 0.8_R8P * ez
print '(A,F7.4)', 'distance = ', q%distance_to_plane(pt1=a, pt2=b, pt3=c)
foot = q%projection_onto_plane(pt1=a, pt2=b, pt3=c)
print '(A,3F7.4)', 'foot     = ', foot%x, foot%y, foot%z
endprogram quickstart
$ quickstart
normal   = +0.5, +0.5, +0.5
area     =  0.8660
angle    = 60.0000
distance =  0.6928
foot     =  0.4000 0.2000 0.4000

Grows with your program

The same calls work on whole arrays. From the tutorial: the four unit normals of a tetrahedron in one call, then the volume estimated by testing 64000 grid points against its faces, one call per face:

normal = face_normal3(pt1=p(face(1,:)), pt2=p(face(2,:)), pt3=p(face(3,:)), norm='y')   ! four faces, one call
print '(A,4F8.4)', 'x of the normals ', normal%x
print '(A,4F8.4)', 'their lengths    ', normL2(normal)
allocate(inside(size(g)), source=.true.)
do f = 1, 4
   dist = g%distance_to_plane(pt1=p(face(1,f)), pt2=p(face(2,f)), pt3=p(face(3,f)))   ! every point, one call
   inside = inside .and. dist <= 0._R8P
enddo
print '(A,I0,A,I0)', 'points inside    ', count(inside), ' of ', size(g)
print '(A,F8.4,A,F8.4)', 'volume estimate  ', count(inside) / real(size(g), R8P), ', exact', 1._R8P / 6
$ probe
x of the normals   0.0000  0.0000 -1.0000  0.5774
their lengths      1.0000  1.0000  1.0000  1.0000
points inside    10660 of 64000
volume estimate    0.1666, exact  0.1667

the points of a grid that lie inside a tetrahedron

New to VecFor? The tutorial grows one program around a tetrahedron, chapter by chapter; the cookbook has a short recipe for each task. Every example is a compiled, runnable program in docs/examples/src, shown with its real output in the documentation.

Install

FoBiS

Clone, fetch PENF, and build:

git clone https://github.com/szaghi/VecFor && cd VecFor
fobis fetch                           # PENF into src/third_party
fobis build --mode static-gnu         # static/libvecfor.a, modules in static/mod

The archive contains PENF too: link a program with

gfortran -I static/mod my_program.f90 static/libvecfor.a -o my_program

As a dependency of a FoBiS project, add VecFor to the [dependencies] of your fobos and run fobis fetch.

fpm

fpm build --profile release           # or, in your fpm.toml: VecFor = { git = "https://github.com/szaghi/VecFor" }

If your project declares PENF too, give it preprocess.cpp.macros = ["PENF_R16P"] (see Installation).

Install script or Make

Each release has an install.sh that downloads and builds it:

wget https://github.com/szaghi/VecFor/releases/latest/download/install.sh
bash install.sh --download wget --build fobis     # or --build make, --build fpm

With PENF fetched, the makefile builds static/vecfor.a with gfortran: make.

VecFor is tested on every push with gfortran; its FoBiS modes also build it with the Intel compiler and NVIDIA nvfortran (see Installation).

Authors

Contributions are welcome โ€” see the Contributing page.

Copyrights

This project is distributed under a multi-licensing system:

Anyone interested in using, developing, or contributing to this project is welcome โ€” pick the license that best fits your needs.

About

Vector algebra class for Fortran poor people

Topics

Resources

Contributing

Stars

29 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages