Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit files over 2GB #156

Merged
merged 5 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion ansys/mapdl/reader/archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class Archive(Mesh):
name : str, optional
Internally used parameter used to have a custom ``__repr__``.

read_eblock : bool, default: True
Read the element block.

Examples
--------
>>> from ansys.mapdl import reader as pymapdl_reader
Expand Down Expand Up @@ -125,13 +128,17 @@ def __init__(
null_unallowed=False,
verbose=False,
name="",
read_eblock=True,
):
"""Initializes an instance of the archive class."""
self._read_parameters = read_parameters
self._filename = pathlib.Path(filename)
self._name = name
self._raw = _reader.read(
self.filename, read_parameters=read_parameters, debug=verbose
self.filename,
read_parameters=read_parameters,
debug=verbose,
read_eblock=read_eblock,
)
super().__init__(
self._raw["nnum"],
Expand Down
85 changes: 39 additions & 46 deletions ansys/mapdl/reader/cython/_reader.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ def safe_int(value):

cdef extern from "reader.h":
int read_nblock_from_nwrite(char*, int*, double*, int)
int read_nblock(char*, int*, double*, int, int*, int, int*)
int read_eblock(char*, int*, int*, int, int, int*)
int read_nblock(char*, int*, double*, int, int*, int, int64_t*)
int read_eblock(char*, int*, int*, int, int, int64_t*)
int write_array_ascii(const char*, const double*, int);


Expand All @@ -58,13 +58,13 @@ cdef extern from 'vtk_support.h':
const int*, int64_t*, int64_t*, uint8_t*, const int)


cdef int myfgets(char *outstr, char *instr, int *n, int fsize):
cdef int myfgets(char *outstr, char *instr, int64_t *n, int64_t fsize):
"""Copies a single line from instr to outstr starting from position n """

cdef int k = n[0]

# Search line at a maximum of 10000 characters
cdef int i, c
cdef int64_t i, c
c = n[0]
for i in range(1000):
# check if end of file
Expand All @@ -89,7 +89,7 @@ cdef int myfgets(char *outstr, char *instr, int *n, int fsize):
return 1


