Esempio n. 1
0
def pmomsave2(\
                datafile, \
                Npmomarray, pmomarray, \
                wnum_mesh, reff_mesh, w0_mesh, qext_mesh, asym_mesh, \
                wnum_list, reff_list, maxdim_list, volume_list, parea_list):

    from scipy.io.netcdf import NetCDFFile as DS
    import numpy
    (Nreff, Niors, Nmoms) = pmomarray.shape
    nc = DS(datafile, 'w')
    nc.createDimension('reff', Nreff)
    nc.createDimension('iors', Niors)
    nc.createDimension('moms', Nmoms)
    nc.createDimension('one', 1)
    data = nc.createVariable('Npmomarray',
                             numpy.dtype('int32').char, ('reff', 'iors'))
    data[:] = Npmomarray
    data = nc.createVariable('pmomarray',
                             numpy.dtype('float64').char,
                             ('reff', 'iors', 'moms'))
    data[:] = pmomarray
    data = nc.createVariable('wnum_mesh',
                             numpy.dtype('float64').char, ('reff', 'iors'))
    data[:] = wnum_mesh[0:Nreff, 0:Niors]
    data = nc.createVariable('reff_mesh',
                             numpy.dtype('float64').char, ('reff', 'iors'))
    data[:] = reff_mesh[0:Nreff, 0:Niors]
    data = nc.createVariable('w0_mesh',
                             numpy.dtype('float64').char, ('reff', 'iors'))
    data[:] = w0_mesh[0:Nreff, 0:Niors]
    data = nc.createVariable('qext_mesh',
                             numpy.dtype('float64').char, ('reff', 'iors'))
    data[:] = qext_mesh[0:Nreff, 0:Niors]
    data = nc.createVariable('asym_mesh',
                             numpy.dtype('float64').char, ('reff', 'iors'))
    data[:] = asym_mesh[0:Nreff, 0:Niors]
    data = nc.createVariable('wnum_list',
                             numpy.dtype('float64').char, ('iors', 'one'))
    data[:] = wnum_list[0:Niors, :]
    data = nc.createVariable('reff_list',
                             numpy.dtype('float64').char, ('reff', 'one'))
    data[:] = reff_list[0:Nreff, :]
    data = nc.createVariable('maxdim_list',
                             numpy.dtype('float64').char, ('reff', 'one'))
    data[:] = maxdim_list[0:Nreff, :]
    data = nc.createVariable('volume_list',
                             numpy.dtype('float64').char, ('reff', 'one'))
    data[:] = volume_list[0:Nreff, :]
    data = nc.createVariable('parea_list',
                             numpy.dtype('float64').char, ('reff', 'one'))
    data[:] = parea_list[0:Nreff, :]
    nc.close()
    return
