Source code for schrodinger.application.matsci.stress_strain

"""
Utilities for stress strain.

Copyright Schrodinger, LLC. All rights reserved.
"""

import os
from collections import defaultdict

import numpy

from schrodinger.application.matsci import jobutils
from schrodinger.application.matsci import msprops

AXIS_HEADER = 'Axis %s'
AXIS_HEADERS = [AXIS_HEADER % axis for axis in 'abc']
AXIS_AVG = 'Average'

STRESS_EFF_XDATA = {'Effective': (0, 5), 'Normal': (1, 5), 'Transverse': (3, 5)}

RESIDUAL_STRAIN_Y_COL = 16

# Without and with residual strain
CSV_DATA_NCOLS = [16, 17]


[docs]def get_CSV_path(st): """ Return the CSV path from the structure. :type st: schrodinger.structure.Structure :param st: the structure :rtype: str or None :return: the CSV path or None if one can not be found """ cms_fn = st.property.get(msprops.ORIGINAL_CMS_PROP, '') if cms_fn.endswith('-out.cms'): csv_fn = cms_fn.replace('-out.cms', '.csv') source_path = jobutils.get_source_path(st) csv_fn = os.path.join(source_path, csv_fn) if os.path.exists(csv_fn): return csv_fn
[docs]def parse_CSV(csv_fn): """ Parse CSV file from the calculation. :type csv_fn: str :param csv_fn: Path to CSV file :rtype: dict, dict :return: Both dictionaries keys are main axis name. First dictionary with values is the associated data for the axis and second dictionary the header string for the axis. :raise ValueError: If parsing of CSV file fails """ data = {} headers = defaultdict(str) start_reading = False with open(csv_fn) as csv_fh: for line in csv_fh: if 'Main axis =' in line: tmp = line.split(',') direction = AXIS_HEADER % tmp[1].strip() if direction not in AXIS_HEADERS: raise ValueError('Unknown axis: %s' % direction) start_reading = True if start_reading: headers[direction] += line if 'eps_eff' in line: while True: line = csv_fh.readline().strip() if not line: break tmp = list(map(float, line.split(','))) if len(tmp) not in CSV_DATA_NCOLS: raise ValueError('Different CSV format.') if direction not in data: data[direction] = numpy.array([tmp]) else: data[direction] = numpy.append(data[direction], [tmp], axis=0) if not data: raise ValueError('Could not parse CSV file.') nkeys = len(data.keys()) if nkeys == 1: return data, headers avg_data = None for key, val in data.items(): if avg_data is None: avg_data = numpy.array(val) else: avg_data += numpy.array(val) avg_data /= nkeys data[AXIS_AVG] = avg_data return data, headers