def py_read_eblock(char *raw, int n, char *line, int fsize):
def py_read_eblock(char *raw, int64_t n, char *line, int64_t fsize):
"""Read the eblock

The format of the element "block" is as follows for the SOLID format:
Expand Down Expand Up @@ -144,7 +144,7 @@ additional node numbers if there are more than eight.
return elem_sz, elem, elem_off


def read(filename, read_parameters=False, debug=False):
def read(filename, read_parameters=False, debug=False, read_eblock=True):
"""Read blocked ansys archive file."""
badstr = 'Badly formatted cdb file'
filename_byte_string = filename.encode("UTF-8")
Expand All @@ -159,15 +159,15 @@ def read(filename, read_parameters=False, debug=False):

# Load entire file to memory
fseek(cfile, 0, SEEK_END)
cdef int fsize = ftell(cfile)
cdef int64_t fsize = ftell(cfile)
fseek(cfile, 0, SEEK_SET)
cdef char *raw = < char * >malloc(fsize*sizeof(char))
fread(raw, 1, fsize, cfile)
fclose(cfile)

# File counter
cdef int tmpval, start_pos
cdef int n = 0
cdef int64_t n = 0

# Define variables
cdef size_t l = 0
Expand Down Expand Up @@ -205,13 +205,15 @@ def read(filename, read_parameters=False, debug=False):
# keyopt
keyopt = {}

# Read data up to and including start of NBLOCK
while 1:
if myfgets(line, raw, &n, fsize):
break

# Record element types
if 'E' == line[0] or 'e' == line[0]:
if debug:
print('Hit "E"')

if b'ET,' == line[:3] or b'et,' == line[:3]:
if debug:
print('reading ET')
Expand All @@ -226,7 +228,7 @@ def read(filename, read_parameters=False, debug=False):
print('Invalid "ET" command %s' % line.decode())
continue

elif b'EBLOCK,' == line[:7] or b'eblock,' == line[:7]:
elif b'EBLOCK,' == line[:7] or b'eblock,' == line[:7] and read_eblock:
if eblock_read:
# Sometimes, DAT files contain two EBLOCKs. Read
# only the first block.
Expand All @@ -244,6 +246,9 @@ def read(filename, read_parameters=False, debug=False):
print('finished')

elif b'K' == line[0] or b'k' == line[0]:
if debug:
print('Hit "K"')

if b'KEYOP' in line or b'keyop' in line:
if debug:
print('reading KEYOP')
Expand All @@ -262,6 +267,9 @@ def read(filename, read_parameters=False, debug=False):
keyopt[key_num] = [entry[1:]]

elif 'R' == line[0] or 'r' == line[0]:
if debug:
print('Hit "R"')

if b'RLBLOCK' in line or b'rlblock' in line:
if debug:
print('reading RLBLOCK')
Expand Down Expand Up @@ -349,6 +357,9 @@ def read(filename, read_parameters=False, debug=False):
rdat.append(rcon)

elif 'N' == line[0] or 'n' == line[0]:
if debug:
print('Hit "N"')

# if line contains the start of the node block
if line[:6] == b'NBLOCK' or line[:6] == b'nblock':
if nodes_read:
Expand Down Expand Up @@ -380,43 +391,13 @@ def read(filename, read_parameters=False, debug=False):
nodes = nodes[:nnodes]
nnum = nnum[:nnodes]

# # verify at the end of the block
# if nnodes_read != nnodes:
# nnodes = nnodes_read
# nodes = nodes[:nnodes]
# nnum = nnum[:nnodes]
# else:
# if myfgets(line, raw, &n, fsize):
# raise RuntimeError('Unable to read nblock format line or '
# 'at end of file.')

# bl_end = line.decode().replace(' ', '')
# if 'LOC' not in bl_end or b'-1' == bl_end[:2]:
# if debug:
# print('Unable to find the end of the NBLOCK')
# # need to reread the number of nodes
# n = start_pos
# if myfgets(line, raw, &n, fsize): raise Exception(badstr)
# nnodes = 0
# while True:
# if myfgets(line, raw, &n, fsize): raise Exception(badstr)
# bl_end = line.decode().replace(' ', '')
# if 'LOC' not in bl_end or b'-1' == bl_end[:2]:
# break
# nnodes += 1

# # reread nodes
# n = start_pos
# if myfgets(line, raw, &n, fsize): raise Exception(badstr)
# d_size, f_size, nfld, nexp = node_block_format(line)
# nnum = np.empty(nnodes, dtype=ctypes.c_int)
# nodes = np.zeros((nnodes, 6))

# n = read_nblock(raw, &nnum[0], &nodes[0, 0], nnodes,
# &d_size[0], f_size, &n)

if debug:
print('Read', nnodes_read, 'nodes')

elif 'C' == line[0] or 'c' == line[0]:
if debug:
print('Hit "C"')

if line[:8] == b'CMBLOCK,' or line[:8] == b'cmblock,': # component block
if debug:
print('reading CMBLOCK')
Expand Down Expand Up @@ -463,6 +444,9 @@ def read(filename, read_parameters=False, debug=False):
elem_comps[comname] = component_interperter(component)

elif '*' == line[0] and read_parameters: # maybe *DIM
if debug:
print('Hit "*"')

if b'DIM' in line:
items = line.decode().split(',')
if len(items) < 3:
Expand Down Expand Up @@ -495,6 +479,10 @@ def read(filename, read_parameters=False, debug=False):

# if the node block was not read for some reason
if not nodes_read:
# Free cached archive file
if debug:
print('Did not read nodes block. Rereading from start.')

n = 0
while 1:
if myfgets(line, raw, &n, fsize):
Expand All @@ -516,6 +504,8 @@ def read(filename, read_parameters=False, debug=False):
&d_size[0], f_size, &n)

# Free cached archive file
if debug:
print('Freeing memory')
free(raw)

# assemble global element block
Expand All @@ -524,6 +514,9 @@ def read(filename, read_parameters=False, debug=False):
elem_off = np.empty(0, dtype=ctypes.c_int)
elem_sz = 0

if debug:
print('Returning arrays')

return {'rnum': np.asarray(rnum),
'rdat': rdat,
'ekey': np.asarray(elem_type, ctypes.c_int),
Expand Down
17 changes: 7 additions & 10 deletions ansys/mapdl/reader/cython/reader.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include <errno.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>


//=============================================================================
// Fast string to integer convert to ANSYS formatted integers
Expand Down Expand Up @@ -216,11 +216,11 @@ static inline double ans_strtod2(char *raw, int fltsz){
// Number of nodes read.
//=============================================================================
int read_nblock(char *raw, int *nnum, double *nodes, int nnodes, int* intsz,
int fltsz, int *n){
int fltsz, int64_t* n){

// set to start of the NBLOCK
raw += n[0];
int len_orig = strlen(raw);
int64_t len_orig = strlen(raw);
int i, j, i_val, eol;

for (i=0; i<nnodes; i++){
Expand Down Expand Up @@ -265,11 +265,8 @@ int read_nblock(char *raw, int *nnum, double *nodes, int nnodes, int* intsz,
}

// return file position
/* int fpos = len_orig - strlen(raw) + n[0]; */
/* return fpos; */
n[0] += len_orig - strlen(raw);
return i;

}


Expand Down Expand Up @@ -356,12 +353,12 @@ int read_nblock_from_nwrite(const char* filename, int *nnum, double *nodes,
* pos : Position of the start of the EBLOCK.
* ==========================================================================*/
int read_eblock(char *raw, int *elem_off, int *elem, int nelem, int intsz,
int *pos){
int64_t *pos){
int i, j, nnode;

// set to start of the EBLOCK
raw += pos[0];
int len_orig = strlen(raw);
int64_t len_orig = strlen(raw);
int c = 0; // position in elem array

// Loop through elements
Expand Down
9 changes: 7 additions & 2 deletions ansys/mapdl/reader/cython/reader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include <stdio.h>

int read_nblock(char*, int*, double*, int, int*, int, int*);
int read_eblock(char*, int*, int*, int, int, int*);
#ifdef __linux__
#include <stdint.h>
#endif


int read_nblock(char*, int*, double*, int, int*, int, int64_t*);
int read_eblock(char*, int*, int*, int, int, int64_t*);
int read_nblock_from_nwrite(char*, int*, double*, int);
int write_array_ascii(const char*, const double*, int nvalues);