Esempio n. 2
0
def write_netcdf(filename, df, info=None):
    # FIXME: still a lot of issues here
    if info is None:
        info = {}

    f = NetCDFFile(filename, 'w', version=1)

    f.createDimension('_2_byte_string', 2)
    f.createDimension('_4_byte_string', 4)
    f.createDimension('_8_byte_string', 8)
    f.createDimension('_16_byte_string', 16)
    f.createDimension('_32_byte_string', 32)
    f.createDimension('_64_byte_string', 64)
    f.createDimension('_128_byte_string', 128)
    f.createDimension('_255_byte_string', 255)
    f.createDimension('error_number', 1)
    f.flush()

    # TODO: check that these do anything
    f.createDimension('instrument_number', 1)
    f.createDimension('range', 2)
    f.flush()

    f.dataset_completeness = 'C1'  # TODO: save peaks too? ('C1+C2')
    f.aia_template_revision = '1.0'
    f.ms_template_revision = '1.0.1'
    f.netcdf_revision = '2.3.2'
    f.languages = 'English'

    f.administrative_comments = 'none'
    f.dataset_origin = 'none'
    f.dataset_owner = ' '
    f.dataset_date_time_stamp = ' '
    f.flush()

    f.company_method_name = ' '
    f.pre_experiment_program_name = ' '
    f.post_experiment_program_name = ' '
    f.source_file_reference = ' '

    f.experiment_title = info.get('name', ' ')
    f.operator_name = info.get('operator', ' ')
    # TODO: wrong format for injection_date_time_stamp
    # example: 20141027123030-0500
    f.injection_date_time_stamp = info.get('date', ' ')
    f.company_method_id = info.get('method', ' ')
    f.sample_name = info.get('sample', ' ')
    f.flush()

    f.sample_id_comments = 'none'
    f.sample_id = 'none'
    f.sample_name = 'none'
    f.sample_type = 'none'
    f.sample_injection_volume = 'none'
    f.sample_amount = 'none'
    f.flush()

    f.retention_unit = 'Seconds'

    # TODO: need to merge this back into access method
    if hasattr(df.values, 'todense'):
        scan_locs = (df.values != 0).todense()
    else:
        scan_locs = df.values != 0

    f.createVariable('error_log', 'c', ('error_number', '_64_byte_string'))

    f.createDimension('scan_number', len(df.index))
    v = f.createVariable('scan_acquisition_time', '>d', ('scan_number',))
    v[:] = 60. * df.index.astype('d')
    v = f.createVariable('total_intensity', '>d', ('scan_number',))
    v[:] = df.values.sum(axis=1).astype('d').flatten()
    v = f.createVariable('point_count', '>i', ('scan_number',))
    v[:] = np.sum(scan_locs, axis=1).astype('i').flatten()
    f.flush()

    f.createDimension('point_number', np.sum(scan_locs))
    stretch_t = np.resize(df.index, df.values.T.shape).T
    v = f.createVariable('mass_values', '>f', ('point_number',))
    v[:] = stretch_t[scan_locs]
    v = f.createVariable('intensity_values', '>f', ('point_number',))
    if hasattr(df.values, 'todense'):
        v[:] = df.values.todense()[scan_locs]
    else:
        v[:] = df.values[scan_locs]

    # TODO: check that these do anything
    # f.createVariable('time_values', 'd', ('point_number',))
    v = f.createVariable('resolution', 'd', ('scan_number',))
    v[:] = -9999
    f.createVariable('actual_scan_number', 'i', ('scan_number',))
    v[:] = -9999
    f.createVariable('scan_index', 'i', ('scan_number',))
    v[:] = np.cumsum(np.sum(scan_locs, axis=1).astype('i'))
    f.createVariable('mass_range_min', 'd', ('scan_number',))
    v[:] = np.min(stretch_t[scan_locs]) * np.ones(stretch_t.shape[0])
    v = f.createVariable('mass_range_max', 'd', ('scan_number',))
    v[:] = np.max(stretch_t[scan_locs]) * np.ones(stretch_t.shape[0])
    v = f.createVariable('a_d_sampling_rate', 'd', ('scan_number',))
    v[:] = -9999
    v = f.createVariable('a_d_coaddition_factor', 'h', ('scan_number',))
    v[:] = -9999
    v = f.createVariable('flag_count', 'i', ('scan_number',))
    v[:] = 0
    f.createVariable('inter_scan_time', 'd', ('scan_number',))
    v[0] = 0
    v[1:] = np.diff(df.index.astype('d'))
    f.createVariable('scan_duration', 'd', ('scan_number',))
    v[:] = 1
    v = f.createVariable('time_range_min', 'd', ('scan_number',))
    v[:] = -9999
    v = f.createVariable('time_range_max', 'd', ('scan_number',))
    v[:] = -9999

    inst_tup = ('instrument_number', '_32_byte_string')
    f.createVariable('instrument_serial_no', 'c', inst_tup)
    f.createVariable('instrument_fw_version', 'c', inst_tup)
    f.createVariable('instrument_app_version', 'c', inst_tup)
    f.createVariable('instrument_os_version', 'c', inst_tup)
    f.createVariable('instrument_sw_version', 'c', inst_tup)
    f.createVariable('instrument_comments', 'c', inst_tup)
    f.createVariable('instrument_model', 'c', inst_tup)
    f.createVariable('instrument_name', 'c', inst_tup)
    f.createVariable('instrument_id', 'c', inst_tup)
    f.createVariable('instrument_mfr', 'c', inst_tup)

    f.close()
