import warnings
import numpy as np
[docs]
class Responses:
"""Defines SOL 200 responses from the R1TABRG table"""
def __init__(self):
self.convergence_data = None
self.desvars = None
self.dscmcol = None
self.weight_response = None
self.displacement_response = None
self.stress_response = None
self.strain_response = None
self.force_response = None
self.composite_stress_response = None
self.composite_strain_response = None
self.flutter_response = None
self.fractional_mass_response = None
self.normalized_mass_density = None
[docs]
def get_stats(self, short: bool=False) -> str:
objects = [
self.convergence_data,
self.desvars,
self.dscmcol,
self.displacement_response,
self.weight_response,
self.stress_response,
self.strain_response,
self.force_response,
self.composite_stress_response,
self.composite_strain_response,
self.flutter_response,
self.fractional_mass_response,
self.normalized_mass_density,
]
msg = []
for obj in objects:
if obj is not None:
if isinstance(obj, dict):
for key, obji in dict.items():
msg += obji.get_stats(short=short) + '\n'
else:
msg += obj.get_stats(short=short) + '\n'
return msg
[docs]
def get_table_types(self):
tables = [
'convergence_data', 'desvars', 'dscmcol',
'displacement_response', 'weight_response',
'stress_response', 'strain_response', 'force_response',
'composite_stress_response', 'composite_strain_response', 'flutter_response',
'fractional_mass_response', 'normalized_mass_density',
]
return ['responses.' + table for table in tables
#if getattr(self, table) is not None
]
def __repr__(self) -> str:
msg = 'Responses:\n - ' + '\n - '.join(self.get_table_types()).rstrip('\n -')
return msg
[docs]
class WeightResponse:
def __init__(self):
self.n = 1
self._n = 0
self._itable = 0
self.is_built = False
self.internal_id = []
[docs]
def add_from_op2(self, out, log):
"""
Weight Response
1 IRID I Internal response identification number
2 RID I External response identification number
3 TYPE(C) I Response type
4 LABEL(2) CHAR4 Label
6 REGION I Region identifier
7 SCID I Subcase identification number
8 UNDEF(2) I Not used
10 SEID I Superelement identification number or ALL
11 UNDEF(2) I Not used
13 UNDEF I Not used
14 TYFLG I Flag to indicate how response is referenced
15 SEID I Superelement identificaiton number
---> 3i 8s 7i 3i
# ----- WEIGHT RESPONSE -----
# ---------------------------------------------------------------------------------
# INTERNAL DRESP1 RESPONSE ROW COLUMN LOWER INPUT OUTPUT UPPER
# ID ID LABEL ID ID BOUND VALUE VALUE BOUND
# ---------------------------------------------------------------------------------
# 1 1 WEIGHT 3 3 N/A 2.9861E+05 2.9852E+05 N/A
# ? ? ? LABEL? ? ? ROW_ID? COL_ID? ? ? ? ? ? ?
#(1, 1, 1, 'WEIGHT ', 0, 1011, 3, 3, 0, 0, 0, 0, 0, 0)
#(1, 1000, 1, 'W ', 0, 1, 3, 3, 0, 0, 0, 0, 0, 0)
#
# per dev forum; 538976288 is probably just ' '
#(1, 1, 1, 'WEIGHT ', 0, 1, 3, 3, 0, 0, 538976288, 538976288, 0, 0)
"""
# F:\work\pyNastran\examples\Dropbox\move_tpl\mbcgen.op2
# (1, 15, 1, 'W ', -1, 1, 3, 3, 0, 0, 0, 0, 0, 10)
# F:\work\pyNastran\examples\Dropbox\move_tpl\i2002.op2
# (20, 15, 1, 'W ', -1, 1, 3, 3, 0, 0, 0, 0, 0, 20)
# F:\work\pyNastran\examples\Dropbox\move_tpl\edr2n.op2
# (1, 201, 1, 'WEIGHT ', -1, 0, 3, 3, 0, 0, 0, 0, 0, 100)
# F:\work\pyNastran\examples\Dropbox\move_tpl\ss200m2.op2
# (1, 1, 1, 'W ', 0, 30001, 3, 3, 0, 0, 0, 0, 0, 300)
# F:\work\pyNastran\examples\Dropbox\move_tpl\mcso43.op2
# (1, 10, 1, 'W ', 0, 1, 3, 3, 0, 0, 0, 0, 1, 0)
#--------------------------
# common
#
# per the R1TAB DMAP page:
# all indicies are downshift by 1
# indices above out[3] are off by +2 because of the 2 field response_label
internal_id = out[0]
dresp_id = out[1]
response_type = out[2]
response_label = out[3].strip()
# -1 for 2 field wide response_label
region = out[4]
subcase = out[5]
type_flag = out[12] # no meaning per MSC DMAP 2005
seid = out[13]
#--------------------------------------------------
#row_id = out[4]
# these should be blank?
row_id = out[6]
column_id = out[7]
seid_weight = out[8]
if np.abs(out[8:-1]).sum() != 0.0:
msg = 'WEIGHT response sum error; out=%s 8=%s' % (out, out[8:-1])
log.warning(msg)
assert seid == out[-1]
#assert out[-1] in [0, 1, 2, 3, 4, 5, 10, 20, 100, 200, 300], out
#dunno_8 = out[8]
#dunno_9 = out[9]
#dunno_10 = out[10]
#dunno_11 = out[11]
#dunno_12 = out[12]
#msg = ('WEIGHT - response_type=%r response_label=%r row_id=%r column_id=%r '
#'6=%r 7=%r 8=%r 9=%r 10=%r 11=%r 12=%r seid=%r' % (
#response_type, response_label, row_id, column_id,
#dunno_6, dunno_7, dunno_8, dunno_9, dunno_10, dunno_11, dunno_12, seid))
#out = unpack(self._endian + b'iii 8s iiff f fffff', data)
#msg = 'WEIGHT - label=%r region=%s subcase=%s row_id=%r column_id=%r' % (
#response_label, region, subcase, row_id, column_id)
self.append(internal_id, dresp_id, response_label, region,
subcase, type_flag, seid,
row_id, column_id)
#print(msg)
#self.log.debug(msg)
[docs]
def append(self, internal_id, dresp_id, response_label, region,
subcase, type_flag, seid,
row_id, column_id):
self.internal_id.append(internal_id)
#self.response_label.append(response_label)
#self.subcase.append(subcase)
#self.mode.append(mode)
#self.mach.append(mach)
#self.velocity.append(velocity)
#self.density.append(density)
#self.flutter_id.append(flutter_id)
#self.subcase.append(subcase)
self._n += 1
def __repr__(self):
msg = 'responses.WeightResponse()\n'
msg += ' n=%s\n' % self.n
#msg += ' velocity=%s\n' % (velocity)
return msg
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.weight_response (%s)\n' % (self.n)
return self.__repr__() + '\n'
[docs]
class PropertyResponse:
"""common class for StressResponse, StrainResponse, and ForceResponse"""
def __init__(self):
self.n = 1
self._n = 0
self._itable = 0
self.is_built = False
self.internal_id = []
self.response_label = []
self.subcase = []
self.item_code = []
self.pid = []
[docs]
def append(self, internal_id, dresp_id, response_label, region, subcase, type_flag, seid,
item_code, pid):
assert isinstance(response_label, str), response_label
self.internal_id.append(internal_id)
self.response_label.append(response_label)
self.subcase.append(subcase)
self.item_code.append(item_code)
self.pid.append(pid)
self._n += 1
def __repr__(self):
name = self.__class__.__name__
msg = 'responses.%s()\n' % name
msg += ' internal_id = %s\n' % np.array(self.internal_id)
msg += ' response_label = %s\n' % np.array(self.response_label)
msg += ' subcase = %s\n' % np.array(self.subcase)
msg += ' item_code = %s\n' % np.array(self.item_code)
msg += ' pid = %s\n' % np.array(self.pid)
return msg
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.%s_response (%s)\n' % (self.name, self.n)
return self.__repr__() + '\n'
[docs]
class FractionalMassResponse:
name = 'fractional_mass'
def __init__(self):
self.n = 1
self._n = 0
self._itable = 0
self.is_built = False
self.internal_id = []
self.dresp_id = []
self.region = []
self.response_label = []
self.subcase = []
self.type_flag = []
self.seid = []
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.%s_response (%s)\n' % (self.name, self.n)
return self.__repr__() + '\n'
[docs]
def append(self, internal_id, dresp_id, response_label, region,
subcase, type_flag, seid):
self.internal_id.append(internal_id)
self.dresp_id.append(dresp_id)
self.region.append(region)
self.response_label.append(response_label)
self.subcase.append(subcase)
self.type_flag.append(type_flag)
self.seid.append(seid)
self._n += 1
def __repr__(self):
msg = 'FractionalMassResponse()\n'
msg += ' response_label=%s\n' % np.array(self.response_label)
msg += ' internal_id=%s\n' % np.array(self.internal_id)
msg += ' region=%s\n' % np.array(self.region)
msg += ' subcase=%s\n' % np.array(self.subcase)
msg += ' type_flag=%s\n' % np.array(self.type_flag)
msg += ' seid=%s\n' % np.array(self.seid)
return msg
[docs]
class DisplacementResponse:
name = 'displacement'
def __init__(self):
self.n = 1
self._n = 0
self._itable = 0
self.is_built = False
self.internal_id = []
self.dresp_id = []
self.region = []
self.response_label = []
self.subcase = []
self.nid = []
self.component = []
self.type_flag = []
self.seid = []
[docs]
def append(self, internal_id, dresp_id, response_label, region,
subcase, type_flag, seid,
nid, component):
self.internal_id.append(internal_id)
self.dresp_id.append(dresp_id)
self.region.append(region)
self.response_label.append(response_label)
self.subcase.append(subcase)
self.nid.append(nid)
self.component.append(component)
self.type_flag.append(type_flag)
self.seid.append(seid)
self._n += 1
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.%s_response (%s)\n' % (self.name, self.n)
return self.__repr__() + '\n'
def __repr__(self):
msg = 'DisplacementResponse()\n'
msg += ' response_label=%s\n' % np.array(self.response_label)
msg += ' nid=%s\n' % np.array(self.nid)
msg += ' component=%s\n' % np.array(self.component)
msg += ' internal_id=%s\n' % np.array(self.internal_id)
msg += ' subcase=%s\n' % np.array(self.subcase)
msg += ' type_flag=%s\n' % np.array(self.type_flag)
msg += ' seid=%s\n' % np.array(self.seid)
return msg
[docs]
class ForceResponse(PropertyResponse):
name = 'force'
[docs]
class StressResponse(PropertyResponse):
name = 'stress'
[docs]
class StrainResponse(PropertyResponse):
name = 'strain'
[docs]
class FlutterResponse:
name = 'flutter'
def __init__(self):
self.n = 1
self._n = 0
self._itable = 0
self.is_built = False
self.internal_id = []
self.response_label = []
self.subcase = []
self.mode = []
self.mach = []
self.velocity = []
self.density = []
self.flutter_id = []
self.subcase = []
[docs]
def append(self, internal_id, dresp_id, response_label, region, subcase, type_flag, seid,
mode, mach, velocity, density, flutter_id):
self.internal_id.append(internal_id)
self.response_label.append(response_label)
self.subcase.append(subcase)
self.mode.append(mode)
self.mach.append(mach)
self.velocity.append(velocity)
self.density.append(density)
self.flutter_id.append(flutter_id)
self._n += 1
def __repr__(self):
msg = 'FlutterResponse()\n'
msg += ' velocity=%s\n' % np.array(self.velocity)
return msg
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.%s_response (%s)\n' % (self.name, self.n)
return self.__repr__() + '\n'
[docs]
class DSCMCOL:
"""
' ----- IDENTIFICATION OF COLUMNS IN THE DESIGN SENSITIVITY -----'
' ----- MATRIX THAT ARE ASSOCIATED WITH DRESP1 ENTRIES -----'
''
''
' ----- WEIGHT/VOLUME RESPONSES -----'
' ------------------------------------------'
' COLUMN DRESP1 RESPONSE'
' NO. ENTRY ID TYPE '
' ------------------------------------------'
' 1 1 WEIGHT '
''
''
' ----- STATICS RESPONSES -----'
' ------------------------------------------------------------------------------------------------------------------------'
' COLUMN DRESP1 RESPONSE GRID/ELM VIEW COMPONENT SUB PLY '
' NO. ENTRY ID TYPE ID ELM ID NO. CASE NO. '
#' COLUMN DRESP1 RESPONSE GRID/ELM VIEW COMPONENT SUB '
#' NO. ENTRY ID TYPE ID ELM ID NO. CASE '
' ------------------------------------------------------------------------------------------------------------------------'
' 2 2 STRESS 1 5 1'
' 3 2 STRESS 3 5 1'
' 4 10501 DISP 100 1 1'
''
''
#' ---- RETAINED DRESP2 RESPONSES ----'
#''
#' ----------------------------------------------------------------------------------------------------------'
#' INTERNAL DRESP2 RESPONSE EQUATION LOWER UPPER '
#' ID ID LABEL ID BOUND VALUE BOUND '
#' ----------------------------------------------------------------------------------------------------------'
#' 3 105 DISPMAG 3 -1.0000E+20 9.4677E-05 2.5000E-04'
' ----- IDENTIFICATION OF COLUMNS IN THE DESIGN SENSITIVITY -----'
' ----- MATRIX THAT ARE ASSOCIATED WITH DRESP2 ENTRIES -----'
''
''
' ----------------------------------------------------------'
' COLUMN DRESP2 SUB FREQ/ '
' NO. ENTRY ID CASE TIME '
' ----------------------------------------------------------'
' 96 103 0 0.00000'
' 97 104 0 0.00000'
' 100 105 1'
"""
def __init__(self, responses):
"""internal_response_id = iresponse + 1 = column in DSCM2"""
self.responses = responses
#def write_f06(self):
#msg = [
#' ----- IDENTIFICATION OF COLUMNS IN THE DESIGN SENSITIVITY -----'
#' ----- MATRIX THAT ARE ASSOCIATED WITH DRESP1 ENTRIES -----'
#''
#''
#' ----- WEIGHT/VOLUME RESPONSES -----'
#' ------------------------------------------'
#' COLUMN DRESP1 RESPONSE'
#' NO. ENTRY ID TYPE '
#' ------------------------------------------'
#' 1 1 WEIGHT '
#''
#''
#' ----- STATICS RESPONSES -----'
#' ------------------------------------------------------------------------------------------------------------------------'
#' COLUMN DRESP1 RESPONSE GRID/ELM VIEW COMPONENT SUB '
#' NO. ENTRY ID TYPE ID ELM ID NO. CASE '
#' ------------------------------------------------------------------------------------------------------------------------'
#' 2 2 STRESS 1 5 1'
#' 3 2 STRESS 3 5 1'
#''
#''
#' ----- EIGENVALUE RESPONSES -----'
#' --------------------------------------------------------------------------'
#' COLUMN DRESP1 RESPONSE MODE SUB '
#' NO. ENTRY ID TYPE NO. CASE '
#' --------------------------------------------------------------------------'
#' 2 4 FREQ 1 1'
#]
#return msg
[docs]
def get_responses_by_group(self):
response_groups_order = [
'weight_volume', 'static', 'eigenvalue',
'buckling',
'???', 'psd',
'2',
]
responses_groups = {key: [] for key in response_groups_order}
response_name_to_group = {
'weight': 'weight_volume',
'volume': 'weight_volume',
'static stress': 'static',
'static displacement': 'static',
'static strain': 'static',
'composite failure': 'static',
'composite strain': 'static',
'buckling': 'buckling',
'psd displacement': 'psd',
'psd acceleration': 'psd',
'normal modes': 'eigenvalue',
'equivalent radiated power': '???',
'frequency response displacement': '???',
'frequency response stress?': '???',
'ceig': '???', # complex eigenvalues
}
response_name_to_f06_response_type = {
# weight/volume
'weight' : 'WEIGHT',
'volume': 'VOLUME',
'normal modes': 'FREQ',
# static
'static stress': 'STRESS',
'static strain': 'STRAIN',
'static displacement': 'DISP',
'composite failure': 'CFAILURE',
'composite strain': 'CSTRAIN',
# buckling
'buckling': 'BUCK',
# complex eigenvalues
'ceig': '???',
# psd
'psd displacement': 'DISP',
'psd acceleration': 'ACCE',
# ???
'frequency response displacement': '???',
'frequency response stress?': '???',
}
for i, respi in self.responses.items():
response_number = respi['response_number']
if 'name' in respi:
name = respi['name']
group = response_name_to_group[name]
responses_groups[group].append(i)
assert response_number == 1, respi
else:
assert response_number == 2, respi
responses_groups['2'].append(i)
#print(f'responses_groups = {responses_groups}')
msg = ''
#' ----- IDENTIFICATION OF COLUMNS IN THE DESIGN SENSITIVITY -----'
#' ----- MATRIX THAT ARE ASSOCIATED WITH DRESP1 ENTRIES -----'
#''
#''
missing_keys = set(list(responses_groups.keys())) - set(response_groups_order)
assert len(missing_keys) == 0, missing_keys
for group_name in response_groups_order:
ids = responses_groups[group_name]
if len(ids) == 0:
continue
if group_name == 'weight_volume':
msg += (
' ----- WEIGHT/VOLUME RESPONSES -----\n'
' ------------------------------------------\n'
' COLUMN DRESP1 RESPONSE\n'
' NO. ENTRY ID TYPE \n'
' ------------------------------------------\n')
for i in ids:
respi = self.responses[i]
external_id = respi['external_response_id']
name = respi['name']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s}\n'
elif group_name == 'static':
msg += self._write_static(ids, response_name_to_f06_response_type)
elif group_name in ['eigenvalue', 'buckling']:
if group_name == 'eigenvalue':
msg += ' ----- EIGENVALUE RESPONSES -----\n'
elif group_name == 'buckling':
msg += ' ------ BUCKLING RESPONSES ------\n'
else: # pragma: no cover
raise RuntimeError(group_name)
msg += (
' --------------------------------------------------------------------------\n'
' COLUMN DRESP1 RESPONSE MODE SUB \n'
' NO. ENTRY ID TYPE NO. CASE \n'
' --------------------------------------------------------------------------\n'
)
for i in ids:
respi = self.responses[i]
external_id = respi['external_response_id']
name = respi['name']
mode_num = respi['mode_num']
subcase = respi['subcase']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {mode_num:8d} {subcase:8d}\n'
elif group_name == 'psd':
msg += self._write_psd(ids, response_name_to_f06_response_type)
elif group_name == '2':
msg += self._write_dresp2(ids)
else:
warnings.warn(f'skipping DSCMCOL group_name={group_name}')
for i in ids:
respi = self.responses[i]
warnings.warn(str(respi))
continue
msg += '\n\n'
str(msg)
@property
def external_ids(self) -> list[int]:
external_ids = []
for resp in self.responses.values():
external_ids.append(resp['external_response_id'])
print(resp)
return external_ids
@property
def names(self) -> list[str]:
names = []
for resp in self.responses.values():
names.append(resp['name'])
return names
def _write_static(self, ids, response_name_to_f06_response_type):
msg = ''
is_composite = False
for i in ids:
respi = self.responses[i]
name = respi['name']
if name in ['composite failure', 'composite strain']:
is_composite = True
break
msg += (
' ----- STATICS RESPONSES -----\n'
' ------------------------------------------------------------------------------------------------------------------------\n'
)
if is_composite:
msg += (
' COLUMN DRESP1 RESPONSE GRID/ELM VIEW COMPONENT SUB PLY \n'
' NO. ENTRY ID TYPE ID ELM ID NO. CASE NO. \n'
)
else:
msg += (
' COLUMN DRESP1 RESPONSE GRID/ELM VIEW COMPONENT SUB \n'
' NO. ENTRY ID TYPE ID ELM ID NO. CASE \n'
#' ------------------------------------------------------------------------------------------------------------------------\n'
#' 2 2 STRESS 1 5 1'
)
msg += ' ------------------------------------------------------------------------------------------------------------------------\n'
for i in ids:
respi = self.responses[i]
external_id = respi['external_response_id']
name = respi['name']
subcase = respi['subcase']
comp = respi['component']
if name in ['static stress', 'static strain']:
eid = respi['eid']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {eid:8d} {comp:8d} {subcase:8d}\n'
elif name in ['static displacement']:
grid = respi['grid']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {grid:8d} {comp:8d} {subcase:8d}\n'
elif name in ['composite failure', 'composite strain']:
eid = respi['eid']
ply = respi['ply']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {eid:8d} 0 {comp:8d} {subcase:8d} {ply:8d}\n'
#msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {eid:8d} {comp:8d} {subcase:8d}\n'
else:
raise NotImplementedError(respi)
return msg
def _write_psd(self, ids, response_name_to_f06_response_type):
msg = ''
#is_composite = False
#for i in ids:
#respi = self.responses[i]
#name = respi['name']
#if name in ['composite failure', 'composite strain']:
#is_composite = True
#break
msg += (
' ----- PSD RESPONSES -----\n'
)
msg += (
' ------------------------------------------------------------------------------------------------------------------------\n'
' COLUMN DRESP1 RESPONSE GRID/ELM RANDPS COMPONENT SUB PLY \n'
' NO. ENTRY ID TYPE ID ID NO. CASE NO. \n'
' ------------------------------------------------------------------------------------------------------------------------\n'
)
for i in ids:
respi = self.responses[i]
external_id = respi['external_response_id']
name = respi['name']
subcase = respi['subcase']
comp = respi['component']
if name in ['psd displacement', 'psd acceleration']:
grid = respi['grid']
randps = respi['randps']
response_type = response_name_to_f06_response_type[name]
msg += f' {i+1:8d} {external_id:8d} {response_type:8s} {grid:8d} {randps:8d} {comp:8d} {subcase:8d}\n'
else:
raise RuntimeError(respi)
return msg
def _write_dresp2(self, ids):
msg = (
' ----- IDENTIFICATION OF COLUMNS IN THE DESIGN SENSITIVITY -----\n'
' ----- MATRIX THAT ARE ASSOCIATED WITH DRESP2 ENTRIES -----\n'
'\n'
'\n'
' ----------------------------------------------------------\n'
' COLUMN DRESP2 SUB FREQ/ \n'
' NO. ENTRY ID CASE TIME \n'
' ----------------------------------------------------------\n'
)
#' 96 103 0 0.00000'
#' 97 104 0 0.00000'
#' 100 105 1'
for i in ids:
#{'iresponse': 95, 'response_number': 2, 'internal_response_id': 1, 'external_response_id': 103,
#'subcase': 0, 'dflag': 0, 'freq': 0.0, 'seid': 0}
respi = self.responses[i]
external_id = respi['external_response_id']
freq = respi['freq']
subcase = respi['subcase']
dflag = respi['dflag']
if dflag:
msg += f' {i+1:8d} {external_id:8d} {subcase:8d}\n'
else:
msg += f' {i+1:8d} {external_id:8d} {subcase:8d} {freq:8f}\n'
return msg
def __repr__(self):
self.get_responses_by_group()
nresponses = len(self.responses)
internal_ids = np.zeros(nresponses, dtype='int32')
external_ids = np.zeros(nresponses, dtype='int32')
response_types = -np.full(nresponses, -1, dtype='int32')
names_per_response = {}
#internal_ids = [resp['internal_id'] for resp in self.responses.values()]
#external_ids = [resp['external_id'] for resp in self.responses.values()]
#response_types = [resp['response_type'] for resp in self.responses.values()]
is_dresp2 = False
for i, respi in self.responses.items():
internal_ids[i] = respi['internal_response_id']
external_ids[i] = respi['external_response_id']
try:
response_type = respi['response_type']
response_types[i] = response_type
name = respi['name']
if (response_type, name) not in names_per_response:
names_per_response[(response_type, name)] = list(respi.keys())
except KeyError:
is_dresp2 = True
msg = 'DSCMCOL()\n'
msg += f' nresponses: {nresponses}\n'
msg += f' internal_ids: {internal_ids}\n'
msg += f' external_ids: {external_ids}\n'
msg += f' response_types: {response_types}\n'
if names_per_response:
msg += ' response_type names:\n'
for (response_type, name), names in names_per_response.items():
names.remove('internal_response_id')
names.remove('external_response_id')
names2 = str(names).replace("'", '')
msg += f' {response_type:2d}: name={name!r}; names={names2}\n'
return msg
[docs]
def get_stats(self, short: bool=False):
self.get_responses_by_group()
if short:
return f'responses.dscmcol ({len(self.responses)})\n'
return self.__repr__() + '\n'
[docs]
class Desvars:
def __init__(self, desvars):
#internal_id, desvar_id, label, lower, upper, delxv, dunno = desvar
ndesvars = len(desvars)
self.internal_id = np.zeros(ndesvars, dtype='int32')
self.desvar_id = np.zeros(ndesvars, dtype='int32')
self.label = np.zeros(ndesvars, dtype='|U8')
self.lower = np.zeros(ndesvars, dtype='float32')
self.upper = np.zeros(ndesvars, dtype='float32')
self.delxv = np.zeros(ndesvars, dtype='float32')
self.dunno = np.zeros(ndesvars, dtype='float32')
encoding = 'ascii'
for i, (internal_id, desvar_id, label, lower, upper, delxv, dunno) in enumerate(desvars):
try:
label_str = label.decode(encoding)
#print((internal_id, desvar_id, label_str, lower, upper, delxv, dunno))
except Exception:
label_str = 'fake_%d' % i
#warnings.warn(str([internal_id, desvar_id, label, label_str, lower, upper, delxv, dunno]))
#raise
self.internal_id[i] = internal_id
self.desvar_id[i] = desvar_id
self.label[i] = label_str.strip()
self.lower[i] = lower
self.upper[i] = upper
self.delxv[i] = delxv
self.dunno[i] = dunno
def __repr__(self):
msg = 'Desvars()\n'
#msg += ' shape=(%s, %s)\n' % (self.n, self.ndesign_variables)
msg += ' internal_id = %s\n' % self.internal_id
msg += ' desvar_id = %s\n' % self.desvar_id
msg += ' label = %s\n' % self.label
msg += ' lower = %s\n' % self.lower
msg += ' upper = %s\n' % self.upper
msg += ' delxv = %s\n' % self.delxv
msg += ' dunno = %s\n' % self.dunno
return msg
[docs]
def get_stats(self, short: bool=False):
if short:
return f'responses.desvars ({len(self.internal_id)})\n'
return self.__repr__() + '\n'
[docs]
class Convergence:
def __init__(self, ndesign_variables):
self.n = 1
self._n = 0
self.is_built = False
self.ndesign_variables = ndesign_variables
self.design_iter = []
self.iconvergence = [] # 1-soft, 2-hard
self.conv_result = [] # 0-no, 1-soft, 2-hard
self.obj_initial = []
self.obj_final = []
self.constraint_max = []
self.row_constraint_max = []
self.desvar_values = []
[docs]
def get_convergence(self):
iconvergence = self.iconvergence[-1] # hard, soft (2)
conv_result = self.conv_result[-1] # no, hard, soft (3)
# 2*3 = 6
if (conv_result, iconvergence) == ('hard', 'hard'): # sure about this
convergence = 'HARD'
elif (conv_result, iconvergence) == ('no', 'hard'): # pretty sure about this...
convergence = 'MAX DESIGN CYCLES'
elif (conv_result, iconvergence) == ('no', 'soft'): # is this possible???
convergence = 'MAX DESIGN CYCLES'
# are these possible???
# we'll just assume SOFT convergence
if (conv_result, iconvergence) == ('hard', 'soft'): # pretty sure about this...
convergence = 'SOFT'
elif (conv_result, iconvergence) == ('soft', 'hard'): # is this possible???
convergence = 'SOFT'
elif (conv_result, iconvergence) == ('soft', 'soft'): # is this possible???
convergence = 'SOFT'
else: # pragma: no cover
msg = 'conv_result=%r iconvergence=%r' % (conv_result, iconvergence)
raise NotImplementedError(msg)
return convergence, (conv_result, iconvergence)
[docs]
def append(self, design_iter, iconvergence, conv_result, obj_initial, obj_final,
constraint_max, row_constraint_max, desvar_values):
if not self.is_built:
self.design_iter = np.zeros(self.n, dtype='int32')
self.iconvergence = np.zeros(self.n, dtype=object)
self.conv_result = np.zeros(self.n, dtype=object)
self.obj_initial = np.zeros(self.n, dtype='float32')
self.obj_final = np.zeros(self.n, dtype='float32')
self.constraint_max = np.zeros(self.n, dtype='float32')
self.row_constraint_max = np.zeros(self.n, dtype='int32')
self.desvar_values = np.zeros((self.n, self.ndesign_variables), dtype='float32')
self.is_built = True
n = self._n
self.design_iter[n] = design_iter
self.iconvergence[n] = iconvergence
self.conv_result[n] = conv_result
self.obj_initial[n] = obj_initial
self.obj_final[n] = obj_final
self.constraint_max[n] = constraint_max
self.row_constraint_max[n] = row_constraint_max
self.desvar_values[n, :] = desvar_values
self._n += 1
def __repr__(self):
msg = 'Convergence()\n'
msg += ' design_iter = %s\n' % self.design_iter
msg += ' icovergence = %s\n' % self.iconvergence
msg += ' conv_result = %s\n' % self.conv_result
msg += ' obj_initial = %s\n' % self.obj_initial
msg += ' obj_final = %s\n' % self.obj_final
msg += ' constraint_max = %s\n' % self.constraint_max
msg += ' row_constraint_max = %s\n' % self.row_constraint_max
msg += f' desvar_values; shape=({self.n}, {self.ndesign_variables}):\n{self.desvar_values}'
return msg
[docs]
def get_stats(self, short: bool=False):
if short:
return 'responses.convergence_data (%s, %s)\n' % (self.n, self.ndesign_variables)
return self.__repr__() + '\n'