Giter Club home page Giter Club logo

ovf's Introduction

OVF Parser Library

Simple API for powerful OOMMF Vector Field file parsing

OVF format specification

Build Status

Python package: PyPI version

Library Coverage Python Bindings Coverage
Library Coverage Status Python Bindings Coverage Status

How to use

For usage examples, take a look into the test folders: test, python/test or fortran/test.

Except for opening a file or initializing a segment, all functions return status codes (generally OVF_OK, OVF_INVALID or OVF_ERROR). When the return code is not OVF_OK, you can take a look into the latest message, which should tell you what the problem was (const char * ovf_latest_message(struct ovf_file *) in the C API).

In C/C++ and Fortran, before writing a segment, make sure the ovf_segment you pass in is initialized, i.e. you already called either ovf_read_segment_header or ovf_segment_create.

C/C++

Opening and closing:

  • struct ovf_file *myfile = ovf_open("myfilename.ovf") to open a file
  • myfile->found to check if the file exists on disk
  • myfile->is_ovf to check if the file contains an OVF header
  • myfile->n_segments to check the number of segments the file should contain
  • ovf_close(myfile); to close the file and free resources

Reading from a file:

  • struct ovf_segment *segment = ovf_segment_create() to initialize a new segment and get the pointer
  • ovf_read_segment_header(myfile, index, segment) to read the header into the segment struct
  • create float data array of appropriate size...
  • ovf_read_segment_data_4(myfile, index, segment, data) to read the segment data into your float array
  • setting segment->N before reading allows partial reading of large data segments

Writing and appending to a file:

  • struct ovf_segment *segment = ovf_segment_create() to initialize a new segment and get the pointer
  • segment->n_cells[0] = ... etc to set data dimensions, title and description, etc.
  • ovf_write_segment_4(myfile, segment, data, OVF_FORMAT_TEXT) to write a file containing the segment header and data
  • ovf_append_segment_4(myfile, segment, data, OVF_FORMAT_TEXT) to append the segment header and data to the file

Python

To install the ovf python package, either build and install from source or simply use

pip install ovf

To use ovf from Python, e.g.

from ovf import ovf
import numpy as np

data = np.zeros((2, 2, 1, 3), dtype='f')
data[0,1,0,:] = [3.0, 2.0, 1.0]

with ovf.ovf_file("out.ovf") as ovf_file:

    # Write one segment
    segment = ovf.ovf_segment(n_cells=[2,2,1])
    if ovf_file.write_segment(segment, data) != -1:
        print("write_segment failed: ", ovf_file.get_latest_message())

    # Add a second segment to the same file
    data[0,1,0,:] = [4.0, 5.0, 6.0]
    if ovf_file.append_segment(segment, data) != -1:
        print("append_segment failed: ", ovf_file.get_latest_message())

Fortran

The Fortran bindings are written in object-oriented style for ease of use. Writing a file, for example:

type(ovf_file)      :: file
type(ovf_segment)   :: segment
integer             :: success
real(kind=4), allocatable :: array_4(:,:)
real(kind=8), allocatable :: array_8(:,:)

! Initialize segment
call segment%initialize()

! Write a file
call file%open_file("fortran/test/testfile_f.ovf")
segment%N_Cells = [ 2, 2, 1 ]
segment%N = product(segment%N_Cells)

allocate( array_4(3, segment%N) )
array_4 = 0
array_4(:,1) = [ 6.0, 7.0, 8.0 ]
array_4(:,2) = [ 5.0, 4.0, 3.0 ]

success = file%write_segment(segment, array_4, OVF_FORMAT_TEXT)
if ( success == OVF_OK) then
    write (*,*) "test write_segment succeeded."
    ! write (*,*) "n_cells = ", segment%N_Cells
    ! write (*,*) "n_total = ", segment%N
else
    write (*,*) "test write_segment did not work. Message: ", file%latest_message
    STOP 1
endif

For more information on how to generate modern Fortran bindings, see also https://github.com/MRedies/Interfacing-Fortran

How to embed it into your project

If you are using CMake, it is as simple as cloning this into a subdirectory, e.g. thirdparty/ovf and using it with add_subdirectory:

add_subdirectory( ${PROJECT_SOURCE_DIR}/thirdparty/ovf )
set( OVF_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/thirdparty/ovf/include )
target_include_directories( myproject PRIVATE ${OVF_INCLUDE_DIRS} )
target_link_libraries( myproject PUBLIC ${OVF_LIBRARIES_STATIC} )