Esempio n. 3
0
def write_netcdf(filename, df, info=None):
    # FIXME: still a lot of issues here
    if info is None:
        info = {}

    f = NetCDFFile(filename, "w")

    f.createDimension("_2_byte_string", 2)
    f.createDimension("_4_byte_string", 4)
    f.createDimension("_8_byte_string", 8)
    f.createDimension("_16_byte_string", 16)
    f.createDimension("_32_byte_string", 32)
    f.createDimension("_64_byte_string", 64)
    f.createDimension("_128_byte_string", 128)
    f.createDimension("_255_byte_string", 255)
    f.createDimension("error_number", 1)
    f.flush()

    f.dataset_completeness = "C1"  # TODO: save peaks too? ('C1+C2')
    f.netcdf_revision = "2.3.2"
    f.languages = "English"
    f.flush()

    f.experiment_title = info.get("name", " ")
    f.operator_name = info.get("operator", " ")
    # TODO: wrong format for injection_date_time_stamp
    f.injection_date_time_stamp = info.get("date", " ")
    f.company_method_id = info.get("method", " ")
    f.sample_name = info.get("sample", " ")
    f.flush()

    f.createDimension("scan_number", len(df.index))
    v = f.createVariable("scan_acquisition_time", ">d", ("scan_number",))
    v[:] = df.index.astype("d")
    v = f.createVariable("total_intensity", ">d", ("scan_number",))
    v[:] = df.values.sum(axis=1).astype("d")
    v = f.createVariable("point_count", ">i", ("scan_number",))
    v[:] = np.sum(df.values != 0, axis=1).astype("i")
    f.flush()

    f.createDimension("point_number", np.sum(df.values != 0))
    stretch_t = np.resize(df.index, df.values.T.shape).T
    v = f.createVariable("mass_values", ">f", ("point_number",))
    v[:] = stretch_t[df.values != 0]
    v = f.createVariable("intensity_values", ">f", ("point_number",))
    v[:] = df.values[df.values != 0]

    f.close()
