Example #1
0
    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 = splitext(basename(filename))[0]
        self.filename = filename

        self.initialized = False
        self.viewable = False
Example #2
0
def read_exodus_legacy(filename, variables=None, disp=1, blk_num=1, elem_num=1):
    '''Read the specified variables from the exodus file in filepath

    '''
    if not isfile(filename):
        raise IOError('{0}: no such file'.format(filename))

    fh = NetCDFFile(filename, 'r')

    # global/element vars and mapping
    num_glo_var = fh.dimensions.get('num_glo_var', 0)
    if num_glo_var:
        name_glo_var = exodus.stringify(fh.variables['name_glo_var'].data)
        gmap = dict(zip(name_glo_var, range(len(name_glo_var))))

    name_elem_var = exodus.stringify(fh.variables['name_elem_var'].data)
    emap = dict(zip(name_elem_var, range(len(name_elem_var))))

    # retrieve the data from the database
    head = ['TIME']
    if num_glo_var:
        head.extend([H.upper() for H in name_glo_var])
    head.extend([H.upper() for H in name_elem_var])

    data = []
    times = fh.variables['time_whole'].data.flatten()
    for (i, time) in enumerate(times):
        row = [time]
        if num_glo_var:
            vals_glo_var = fh.variables['vals_glo_var'].data[i]
            for var in name_glo_var:
                var_num = gmap[var]
                try: row.append(vals_glo_var[var_num])
                except KeyError: continue
        for var in name_elem_var:
            var_num = emap[var]+1
            name = 'vals_elem_var{0}eb{1}'.format(var_num, blk_num)
            row.append(fh.variables[name].data[i, elem_num-1])
        data.append(row)
    fh.close()
    data = np.asarray(data)
    if len(head) != data.shape[1]:
        raise ValueError('inconsistent data')

    data = np.array(data)

    if variables is not None:
        variables = [x.upper() for x in variables]
        idx = []
        for name in variables:
            try:
                idx.append(head.index(name))
            except IndexError:
                raise KeyError('{0} not in output database'.format(name))
        head = [head[i] for i in idx]
        data = data[:, idx]

    if disp:
        return head, data

    return data
Example #3
0
def read_exodus_legacy(filename,
                       variables=None,
                       disp=1,
                       blk_num=1,
                       elem_num=1):
    '''Read the specified variables from the exodus file in filepath

    '''
    if not isfile(filename):
        raise IOError('{0}: no such file'.format(filename))

    fh = NetCDFFile(filename, 'r')

    # global/element vars and mapping
    num_glo_var = fh.dimensions.get('num_glo_var', 0)
    if num_glo_var:
        name_glo_var = exodus.stringify(fh.variables['name_glo_var'].data)
        gmap = dict(zip(name_glo_var, range(len(name_glo_var))))

    name_elem_var = exodus.stringify(fh.variables['name_elem_var'].data)
    emap = dict(zip(name_elem_var, range(len(name_elem_var))))

    # retrieve the data from the database
    head = ['TIME']
    if num_glo_var:
        head.extend([H.upper() for H in name_glo_var])
    head.extend([H.upper() for H in name_elem_var])

    data = []
    times = fh.variables['time_whole'].data.flatten()
    for (i, time) in enumerate(times):
        row = [time]
        if num_glo_var:
            vals_glo_var = fh.variables['vals_glo_var'].data[i]
            for var in name_glo_var:
                var_num = gmap[var]
                try:
                    row.append(vals_glo_var[var_num])
                except KeyError:
                    continue
        for var in name_elem_var:
            var_num = emap[var] + 1
            name = 'vals_elem_var{0}eb{1}'.format(var_num, blk_num)
            row.append(fh.variables[name].data[i, elem_num - 1])
        data.append(row)
    fh.close()
    data = np.asarray(data)
    if len(head) != data.shape[1]:
        raise ValueError('inconsistent data')

    data = np.array(data)

    if variables is not None:
        variables = [x.upper() for x in variables]
        idx = []
        for name in variables:
            try:
                idx.append(head.index(name))
            except IndexError:
                raise KeyError('{0} not in output database'.format(name))
        head = [head[i] for i in idx]
        data = data[:, idx]

    if disp:
        return head, data

    return data
Example #4
0
 def __init__(self, filename):
     if not isfile(filename):
         raise IOError('no such file: {0}'.format(repr(filename)))
     self.filename = filename
     self.fh = NetCDFFile(filename, mode='r')
     self.read()
