OVF 文件解析器
项目描述
OVF 解析器库
用于强大的 OOMMF 矢量字段文件解析的简单 API
| 图书馆覆盖率 | Python 绑定覆盖率 |
|---|---|
如何使用
有关使用示例,请查看测试文件夹:test、python/test或fortran/test。
除了打开文件或初始化段外,所有函数都返回状态码(通常OVF_OK为OVF_INVALID或OVF_ERROR)。当返回码不是OVF_OK时,您可以查看最新消息,它应该会告诉您问题所在(const char * ovf_latest_message(struct ovf_file *)在 C API 中)。
在 C/C++ 和 Fortran 中,在编写段之前,请确保ovf_segment您传入的已初始化,即您已经调用了ovf_read_segment_headeror 或ovf_segment_create.
C/C++
打开和关闭:
struct ovf_file *myfile = ovf_open("myfilename.ovf")打开文件myfile->found检查文件是否存在于磁盘上myfile->is_ovf检查文件是否包含 OVF 标头myfile->n_segments检查文件应包含的段数ovf_close(myfile);关闭文件并释放资源
从文件中读取:
struct ovf_segment *segment = ovf_segment_create()初始化一个新段并获取指针ovf_read_segment_header(myfile, index, segment)将标头读入段结构- 创建适当大小的浮点数据数组...
ovf_read_segment_data_4(myfile, index, segment, data)将段数据读入浮点数组- 读取前设置
segment->N允许部分读取大数据段
写入和附加到文件:
struct ovf_segment *segment = ovf_segment_create()初始化一个新段并获取指针segment->n_cells[0] = ...等设置数据维度、标题和描述等。ovf_write_segment_4(myfile, segment, data, OVF_FORMAT_TEXT)写一个包含段头和数据的文件ovf_append_segment_4(myfile, segment, data, OVF_FORMAT_TEXT)将段头和数据附加到文件中
Python
要安装ovf python 包,要么从源代码构建和安装,要么简单地使用
pip install ovf
ovf从 Python 中使用,例如
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
Fortran 绑定以面向对象的风格编写,以便于使用。写一个文件,例如:
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
有关如何生成现代 Fortran 绑定的更多信息,另请参阅https://github.com/MRedies/Interfacing-Fortran
如何将其嵌入到您的项目中
如果您使用的是 CMake,则只需将其克隆到子目录中即可,例如thirdparty/ovf并将其与以下内容一起使用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} )
如果您不使用 CMake,则可能需要进行一些手动工作。
建造
在 Unix 系统上
通常:
mkdir build
cd build
cmake ..
make
在 Windows 上
一种可能:
- 在 CMake GUI 中打开文件夹
- 生成VS项目
- 在 VS 中打开生成的项目并构建它
CMake 选项
以下选项是ON默认的。如果你想关闭它们,只需传递-D<OPTION>=OFF给 CMake,例如-DOVF_BUILD_FORTRAN_BINDINGS=OFF.
OVF_BUILD_PYTHON_BINDINGSOVF_BUILD_FORTRAN_BINDINGSOVF_BUILD_TEST
在 Windows 上,您还可以从 CMake GUI 设置这些。
创建并安装 Python 包
代替pip安装它,您可以例如构建所有内容,然后在本地安装包,该-e标志将允许您更改/更新包而无需重新安装它。
cd python
pip install -e .
不使用 CMake 构建
以下是如何使用 gcc 手动构建 C 库并将其与绑定链接到相应的 Fortran 可执行文件的示例。
C 库:
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++ 测试可执行文件:
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 库:
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 测试可执行文件
gfortran -c fortran/test/simple.f90 -o simple.f90.o
gfortran -lc++ libovf_fortran.a simple.f90.o -o test_fortran_simple
静态链接时,您还可以链接目标文件ovf.cpp.o而不是libovf_static.a.
注意:根据编译器和/或系统,您可能需要-lstdc++代替-lc++.
文件格式v2.0规范
本规范是根据 NIST 用户指南编写的 OOMMF 并已实施,但未针对 OOMMF 进行测试或验证。
注意:OVF 2.0 格式是对 OVF 1.0 格式的修改,它还支持跨三个空间维度的字段,但具有任意(但固定)维度的值。以下是 2.0 格式的完整规范。
一般的
- OVF 文件具有 ASCII 标头和尾标,以及可能是 ASCII 或二进制的数据块。
- 所有非数据行都以
#字符开头 - 注释以开头
##并被解析器忽略。注释一直持续到行尾。 - 没有行继续符
- 以 a 开头
#但仅包含空格的行将被忽略 - 以 a 开头
#但包含未知关键字的行是错误的
在整体头之后,文件由段块组成,每个段由段头、数据块和尾部组成。
- 场域(即空间范围)跨越三个维度,单位通常以米或纳米表示
- 该字段可以是任意维度
N > 0(但是,该维度在每个段中是固定的)。
标题
- OVF 2.0 文件的第一行必须是
# OOMMF OVF 2.0 - 标头还应包含段数,指定为例如
# Segment count: 000001 - 未指定段计数的零填充
细分市场
段头
- 每个块都以
# Begin: <block type>一行开始,并以相应的# End: <block type>行结束 - 非空非注释行由关键字和值组成:
- 关键字由从首字母
#到第一个冒号 (:) 字符的所有字符组成。忽略大小写,并删除所有空格 - 未知关键字是错误
- 该值由第一个冒号 (
:) 之后直到注释 (##) 或行尾的所有字符组成
- 关键字由从首字母
- 未指定关键字的顺序
- 所有关键字都没有默认值,因此除非另有说明,否则所有关键字都是必需的
块内的所有内容都Header应该是注释或以下文件关键字行之一
title: 长文件名或标题desc(可选):描述行,尽可能多地使用meshunit:基本网格空间单元。##此行中不允许使用注释标记。示例值:nmvalueunits: 应该是一个 (Tcl) 值单位列表。##此行中不允许使用注释标记。示例值:"kA/m". 列表的长度应该是以下之一N:每个元素表示相应维度索引的单位1:单个元素应用于所有维度索引
valuelabels:这应该是N值标签的 -item (Tcl) 列表,每个值维度一个。标签标识每个维度中的数量。例如,在能量密度文件中,N可能是1,valueunits 可能是"J/m3",而 valuelabels 可能是"Exchange energy density"valuedim(integer):指定一个整数值,N,它是字段的维数。N >= 1xmin,ymin,zmin,xmax,ymax,zmax: 六个单独的线,指定网格的边界框,单位为meshunitmeshtype:网格结构;之一rectangular: 也需要xbase,ybase,zbase: 三个单独的线,表示原点(即数据段中第一个点的位置),单位为meshunitxstepsize,ystepsize,zstepsize: 三个单独的线,指定相邻网格点之间的距离,单位为meshunitxnodes,ynodes,znodes(整数):三个单独的行,指定沿每个轴的节点数。
irregular: 也需要pointcount(整数):数据样本点/位置的数量,即节点。仅适用于不规则网格
分段数据
- 数据块开始由表格的一行标记
# Begin: data <representation>(因此由 关闭# End: data <representation>),其中<representation>一个是textbinary 4binary 8
- 在 Data 块中,对于常规网格,每条记录都由
N值组成,其中是Segment Header 中N的记录指定的值维度。valuedim对于不规则网格,每个记录由N + 3值组成,其中前三个值是节点位置的 x 、 y 和 z 分量。 text数据在列中是常见的约定,N以空格分隔- 数据排序一般是先增加 x 索引,然后是 y 索引,最后是 z 索引
对于二进制数据:
- 二进制表示是采用小端 (LSB) 顺序的 IEEE 754 标准化浮点数。为确保字节顺序正确,并提供部分检查文件未通过非 8 位干净通道发送,第一个数据值固定
1234567.0为 4 字节模式,对应于 LSB hex byte sequence38 B4 96 49,123456789012345.0对于 8-byte 模式,对应 LSB hex byte sequence40 DE 77 83 21 12 DC 42 - 数据紧跟校验值
- 最后一个数据值之后的第一个字符应该是换行符
这个库所做的扩展
这些扩展主要是为了帮助处理原子系统的数据。
- 段计数用零填充到 6 位(这样可以附加段并增加计数,而无需重新写入整个文件)
- 以 a 开头
#但包含未知关键字的行将被忽略。 ##始终是注释,并且允许在所有关键字行中使用,包括meshunit和valueunits- 所有关键字都有默认值,因此不需要
csv也是一个有效的 ASCII 数据表示,并且对应于text类型的逗号分隔的列
该库的当前限制
- 结构/类中变量的命名与文件格式规范不一致
- 并非该段中的所有默认值都保证是合理的
valueunits并且valuelabels被写入和解析,但不检查维度或内容min并且max不检查值以确保它们是合理的界限irregular网格类型未得到正确支持,因为在读取或写入时未考虑位置
例子
N = 2 的不规则网格的示例 OVF 2.0 文件:
# 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
与 OVF 1.0 的比较
- 第一行读取
# OOMMF OVF 2.0规则和不规则网格。 - 在段头块中
- 不支持 OVF 1.0 格式的关键字
valuemultiplier、boundary和。ValueRangeMaxMagValueRangeMinMag - new 关键字
valuedim是必需的。这必须指定一个N大于或等于 1 的整数值。 - 新
valueunits关键字替换valueunitOVF 1.0 的关键字,在 OVF 2.0 文件中不允许使用该关键字。 - new
valuelabels关键字是必需的。
- 不支持 OVF 1.0 格式的关键字
- 在段数据块中
- 节点排序与 OVF 1.0 格式相同。
- 对于使用文本表示
N = 3的数据块,OVF 1.0 和 OVF 2.0 文件中的数据块完全相同。另一种常见情况是N = 1,它表示标量场,例如能量密度(例如J/m3)
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。