Esempio n. 4
0
class DatabaseFileWriter(DatabaseFile):
    mode = 'w'
    def __init__(self, filename):
        '''
        Notes
        -----
        The EXOFile class is an interface to the Exodus II api. Its methods
        are named after the analogous method from the Exodus II C bindings,
        minus the prefix 'ex_'.

        '''
        self.fh = NetCDFFile(filename, mode='w')
        self.jobid = os.path.splitext(os.path.basename(filename))[0]
        self.filename = filename

    def initialize(self, elem_var_names):
        # ------------------------------------------------------------------- #
        # -------------------------------- standard ExodusII dimensioning --- #
        # ------------------------------------------------------------------- #
        self.fh.floating_point_word_size = 4
        self.fh.version = 5.0300002
        self.fh.file_size = 1
        self.fh.api_version = 5.0300002
        self.fh.title = 'Matmodlab material point simulation'

        self.fh.filename = basename(self.filename)
        self.fh.jobid = self.jobid

        self.fh.createDimension('len_string', 33)
        self.fh.createDimension('len_line', 81)
        self.fh.createDimension('four', 4)

        self.fh.createDimension('num_dim', 3)
        self.fh.createDimension('num_node', 8)
        self.fh.createDimension('num_elem', 1)

        # node and element number maps
        self.fh.createVariable('nodes', 'i', ('num_node',))
        self.fh.variables['nodes'][:] = range(1, 9)
        self.fh.createVariable('elements', 'i', ('num_elem',))
        self.fh.variables['elements'][:] = [1]

        # ------------------------------------------------------------------- #
        # ---------------------------------------------------- QA records --- #
        # ------------------------------------------------------------------- #
        now = datetime.datetime.now()
        day = now.strftime("%m/%d/%y")
        hour = now.strftime("%H:%M:%S")
        self.fh.createDimension('num_qa_rec', 1)
        self.fh.createVariable('qa_records', 'c',
                               ('num_qa_rec', 'four', 'len_string'))
        self.fh.variables['qa_records'][0, 0, :] = adjstr('Matmodlab')
        self.fh.variables['qa_records'][0, 1, :] = adjstr(self.jobid)
        self.fh.variables['qa_records'][0, 2, :] = adjstr(day)
        self.fh.variables['qa_records'][0, 3, :] = adjstr(hour)

        # ------------------------------------------------------------------- #
        # ------------------------------------------------- record arrays --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension('time_step', None)
        self.fh.createVariable('time_whole', 'f', ('time_step',))
        self.fh.createVariable('step_num', 'i', ('time_step',))
        self.fh.createVariable('frame_num', 'i', ('time_step',))

        # ------------------------------------------------------------------- #
        # --------------------------------------- element block meta data --- #
        # ------------------------------------------------------------------- #
        # block IDs - standard map
        self.fh.createDimension('num_el_blk', 1)
        self.fh.createVariable('eb_prop1', 'i', ('num_el_blk',))
        self.fh.variables['eb_prop1'][:] = np.arange(1, dtype=np.int32)+1
        self.fh.variables['eb_prop1'].name = 'ID'

        self.fh.createVariable('eb_status', 'i', ('num_el_blk',))
        self.fh.variables['eb_status'][:] = np.ones(1, dtype=int)

        self.fh.createVariable('eb_names', 'c', ('num_el_blk', 'len_string'))
        self.fh.variables['eb_names'][0][:] = adjstr('ElementBlock1')

        # element map
        self.fh.createDimension('num_el_in_blk1', 1)
        self.fh.createDimension('num_nod_per_el1', 8)
        self.fh.createVariable('elem_map1', 'i', ('num_el_in_blk1',))
        self.fh.variables['elem_map1'][:] = np.arange(1, dtype=np.int32)+1

        # set up the element block connectivity
        dim = ('num_el_in_blk1', 'num_nod_per_el1')
        self.fh.createVariable('connect1', 'i', dim)
        self.fh.variables['connect1'][:] = np.arange(8, dtype=np.int32)+1
        self.fh.variables['connect1'].elem_type = 'HEX'

        # ------------------------------------------------------------------- #
        # -------------------------------------------------- Element data --- #
        # ------------------------------------------------------------------- #
        num_elem_var = len(elem_var_names)
        self.fh.createDimension('num_elem_var', num_elem_var)
        dim = ('num_elem_var', 'len_string')
        self.fh.createVariable('name_elem_var', 'c', dim)
        for (i, name) in enumerate(elem_var_names):
            key = adjstr(name)
            self.fh.variables['name_elem_var'][i, :] = key
            self.fh.createVariable('vals_elem_var{0}eb1'.format(i+1),
                                   'f', ('time_step', 'num_el_in_blk1'))

        # ------------------------------------------------------------------- #
        # ----------------------------------------------------- Node data --- #
        # ------------------------------------------------------------------- #
        coordx = np.array([-0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5])
        coordy = np.array([-0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5])
        coordz = np.array([-0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5])
        vertices = [coordx, coordy, coordz]
        self.fh.createVariable('coor_names', 'c', ('num_dim', 'len_string'))
        for i in range(3):
            key = 'COORD' + 'XYZ'[i]
            self.fh.variables['coor_names'][i][:] = adjstr(key)
            self.fh.createVariable(key, 'f', ('num_nodes',))
            self.fh.variables[key][:] = vertices[i]

        self.fh.createDimension('num_nod_var', 3)
        dim = ('num_nod_var', 'len_string')
        self.fh.createVariable('name_nod_var', 'c', dim)
        for i in range(3):
            key = 'DISPL' + 'XYZ'[i]
            self.fh.variables['name_nod_var'][i, :] = adjstr(key)
            self.fh.createVariable('vals_nod_var{0}'.format(i+1), 'f',
                                   ('time_step', 'num_nodes'))

        # ------------------------------------------------------------------- #
        # ---------------------------------------------- Global variables --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension('num_glo_var', 3)
        dim = ('num_glo_var', 'len_string')
        self.fh.createVariable('name_glo_var', 'c', dim)
        for i in range(3):
            key = ['DTime', 'Step', 'Frame'][i]
            self.fh.variables['name_glo_var'][i, :] = adjstr(key)
        self.fh.createVariable('vals_glo_var', 'f', ('time_step', 'num_glo_var'))

        self.step_count = 0
        self.initialized = True
        return