Example #5
0
class EXOFileWriter(_EXOFile):
    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 = splitext(basename(filename))[0]
        self.filename = filename

        self.initialized = False
        self.viewable = False

    def update(self):
        pass

    def __lshift__(self, u):
        if not self.initialized:
            self.initialize(*u.alpha())
        for step in u.steps.values():
            self.put_step(step)
        self.close()

    def initialize(self, dimension, num_node, nodes, vertices,
                   num_elem, elements, connect, element_blocks, field_outputs,
                   node_sets=None, side_sets=None):
        '''Writes the initialization parameters to the EXODUS II file'''

        # ------------------------------------------------------------------- #
        # -------------------------------- 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 = 'finite element simulation'

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

        self.fh.createDimension(DIM_LEN_STRING, 33)
        self.fh.createDimension(DIM_LEN_LINE, 81)
        self.fh.createDimension(DIM_FOUR, 4)

        self.fh.createDimension(DIM_NUM_DIM, dimension)
        self.fh.createDimension(DIM_NUM_NODES, num_node)
        self.fh.createDimension(DIM_NUM_ELEM, num_elem)

        # node and element number maps
        self.fh.createVariable(VAR_NODES, INT, (DIM_NUM_NODES,))
        self.fh.variables[VAR_NODES][:] = nodes
        self.fh.createVariable(VAR_ELEMENTS, INT, (DIM_NUM_ELEM,))
        self.fh.variables[VAR_ELEMENTS][:] = elements

        # ------------------------------------------------------------------- #
        # ---------------------------------------------------- QA records --- #
        # ------------------------------------------------------------------- #
        now = datetime.datetime.now()
        day = now.strftime("%m/%d/%y")
        hour = now.strftime("%H:%M:%S")
        self.fh.createDimension(DIM_NUM_QA, 1)
        self.fh.createVariable(VAR_QA_RECORDS, CHAR,
                               (DIM_NUM_QA, DIM_FOUR, DIM_LEN_STRING))
        self.fh.variables[VAR_QA_RECORDS][0, 0, :] = adjstr('femlib')
        self.fh.variables[VAR_QA_RECORDS][0, 1, :] = adjstr(self.jobid)
        self.fh.variables[VAR_QA_RECORDS][0, 2, :] = adjstr(day)
        self.fh.variables[VAR_QA_RECORDS][0, 3, :] = adjstr(hour)

        # ------------------------------------------------------------------- #
        # ------------------------------------------------- record arrays --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension(DIM_TIME_STEP, None)
        self.fh.createVariable(VAR_TIME_WHOLE, FLOAT, (DIM_TIME_STEP,))
        self.fh.createVariable(VAR_STEP_NUM, INT, (DIM_TIME_STEP,))
        self.fh.createDimension(DIM_MAX_STEPS, 100) # arbitrary number
        self.fh.createVariable(VAR_STEP_NAMES, CHAR,
                               (DIM_MAX_STEPS, DIM_LEN_STRING))

        self.step_count = 0

        # ------------------------------------------------------------------- #
        # ------------------------------------------------- field outputs --- #
        # ------------------------------------------------------------------- #
        fields = field_outputs.values()

        nev = sum([len(fo.keys) for fo in fields if fo.position==ELEMENT])
        self.fh.createDimension(DIM_NUM_ELEM_VAR, nev)
        self.fh.createVariable(VAR_NAME_ELEM_VAR, CHAR,
                               (DIM_NUM_ELEM_VAR, DIM_LEN_STRING))
        self.fh.createVariable(VAR_FIELD_ELEM_VAR, INT, (DIM_NUM_ELEM_VAR,))

        nnv = sum([len(fo.keys) for fo in fields if fo.position==NODE])
        self.fh.createDimension(DIM_NUM_NOD_VAR, nnv)
        self.fh.createVariable(VAR_NAME_NOD_VAR, CHAR,
                               (DIM_NUM_NOD_VAR, DIM_LEN_STRING))
        self.fh.createVariable(VAR_FIELD_NOD_VAR, INT, (DIM_NUM_NOD_VAR,))

        self.fh.createDimension(DIM_NUM_FIELD, len(fields))
        self.fh.createVariable(VAR_FO_PROP1, INT, (DIM_NUM_FIELD,))
        self.fh.createVariable(VAR_FO_NAMES, CHAR,
                               (DIM_NUM_FIELD, DIM_LEN_STRING))
        self.fh.createVariable(VAR_FO_TYPES, INT, (DIM_NUM_FIELD,))
        self.fh.createVariable(VAR_FO_VALINV, CHAR,
                               (DIM_NUM_FIELD, DIM_LEN_STRING))
        self.fh.variables[VAR_FO_PROP1][:] = np.arange(len(fields)) + 1

        i = j = 0
        for (n, fo) in enumerate(fields):
            self.fh.variables[VAR_FO_NAMES][n, :] = adjstr(fo.name)
            self.fh.variables[VAR_FO_TYPES][n] = fo.type
            string = adjstr(asstring(fo.valid_invariants, 0))
            self.fh.variables[VAR_FO_VALINV][n] = string
            for key in fo.keys:
                key = adjstr(key)
                if fo.position == ELEMENT:
                    self.fh.variables[VAR_NAME_ELEM_VAR][i, :] = key
                    self.fh.variables[VAR_FIELD_ELEM_VAR][i] = n
                    i += 1
                elif fo.position == NODE:
                    self.fh.variables[VAR_NAME_NOD_VAR][j, :] = key
                    self.fh.variables[VAR_FIELD_NOD_VAR][j] = n
                    j += 1
                else:
                    raise ValueError('unknown field output position')

        # ------------------------------------------------------------------- #
        # -------------------------------------------- node set meta data --- #
        # ------------------------------------------------------------------- #
        nns = 0 if node_sets is None else len(node_sets)
        if nns:
            self.fh.createDimension(DIM_NUM_NODE_SETS, nns)
            # node set IDs - standard map
            prop1 = np.arange(nns, dtype=np.int32) + 1
            self.fh.createVariable(VAR_NS_PROP1, INT, (DIM_NUM_NODE_SETS,))
            self.fh.variables[VAR_NS_PROP1][:] = prop1
            self.fh.variables[VAR_NS_PROP1].name = 'ID'
            self.fh.createVariable(VAR_NS_NAMES, CHAR,
                                   (DIM_NUM_NODE_SETS, DIM_LEN_STRING))
            for (i, ns) in enumerate(node_sets, start=1):
                self.fh.variables[VAR_NS_NAMES][i-1][:] = adjstr(ns.name)
                self.fh.createDimension(DIM_NUM_NOD_NS(i), len(ns.nodes))
                self.fh.createVariable(VAR_NODE_NS(i), INT, (DIM_NUM_NOD_NS(i),))
                self.fh.variables[VAR_NODE_NS(i)][:] = ns.nodes

        # ------------------------------------------------------------------- #
        # -------------------------------------------- side set meta data --- #
        # ------------------------------------------------------------------- #
        nss = 0 if side_sets is None else len(side_sets)
        if nss:
            self.fh.createDimension(DIM_NUM_SIDE_SETS, nss)
            # side set IDs - standard map
            prop1 = np.arange(nss, dtype=np.int32) + 1
            self.fh.createVariable(VAR_SS_PROP1, INT, (DIM_NUM_SIDE_SETS,))
            self.fh.variables[VAR_SS_PROP1][:] = prop1
            self.fh.variables[VAR_SS_PROP1].name = 'ID'
            self.fh.createVariable(VAR_SS_NAMES, CHAR,
                                   (DIM_NUM_SIDE_SETS, DIM_LEN_STRING))
            for (i, ss) in enumerate(side_sets, start=1):
                self.fh.variables[VAR_SS_NAMES][i-1][:] = adjstr(ss.name)
                self.fh.createDimension(DIM_NUM_SIDE_SS(i), len(ss.sides))
                self.fh.createVariable(VAR_SIDE_SS(i), INT, (DIM_NUM_SIDE_SS(i),))
                self.fh.variables[VAR_SIDE_SS(i)][:] = ss.sides
                self.fh.createVariable(VAR_ELEM_SS(i), INT, (DIM_NUM_ELEM_SS(i),))
                self.fh.variables[VAR_ELEM_SS(i)][:] = ss.elements

        # ------------------------------------------------------------------- #
        # --------------------------------------- element block meta data --- #
        # ------------------------------------------------------------------- #
        # block IDs - standard map
        num_el_blk = len(element_blocks)
        self.fh.createDimension(DIM_NUM_EL_BLK, num_el_blk)

        prop1 = np.arange(num_el_blk, dtype=np.int32) + 1
        self.fh.createVariable(VAR_EB_PROP1, INT, (DIM_NUM_EL_BLK,))
        self.fh.variables[VAR_EB_PROP1][:] = prop1
        self.fh.variables[VAR_EB_PROP1].name = 'ID'

        self.fh.createVariable(VAR_EB_STATUS, INT, (DIM_NUM_EL_BLK,))
        self.fh.variables[VAR_EB_STATUS][:] = np.ones(num_el_blk, dtype=int)

        self.fh.createVariable(VAR_EB_NAMES, CHAR, (DIM_NUM_EL_BLK, DIM_LEN_STRING))
        for (i, block) in enumerate(element_blocks, start=1):
            self.fh.variables[VAR_EB_NAMES][i-1][:] = adjstr(block.name)

            # block connect
            ij = [elements.index(e) for e in block.elements]
            block_conn = np.array([[n for n in c if n >= 0] for c in connect[ij]])

            ne, nn = block_conn.shape
            d1, d2 = DIM_NUM_EL_IN_BLK(i), DIM_NUM_NOD_PER_EL(i)
            self.fh.createDimension(d1, ne)
            self.fh.createDimension(d2, nn)

            # element map
            elem_map = VAR_ELEM_MAP(i)
            self.fh.createVariable(elem_map, INT, (d1,))
            self.fh.variables[elem_map][:] = block.elements

            # set up the element block connectivity
            self.fh.createVariable(VAR_CONNECT(i), INT, (d1, d2))
            self.fh.variables[VAR_CONNECT(i)][:] = block_conn

            # element type
            if dimension == 1:
                elem_type = 'TRUSS'
            elif dimension == 2:
                if nn == 3:
                    elem_type = 'TRI'
                elif nn == 4:
                    elem_type = 'QUAD'
            elif dimension == 3:
                if nn in (4, 6):
                    elem_type = 'TET'
                elif nn in (8, 20):
                    elem_type = 'HEX'

            self.fh.variables[VAR_CONNECT(i)].elem_type = elem_type

            for j in range(1, nev+1):
                self.fh.createVariable(VALS_ELEM_VAR(j,i),
                                       FLOAT, (DIM_TIME_STEP, d1))

        # ------------------------------------------------------------------- #
        # ------------------------------------------------ node meta data --- #
        # ------------------------------------------------------------------- #
        if len(vertices.shape) == 1:
            vertices = np.reshape(vertices, (num_node, dimension))
        self.fh.createVariable(VAR_COOR_NAMES, CHAR, (DIM_NUM_DIM, DIM_LEN_STRING))
        for i in range(dimension):
            self.fh.variables[VAR_COOR_NAMES][i][:] = adjstr(VAR_COOR_NAME(i))
            self.fh.createVariable(VAR_COOR_NAME(i), FLOAT, (DIM_NUM_NODES,))
            self.fh.variables[VAR_COOR_NAME(i)][:] = vertices[:, i]

        for j in range(1, nnv+1):
            self.fh.createVariable(VALS_NOD_VAR(j), FLOAT,
                                   (DIM_TIME_STEP, DIM_NUM_NODES))

        # ------------------------------------------------------------------- #
        # ------------------------------------ global variables meta data --- #
        # ------------------------------------------------------------------- #
        self.fh.createDimension(DIM_NUM_GLO_VAR, 1)
        self.fh.createVariable(VALS_GLO_VAR, FLOAT, (DIM_TIME_STEP, ))

        self.initialized = True
        return

    def put_steps(self, steps):
        for step in steps:
            self.put_step(step)
        self.close()

    def put_step(self, step):

        assert self.initialized

        self.fh.variables[VAR_STEP_NAMES][self.step_count] = adjstr(step.name)

        for frame in step.frames:

            # write time value
            count = len(self.fh.variables[VAR_TIME_WHOLE].data)
            self.fh.variables[VAR_TIME_WHOLE][count] = frame.value
            self.fh.variables[VAR_STEP_NUM][count] = self.step_count
            self.fh.variables[VALS_GLO_VAR][count] = 0.

            # get node and element fields
            fields = frame.field_outputs.values()
            fo_n = [fo for fo in fields if fo.position==NODE]
            fo_e = [fo for fo in fields if fo.position==ELEMENT]

            # write out node fields
            a = stringify(self.fh.variables[VAR_NAME_NOD_VAR])
            for fo in fo_n:
                data = fo.get_data()
                if len(data.shape) == 1:
                    data = data.reshape(-1, 1)
                for (k, key) in enumerate(fo.keys):
                    i = a.index(key) + 1
                    self.fh.variables[VALS_NOD_VAR(i)][count] = data[:, k]

            # write element data to the appropriate element block
            a = stringify(self.fh.variables[VAR_NAME_ELEM_VAR])
            ebs = stringify(self.fh.variables[VAR_EB_NAMES])
            for fo in fo_e:
                for (j, eb) in enumerate(ebs, start=1):
                    bd = fo.get_data(block=eb)
                    if len(bd.shape) == 1:
                        bd = bd.reshape(-1, 1)
                    for (k, key) in enumerate(fo.keys):
                        i = a.index(key) + 1
                        self.fh.variables[VALS_ELEM_VAR(i,j)][count] = bd[:, k]

        self.step_count += 1
        return