If you're not using CMake, you may need to put in some manual work.

Build

On Unix systems

Usually:

mkdir build
cd build
cmake ..
make

On Windows

One possibility:

  • open the folder in the CMake GUI
  • generate the VS project
  • open the resulting project in VS and build it

CMake Options

The following options are ON by default. If you want to switch them off, just pass -D<OPTION>=OFF to CMake, e.g. -DOVF_BUILD_FORTRAN_BINDINGS=OFF.

  • OVF_BUILD_PYTHON_BINDINGS
  • OVF_BUILD_FORTRAN_BINDINGS
  • OVF_BUILD_TEST

On Windows, you can also set these from the CMake GUI.

Create and install the Python package

Instead of pip-installing it, you can e.g. build everything and then install the package locally, where the -e flag will let you change/update the package without having to re-install it.

cd python
pip install -e .

Build without CMake

The following is an example of how to manually build the C library and link it with bindings into a corresponding Fortran executable, using gcc.

C library:

g++ -DFMT_HEADER_ONLY -Iinclude -fPIC -std=c++11 -c src/ovf.cpp -o ovf.cpp.o

# static
ar qc libovf_static.a ovf.cpp.o
ranlib libovf_static.a

# shared
g++ -fPIC -shared -lc++ ovf.cpp.o -o libovf_shared.so

C/C++ test executable:

g++ -Iinclude -Itest -std=c++11 -c test/main.cpp -o main.cpp.o
g++ -Iinclude -Itest -std=c++11 -c test/simple.cpp -o simple.cpp.o

# link static lib
g++ -lc++ libovf_static.a main.cpp.o simple.cpp.o -o test_cpp_simple

# link shared lib
g++ libovf_shared.so main.cpp.o simple.cpp.o -o test_cpp_simple

Fortran library:

gfortran -fPIC -c fortran/ovf.f90 -o ovf.f90.o

ar qc libovf_fortran.a libovf_static.a ovf.f90.o
ranlib libovf_fortran.a

Fortran test executable

gfortran -c fortran/test/simple.f90 -o simple.f90.o
gfortran -lc++ libovf_fortran.a simple.f90.o -o test_fortran_simple

When linking statically, you can also link the object file ovf.cpp.o instead of libovf_static.a.

Note: depending on compiler and/or system, you may need -lstdc++ instead of -lc++.

File format v2.0 specification

This specification is written according to the NIST user guide for OOMMF and has been implemented, but not tested or verified against OOMMF.

Note: The OVF 2.0 format is a modification to the OVF 1.0 format that also supports fields across three spatial dimensions but having values of arbitrary (but fixed) dimension. The following is a full specification of the 2.0 format.

General

  • An OVF file has an ASCII header and trailer, and data blocks that may be either ASCII or binary.
  • All non-data lines begin with a # character
  • Comments start with ## and are ignored by the parser. A comment continues until the end of the line.
  • There is no line continuation character
  • Lines starting with a # but containing only whitespace are ignored
  • Lines starting with a # but containing an unknown keyword are are an error

After an overall header, the file consists of segment blocks, each composed of a segment header, data block and trailer.

  • The field domain (i.e., the spatial extent) lies across three dimensions, with units typically expressed in meters or nanometers
  • The field can be of any arbitrary dimension N > 0 (This dimension, however, is fixed within each segment).

Header

  • The first line of an OVF 2.0 file must be # OOMMF OVF 2.0
  • The header should also contain the number of segments, specified as e.g. # Segment count: 000001
  • Zero-padding of the segment count is not specified

Segments