Esempio n. 5
0
import numpy as np

from ase.test import NotAvailable

try:
    from scipy.io.netcdf import NetCDFFile
except ImportError:
    raise NotAvailable('Scipy too old')

# Write array
a1 = np.random.rand(5, 5)
a2 = a1 * 2 - 5
nc = NetCDFFile('test.nc', 'w')
nc.createDimension('dimx', a1.shape[0])
nc.createDimension('dimy', a1.shape[1])
nc.createVariable('matrix1', 'd', ('dimx', 'dimy'))[:] = a1
nc.createVariable('matrix2', 'd', ('dimx', 'dimy'))[:] = a2
nc.sync()
nc.close()

# Read array
nc = NetCDFFile('test.nc', 'r')
b1 = nc.variables['matrix1'][:]
b2 = nc.variables['matrix2'][:]

assert np.all(a1 == b1) and np.all(a2 == b2)
Esempio n. 6
0
class DatabaseFileWriter(DatabaseFile):
    mode = 'w'

    def __init__(self, filename):
        '''
        Notes
        -----
        The EXOFile class is an interface to the Exodus II api. Its methods
        are named after the analogous method from the Exodus II C bindings,
        minus the prefix 'ex_'.

        '''
        self.fh = NetCDFFile(filename, mode='w')
        self.jobid = os.path.splitext(os.path.basename(filename))[0]
        self.filename = filename

    def initialize(self, elem_var_names):
        # ------------------------------------------------------------------- #
        # -------------------------------- standard ExodusII dimensioning --- #
        # ------------------------------------------------------------------- #
        self.fh.floating_point_word_size = 4
        self.fh.version = 5.0300002
        self.fh.file_size = 1
        self.fh.api_version = 5.0300002
        self.fh.title = 'Matmodlab material point simulation'

        self.fh.filename = basename(self.filename)
        self.fh.jobid = self.jobid

        self.fh.createDimension('len_string', 33)
        self.fh.createDimension('len_line', 81)
        self.fh.createDimension('four', 4)

        self.fh.createDimension('num_dim', 3)
        self.fh.createDimension('num_node', 8)
        self.fh.createDimension('num_elem', 1)

        # node and element number maps
        self.fh.createVariable('nodes', 'i', ('num_node', ))
        self.fh.variables['nodes'][:] = range(1, 9)
        self.fh.createVariable('elements', 'i', ('num_elem', ))
        self.fh.variables['elements'][:] = [1]

        # ------------------------------------------------------------------- #
        # ---------------------------------------------------- QA records --- #
        # ------------------------------------------------------------------- #
        now = datetime.datetime.now()
        day = now.strftime("%m/%d/%y")
        hour = now.strftime("%H:%M:%S")
        self.fh.createDimension('num_qa_rec', 1)
        self.fh.createVariable('qa_records', 'c',
                               ('num_qa_rec', 'four', 'len_string'))
        self.fh.variables['qa_records'][0, 0, :] = adjstr('Matmodlab')
        self.fh.variables['qa_records'][0, 1, :] = adjstr(self.jobid)
        self.fh.variables['qa_records'][0, 2, :] = adjstr(day)
        self.fh.variables['qa_records'][0, 3, :] = adjstr(hour)

        # ------------------------------------------------------------------- #
        # ------------------------------------------------- record arrays --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension('time_step', None)
        self.fh.createVariable('time_whole', 'f', ('time_step', ))
        self.fh.createVariable('step_num', 'i', ('time_step', ))
        self.fh.createVariable('frame_num', 'i', ('time_step', ))

        # ------------------------------------------------------------------- #
        # --------------------------------------- element block meta data --- #
        # ------------------------------------------------------------------- #
        # block IDs - standard map
        self.fh.createDimension('num_el_blk', 1)
        self.fh.createVariable('eb_prop1', 'i', ('num_el_blk', ))
        self.fh.variables['eb_prop1'][:] = np.arange(1, dtype=np.int32) + 1
        self.fh.variables['eb_prop1'].name = 'ID'

        self.fh.createVariable('eb_status', 'i', ('num_el_blk', ))
        self.fh.variables['eb_status'][:] = np.ones(1, dtype=int)

        self.fh.createVariable('eb_names', 'c', ('num_el_blk', 'len_string'))
        self.fh.variables['eb_names'][0][:] = adjstr('ElementBlock1')

        # element map
        self.fh.createDimension('num_el_in_blk1', 1)
        self.fh.createDimension('num_nod_per_el1', 8)
        self.fh.createVariable('elem_map1', 'i', ('num_el_in_blk1', ))
        self.fh.variables['elem_map1'][:] = np.arange(1, dtype=np.int32) + 1

        # set up the element block connectivity
        dim = ('num_el_in_blk1', 'num_nod_per_el1')
        self.fh.createVariable('connect1', 'i', dim)
        self.fh.variables['connect1'][:] = np.arange(8, dtype=np.int32) + 1
        self.fh.variables['connect1'].elem_type = 'HEX'

        # ------------------------------------------------------------------- #
        # -------------------------------------------------- Element data --- #
        # ------------------------------------------------------------------- #
        num_elem_var = len(elem_var_names)
        self.fh.createDimension('num_elem_var', num_elem_var)
        dim = ('num_elem_var', 'len_string')
        self.fh.createVariable('name_elem_var', 'c', dim)
        for (i, name) in enumerate(elem_var_names):
            key = adjstr(name)
            self.fh.variables['name_elem_var'][i, :] = key
            self.fh.createVariable('vals_elem_var{0}eb1'.format(i + 1), 'f',
                                   ('time_step', 'num_el_in_blk1'))

        # ------------------------------------------------------------------- #
        # ----------------------------------------------------- Node data --- #
        # ------------------------------------------------------------------- #
        coordx = np.array([-0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5])
        coordy = np.array([-0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5])
        coordz = np.array([-0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5])
        vertices = [coordx, coordy, coordz]
        self.fh.createVariable('coor_names', 'c', ('num_dim', 'len_string'))
        for i in range(3):
            key = 'COORD' + 'XYZ'[i]
            self.fh.variables['coor_names'][i][:] = adjstr(key)
            self.fh.createVariable(key, 'f', ('num_nodes', ))
            self.fh.variables[key][:] = vertices[i]

        self.fh.createDimension('num_nod_var', 3)
        dim = ('num_nod_var', 'len_string')
        self.fh.createVariable('name_nod_var', 'c', dim)
        for i in range(3):
            key = 'DISPL' + 'XYZ'[i]
            self.fh.variables['name_nod_var'][i, :] = adjstr(key)
            self.fh.createVariable('vals_nod_var{0}'.format(i + 1), 'f',
                                   ('time_step', 'num_nodes'))

        # ------------------------------------------------------------------- #
        # ---------------------------------------------- Global variables --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension('num_glo_var', 3)
        dim = ('num_glo_var', 'len_string')
        self.fh.createVariable('name_glo_var', 'c', dim)
        for i in range(3):
            key = ['DTime', 'Step', 'Frame'][i]
            self.fh.variables['name_glo_var'][i, :] = adjstr(key)
        self.fh.createVariable('vals_glo_var', 'f',
                               ('time_step', 'num_glo_var'))

        self.step_count = 0
        self.initialized = True
        return
Esempio n. 7
0
class DatabaseFileWriter(_DatabaseFile):
    mode = 'w'
    def __init__(self, jobid, filename):
        '''
        Notes
        -----
        The EXOFile class is an interface to the Exodus II api. Its methods
        are named after the analogous method from the Exodus II C bindings,
        minus the prefix 'ex_'.

        '''
        self.jobid = jobid
        self.filename = filename
        self.fh = NetCDFFile(filename, mode='w')

    def initialize(self, glo_var_names, elem_var_names):
        """Initialize the output database

        Parameters
        ----------
        glo_var_names : list of string
        elem_var_names : list of string

        """
        # ------------------------------------------------------------------- #
        # -------------------------------- standard ExodusII dimensioning --- #
        # ------------------------------------------------------------------- #
        self.fh.floating_point_word_size = 4
        self.fh.version = 5.0300002
        self.fh.file_size = 1
        self.fh.api_version = 5.0300002
        self.fh.title = 'Matmodlab material point simulation'

        self.fh.filename = os.path.basename(self.filename)
        self.fh.jobid = self.jobid

        self.fh.createDimension('time_step', None)

        self.fh.createDimension('len_string', 33)
        self.fh.createDimension('len_line', 81)
        self.fh.createDimension('four', 4)

        self.fh.createDimension('num_dim', 3)
        self.fh.createDimension('num_nodes', 8)
        self.fh.createDimension('num_elem', 1)

        # ------------------------------------------------------------------- #
        # ---------------------------------------------------- QA records --- #
        # ------------------------------------------------------------------- #
        now = datetime.datetime.now()
        day = now.strftime("%m/%d/%y")
        hour = now.strftime("%H:%M:%S")
        self.fh.createDimension('num_qa_rec', 1)
        self.fh.createVariable('qa_records', 'c',
                               ('num_qa_rec', 'four', 'len_string'))
        self.fh.variables['qa_records'][0, 0, :] = adjstr('Matmodlab')
        self.fh.variables['qa_records'][0, 1, :] = adjstr(self.jobid)
        self.fh.variables['qa_records'][0, 2, :] = adjstr(day)
        self.fh.variables['qa_records'][0, 3, :] = adjstr(hour)

        # ------------------------------------------------------------------- #
        # ------------------------------------------------- record arrays --- #
        # ------------------------------------------------------------------- #
        self.fh.createVariable('time_whole', 'f', ('time_step',))

        # ------------------------------------------------------------------- #
        # --------------------------------------- element block meta data --- #
        # ------------------------------------------------------------------- #
        # block IDs - standard map
        self.fh.createDimension('num_el_blk', 1)
        self.fh.createVariable('eb_prop1', 'i', ('num_el_blk',))
        self.fh.variables['eb_prop1'][:] = np.arange(1, dtype=np.int32)+1
        self.fh.variables['eb_prop1'].name = 'ID'

        self.fh.createVariable('eb_status', 'i', ('num_el_blk',))
        self.fh.variables['eb_status'][:] = np.ones(1, dtype=int)

        self.fh.createVariable('eb_names', 'c', ('num_el_blk', 'len_string'))
        self.fh.variables['eb_names'][0][:] = adjstr('ElementBlock1')

        # element map
        self.fh.createDimension('num_el_in_blk1', 1)
        self.fh.createDimension('num_nod_per_el1', 8)
        self.fh.createVariable('elem_map1', 'i', ('num_elem',))
        self.fh.variables['elem_map1'][:] = np.arange(1, dtype=np.int32)+1

        # set up the element block connectivity
        dim = ('num_el_in_blk1', 'num_nod_per_el1')
        self.fh.createVariable('connect1', 'i', dim)
        self.fh.variables['connect1'][:] = np.arange(8, dtype=np.int32)+1
        self.fh.variables['connect1'].elem_type = 'HEX'

        # ------------------------------------------------------------------- #
        # -------------------------------------------------- Element data --- #
        # ------------------------------------------------------------------- #
        num_elem_var = len(elem_var_names)
        self.fh.createDimension('num_elem_var', num_elem_var)
        dim = ('num_elem_var', 'len_string')
        self.fh.createVariable('name_elem_var', 'c', dim)
        for (i, name) in enumerate(elem_var_names):
            key = adjstr(name)
            self.fh.variables['name_elem_var'][i, :] = key
            self.fh.createVariable('vals_elem_var{0}eb1'.format(i+1),
                                   'f', ('time_step', 'num_el_in_blk1'))
        self.fh.createVariable('elem_var_tab', 'i', ('num_elem_var',))
        elem_var_tab = np.ones(num_elem_var, dtype=np.int32)
        self.fh.variables['elem_var_tab'][:] = elem_var_tab


        # ------------------------------------------------------------------- #
        # ----------------------------------------------------- Node data --- #
        # ------------------------------------------------------------------- #
        vertices = [self.coordx, self.coordy, self.coordz]
        self.fh.createVariable('coor_names', 'c', ('num_dim', 'len_string'))
        for i in range(3):
            key = 'coord' + 'xyz'[i]
            self.fh.variables['coor_names'][i][:] = adjstr(key)
            self.fh.createVariable(key, 'f', ('num_nodes',))
            self.fh.variables[key][:] = vertices[i]

        self.fh.createDimension('num_nod_var', 3)
        dim = ('num_nod_var', 'len_string')
        self.fh.createVariable('name_nod_var', 'c', dim)
        for i in range(3):
            key = 'displ' + 'xyz'[i]
            self.fh.variables['name_nod_var'][i, :] = adjstr(key)
            self.fh.createVariable('vals_nod_var{0}'.format(i+1), 'f',
                                   ('time_step', 'num_nodes'))

        # ------------------------------------------------------------------- #
        # ---------------------------------------------- Global variables --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension('num_glo_var', len(glo_var_names))
        dim = ('num_glo_var', 'len_string')
        self.fh.createVariable('name_glo_var', 'c', dim)
        for (i, key) in enumerate(glo_var_names):
            self.fh.variables['name_glo_var'][i, :] = adjstr(key)
        self.fh.createVariable('vals_glo_var', 'f', ('time_step', 'num_glo_var'))

        self.initialized = True
        return

    def update_displ(self, elem_var_vals):
        """Update the node positions based on the deformation gradient"""
        elem_var_names = self.get_elem_var_names()
        names_and_cols = self.groupby_names(elem_var_names, disp=1)
        cols = names_and_cols['F']
        F = np.array(elem_var_vals[cols]).reshape((3,3))
        displ = []
        for i in range(8):
            X = np.array([self.coordx[i], self.coordy[i], self.coordz[i]])
            x = np.dot(F, X)
            displ.append(x)
        displ = np.array(displ).T
        return displ

    def save(self, time, glo_var_vals, elem_var_vals):
        """Save the step information to the database file

        Parameters
        ----------
        time : float
            Time at end of increment
        glo_var_vals : ndarray
            Global variable values, in same order put in to the database
        elem_var_vals : ndarray
            Element variable values, in same order put in to the database

        """

        # write time value
        count = len(self.fh.variables['time_whole'].data)
        self.fh.variables['time_whole'][count] = time
        self.fh.variables['vals_glo_var'][count] = glo_var_vals

        # get node and element fields
        elem_var_names = self.get_elem_var_names()
        if len(elem_var_names) != len(elem_var_vals):
            l1, l2 = len(elem_var_names), len(elem_var_vals)
            message = 'Expected {0} sdv got {1}'.format(l1, l2)
            raise RuntimeError(message)

        for (i, elem_var_val) in enumerate(elem_var_vals):
            key = 'vals_elem_var{0}eb1'.format(i+1)
            self.fh.variables[key][count] = elem_var_val

        nod_var_vals = self.update_displ(elem_var_vals)
        assert nod_var_vals.shape == (3, 8)
        for (i, nod_var_val) in enumerate(nod_var_vals):
            key = 'vals_nod_var{0}'.format(i+1)
            self.fh.variables[key][count] = nod_var_val

        return

    def close(self):
        """Close the database file"""
        self.fh.close()