Segment Header

  • Each block begins with a # Begin: <block type> line, and ends with a corresponding # End: <block type> line
  • A non-empty non-comment line consists of a keyword and a value:
    • A keyword consists of all characters after the initial # up to the first colon (:) character. Case is ignored, and all whitespace is removed
    • Unknown keywords are errors
    • The value consists of all characters after the first colon (:) up to a comment (##) or line ending
  • The order of keywords is not specified
  • None of the keywords have default values, so all are required unless stated otherwise

Everything inside the Header block should be either comments or one of the following file keyword lines

  • title: long file name or title
  • desc (optional): description line, use as many as desired
  • meshunit: fundamental mesh spatial unit. The comment marker ## is not allowed in this line. Example value: nm
  • valueunits: should be a (Tcl) list of value units. The comment marker ## is not allowed in this line. Example value: "kA/m". The length of the list should be one of
    • N: each element denotes the units for the corresponding dimension index
    • 1: the single element is applied to all dimension indexes
  • valuelabels: This should be a N-item (Tcl) list of value labels, one for each value dimension. The labels identify the quantity in each dimension. For example, in an energy density file, N would be 1, valueunits could be "J/m3", and valuelabels might be "Exchange energy density"
  • valuedim (integer): specifies an integer value, N, which is the dimensionality of the field. N >= 1
  • xmin, ymin, zmin, xmax, ymax, zmax: six separate lines, specifying the bounding box for the mesh, in units of meshunit
  • meshtype: grid structure; one of
    • rectangular: Requires also
      • xbase, ybase, zbase: three separate lines, denoting the origin (i.e. the position of the first point in the data section), in units of meshunit
      • xstepsize, ystepsize, zstepsize: three separate lines, specifying the distance between adjacent grid points, in units of meshunit
      • xnodes, ynodes, znodes (integers): three separate lines, specifying the number of nodes along each axis.
    • irregular: Requires also
      • pointcount (integer): number of data sample points/locations, i.e., nodes. For irregular grids only

Segment Data

  • The data block start is marked by a line of the form # Begin: data <representation> (and therefore closed by # End: data <representation>), where <representation> is one of
    • text
    • binary 4
    • binary 8
  • In the Data block, for regular meshes each record consists of N values, where N is the value dimension as specified by the valuedim record in the Segment Header. For irregular meshes, each record consists of N + 3 values, where the first three values are the x , y and z components of the node position.
  • It is common convention for the text data to be in N columns, separated by whitespace
  • Data ordering is generally with the x index incremented first, then the y index, and the z index last

For binary data:

  • The binary representations are IEEE 754 standardized floating point numbers in little endian (LSB) order. To ensure that the byte order is correct, and to provide a partial check that the file hasn't been sent through a non 8-bit clean channel, the first data value is fixed to 1234567.0 for 4-byte mode, corresponding to the LSB hex byte sequence 38 B4 96 49, and 123456789012345.0 for 8-byte mode, corresponding to the LSB hex byte sequence 40 DE 77 83 21 12 DC 42
  • The data immediately follows the check value
  • The first character after the last data value should be a newline

Extensions made by this library

These extensions are mainly to help with data for atomistic systems.

  • The segment count is padded to 6 digits with zeros (this is so that segments can be appended and the count incremented without having to re-write the entire file)
  • Lines starting with a # but containing an unknown keyword are ignored.
  • ## is always a comment and is allowed in all keyword lines, including meshunit and valueunits
  • All keywords have default values, so none are required
  • csv is also a valid ASCII data representation and corresponds to comma-separated columns of text type

Current limitations of this library

  • naming of variables in structs/classes is inconsistent with the file format specifications
  • not all defaults in the segment are guaranteed to be sensible
  • valueunits and valuelabels are written and parsed, but not checked for dimensionality or content in either
  • min and max values are not checked to make sure they are sensible bounds
  • irregular mesh type is not supported properly, as positions are not accounted for in read or write

Example

An example OVF 2.0 file for an irregular mesh with N = 2:

# OOMMF OVF 2.0
#
# Segment count: 1
#
# Begin: Segment
# Begin: Header
#
# Title: Long file name or title goes here
#
# Desc: Optional description line 1.
# Desc: Optional description line 2.
# Desc: ...
#
## Fundamental mesh measurement unit.  Treated as a label:
# meshunit: nm
#
# meshtype: irregular
# pointcount: 5      ## Number of nodes in mesh
#
# xmin:    0.    ## Corner points defining mesh bounding box in
# ymin:    0.    ## 'meshunit'.  Floating point values.
# zmin:    0.
# xmax:   10.
# ymax:    5.
# zmax:    1.
#
# valuedim: 2    ## Value dimension
#
## Fundamental field value units, treated as labels (i.e., unparsed).
## In general, there should be one label for each value dimension.
# valueunits:  J/m^3  A/m
# valuelabels: "Zeeman energy density"  "Anisotropy field"
#
# End: Header
#
## Each data records consists of N+3 values: the (x,y,z) node
## location, followed by the N value components.  In this example,
## N+3 = 5, the two value components are in units of J/m^3 and A/m,
## corresponding to Zeeman energy density and a magneto-crystalline
## anisotropy field, respectively.
#
# Begin: data text
0.5 0.5 0.5  500.  4e4
9.5 0.5 0.5  300.  5e3
0.5 4.5 0.5  400.  4e4
9.5 4.5 0.5  200.  5e3
5.0 2.5 0.5  350.  2.1e4
# End: data text
# End: segment

Comparison to OVF 1.0

  • The first line reads # OOMMF OVF 2.0 for both regular and irregular meshes.
  • In the segment header block
    • the keywords valuemultiplier, boundary, ValueRangeMaxMag and ValueRangeMinMag of the OVF 1.0 format are not supported.
    • the new keyword valuedim is required. This must specify an integer value, N, bigger or equal to one.
    • the new valueunits keyword replaces the valueunit keyword of OVF 1.0, which is not allowed in OVF 2.0 files.
    • the new valuelabels keyword is required.
  • In the segment data block
    • The node ordering is the same as for the OVF 1.0 format.
    • For data blocks using text representation with N = 3, the data block in OVF 1.0 and OVF 2.0 files are exactly the same. Another common case is N = 1, which represents scalar fields, such as energy density (in say, J/m3 )

ovf's People

Contributors

gpmueller avatar mredies avatar msallermann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ovf's Issues

Add support for OVF 1.0?

I am unsure whether this is reasonable, as this is (to my knowledge) no longer the standard output format of current micromagnetic codes. Also, it might negatively impact the API, in which case it should probably not be done.

It might be interesting for educational purposes or rare use-cases and it would be nice to support more than one version of the file format.

Locating segments in a file is implemented inefficiently

Even for a file of only ~30MB, OVF_File::count_and_locate_segments takes a second to run through, so this should definitely be done differently.

The repetitive usage of Filter_File_Handle::Find and thereby Filter_File_Handle::Find_in_Line is probably the bottleneck. Maybe it can be written to be faster, but I don't know how.

Therefore, OVF_File::count_and_locate_segments needs to be rewritten to jump over data blocks while scanning through the file.

  • the file should be scanned for the first # Begin: Segment
  • then, the header should be checked for the data dimensions and formatting
  • then, the file should be scanned for the next # Begin: Data
  • then, the scan should jump over the data block (N lines in text, N*M*sizeof(binarysize) in binary)
  • if the OVF file specifies a different data count in a segment header than what is in the following data block, the code will incorrectly set the segment limits. Can this somehow be avoided?

Not able to pip install package in anaconda on windows 10

I tried to install the package with the anaconda prompt on a windows 10 system using the command 'pip install ovf'. I recieved the following error message:

Collecting ovf
  Using cached ovf-0.4.3.tar.gz (492 kB)
    ERROR: Command errored out with exit status 1:
     command: 'c:\anaconda3\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-0ueof6kx\\ovf\\setup.py'"'"'; __file__='"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-0ueof6kx\\ovf\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\user\AppData\Local\Temp\pip-install-0ueof6kx\ovf\pip-egg-info'
         cwd: C:\Users\user\AppData\Local\Temp\pip-install-0ueof6kx\ovf\
    Complete output (9 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\user\AppData\Local\Temp\pip-install-0ueof6kx\ovf\setup.py", line 123, in <module>
        long_description = read(README),
      File "C:\Users\user\AppData\Local\Temp\pip-install-0ueof6kx\ovf\setup.py", line 45, in read
        with codecs.open(os.path.join(HERE, *parts), "rb", "utf-8") as f:
      File "c:\anaconda3\lib\codecs.py", line 897, in open
        file = builtins.open(filename, mode, buffering)
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-0ueof6kx\\ovf\\..\\README.md'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

I then tried to clone the respository with git. I gave the anaconda prompt the command: "pip install git+https://github.com/spirit-code/ovf.git" and got the following error message.

Collecting git+https://github.com/spirit-code/ovf.git
  Cloning https://github.com/spirit-code/ovf.git to c:\users\user\appdata\local\temp\pip-req-build-k2mltrb6
  Running command git clone -q https://github.com/spirit-code/ovf.git 'C:\Users\user\AppData\Local\Temp\pip-req-build-k2mltrb6'
    ERROR: Command errored out with exit status 1:
     command: 'c:\anaconda3\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-req-build-k2mltrb6\\setup.py'"'"'; __file__='"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-req-build-k2mltrb6\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\user\AppData\Local\Temp\pip-req-build-k2mltrb6\pip-egg-info'
         cwd: C:\Users\user\AppData\Local\Temp\pip-req-build-k2mltrb6\
    Complete output (5 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "c:\anaconda3\lib\tokenize.py", line 452, in open
        buffer = _builtin_open(filename, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\user\\AppData\\Local\\Temp\\pip-req-build-k2mltrb6\\setup.py'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Details;
-python version: 3.6
-pip version: 20.0.2
-operating system : 64 bit windows 10
-git version: 2.25.1.windows.1

Create unit tests

Probably using only Python would be sufficient, at least for the beginning.

ovf.dll not found

I have already installed the ovf library and I am having the following issue:
FileNotFoundError: Could not find module 'C:\Users\Charlie\anaconda3\envs\spirit\Lib\site-packages\ovf\ovf.dll' (or one of its dependencies). Try using the full path with constructor syntax.

I am sending a picture to see the complete problem. Any help to face this problem will be really appreciated.

WhatsApp Image 2023-03-10 at 22 44 33

Design a minimalistic API

The following guide gives a very good intro to minimalistic C API Design
http://nullprogram.com/blog/2018/06/10/
I believe most of the suggestions cannot be realized with the complexity of OVF file parsing

My first suggestion:

/* return codes */
#define OVF_OK          -1
#define OVF_INVALID     -2

/* the geometrical information on the vector field */
struct ovf_geometry {
    int n_cells[3];
    int N;

    float bounds_min[3];
    float bounds_max[3];

    /* then some "private" internal fields */
};

/* all header info on a segment */
struct ovf_segment {
    char *title;
    char *meshunits;
    int valuedim;
    char *valueunits;
    char *valuelabels;
    char *meshtype;

    /* then some "private" internal fields */
};

/* opaque handle which holds the file pointer */
struct ovf_file_handle;

/* the main struct which keeps the info on the main header of a file */
struct ovf_file {
    /* file could be found */
    bool found;
    /* file contains an ovf header */
    bool is_ovf;
    /* number of segments the file should contain */
    int n_segments;

    /* then some "private" internal fields */
    struct ovf_file_handle _file;
};

/* opening a file will fill the struct and prepare everything for read/write */
void ovf_open(struct ovf_file *, const char *filename);
/* reading a segment will write the data, if present, into the buffer.
    The ordering of the data will depend on the specification of the geometry.
    It will also check the file against the expected geometry.
    The ovf_file will be filled with the information from the segment header. */
int  ovf_read_segment(struct ovf_file *, int index, const struct ovf_geometry *expected, struct ovf_segment *segment, float *data);
int  ovf_read_segment(struct ovf_file *, int index, const struct ovf_geometry *expected, struct ovf_segment *segment, double *data);
/* write a segment to the file, overwriting all contents. The new header will have segment count = 1 */
int  ovf_write_segment(struct ovf_file *, long codepoint);
/* append a segment to the file. The segment count will be incremented */
int  ovf_append_segment(struct ovf_file *, long codepoint);
/* close the file and clean up resources */
long ovf_close(struct ovf_file *);

Atomistic OVF file extension

Atomistic OVF file extension

To better support the atomistic use-case, it would be nice to extend the OVF file format by additional fields in the header.

The main problem with the current OVF format is that crystal lattices, consisting of a bravais lattice plus an additional basis cannot be efficiently modelled. They are neither rectangular nor is it necessary to explicitly save all of the positions in three extra columns. Therefore no of the possible meshtype values (rectangular orirregular) really fits.

I suggest to introduce meshtype lattice, which, if set, would require

  • bravaisa a list of three values, giving the bravais vector in the first direction in terms of the meshunit
  • bravaisb see above
  • bravaisc see above
  • anodes number of cells in direction a
  • bnodes see above
  • cnodes see above
  • ncellpoints number of points per cell of the lattice

Lastly, one would need to save the basis vectors. About this part I am the least sure, since there seems to be no good precedent for how to format this in the OVF 2.0 spec.
A few options that come to mind:

## Option 1
# ncellpoints: 2
# basis:
# 0 0 0
# 0 1 0

## Option 2
# ncellpoints: 2
# basis: 0 0 0
# basis: 0 1 0

## Option 3
# ncellpoints: 2
# basis1: 0 0 0
# basis2: 0 1 0

## Option 4
# ncellpoints: 2
# basis: 0 0 0 0 1 0

Of all these, Option 4 breaks the previous OVF specification the least, but it's also the ugliest in my opinion. I would probably prefer Option 1 and thus allow multiline header fields.

One concern is of course the compatibility with the OVF 2.0 format, which unfortunately does not allow for the addition of arbitrary fields in the header.
I can imagine that it would be practicable to introduce a new file ending ".aovf" (for atomistic OVF).
Then I would implement a compatibility mode in this library, which would allow one to save (and read) AOVF files in a format that is compatible to OVF 2.0 (by prefixing the new fields with comments + some special character, e.g ##%).

Im not familiar with the pegtl library used here, so I am not sure how much of a hassle it would be to implement this.

A file in AOVF format could look like this:

# AOVF 1.0
#
# Segment count: 000001
#
# Begin: Segment
# Begin: Header
#
# Title: example.aovf
#
# Desc: more details in this comment...
#
# valuedim: 3   ## field dimensionality
# valueunits:   unspecified unspecified unspecified
# valuelabels:  unspecified unspecified unspecified
#
## Fundamental mesh measurement unit. Treated as a label:
# meshunit: unspecified
#
# meshtype: lattice
# xbase: 0
# ybase: 0
# zbase: 0
# bravaisa: 1 0 0
# bravaisb: 0 1 0
# bravaisc: 0 0 1
# anodes: 2
# bnodes: 1
# cnodes: 1
# ncellpoints: 2
# basis:
# 0 0 0
# 0.5 0 0
#
# End: Header
#
# Begin: Data Text
        0.000000000000        0.000000000000        0.000000000000
        3.000000000000        2.000000000000        1.000000000000
        0.000000000000        0.000000000000        0.000000000000
        0.000000000000        0.000000000000        0.000000000000
# End: Data Text
# End: Segment

And the same file in compatibility mode could look like this:

# OOMMF OVF 2.0
##% AOVF 1.0
#
# Segment count: 000001
#
# Begin: Segment
# Begin: Header
#
# Title: example.ovf
#
# Desc: more details in this comment...
#
# valuedim: 3   ## field dimensionality
# valueunits:   unspecified unspecified unspecified
# valuelabels:  unspecified unspecified unspecified
#
## Fundamental mesh measurement unit. Treated as a label:
# meshunit: unspecified
#
# meshtype: rectangular
# xbase: 0
# ybase: 0
# zbase: 0
# xstepsize: 1
# ystepsize: 1
# zstepsize: 1
# xnodes: 4
# ynodes: 2
# znodes: 1
##% bravaisa: 1 0 0
##% bravaisb: 0 1 0
##% bravaisc: 0 0 1
##% anodes: 2
##% bnodes: 1
##% cnodes: 1
##% ncellpoints: 2
##% basis:
##% 0 0 0
##% 0.5 0 0
#
# End: Header
#
# Begin: Data Text
        0.000000000000        0.000000000000        0.000000000000
        3.000000000000        2.000000000000        1.000000000000
        0.000000000000        0.000000000000        0.000000000000
        0.000000000000        0.000000000000        0.000000000000
# End: Data Text
# End: Segment

Conform closer to OVF 2.0 format specifications

See OVF 2.0 specs and OVF 1.0 specs.

The requirements are:

  • a rectilinear lattice with a single-atom basis cell should work identically between atomistic and micromagnetic
  • specification-conformant files should always be read in correctly
  • a conformant parser (e.g. micromagnetic code) should be able to read our non-conformant files

The latter two points would mean non-conformance would have to be a pure extension of the format, without changing keywords or their meaning.

One concern for me is that OVF keeps everything in x, y, z representation with one node representing one data point, whereas we may want to generalize it to arbitrary bravais lattices with basis cells with potentially multiple nodes per cell. Otherwise, we would have to represent such cases as irregular meshes...

Another concern is that the valuedim seems to specify additional dimensions (the specs are unclear on this), meaning that 3 columns of data always represent the positions and the remaining columns represent the actual data. This seems very wasteful - maybe it is only supposed to be done this way for meshtype irregular? Otherwise I suggest non-conformance.

Improve Continuous Integrations

Travis CI is already running, building on Ubuntu and OSX and uploading the packages to PyPI.

  • AppVeyor
  • When #3 is implemented, unit tests should also be run through the CIs
  • When #3 is implemented, coverage checks should be added

Irregular lattice data blocks do not conform to specifications

For irregular lattices, the specs say the position of each data point should come right before the values, effectively increasing the number of columns by 3.
This is currently not respected by the library, both in writing and parsing.

Questions:

  • should two data pointers be used or only one, which points to a contiguous block of both positions and values?
  • how should the data reading function work: 1:1 into the array or e.g. first read positions, then values?
  • do the specs in the Readme need improvement?

Add individual specs of OVF formats 1.0 and 2.0

This might help anyone trying to convert files between the two formats and may eventually help if this library is supposed to support OVF 1.0 at some point (see #11).

Might be good to also add a proposed format spec, generalized to support both atomistic and micromagnetic use cases fully and conveniently.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.