Source code for pyNastran.op2.result_objects.grid_point_weight

"""defines the GridPointWeight class"""
from io import StringIO
from itertools import count
from struct import pack
from typing import TextIO, BinaryIO, cast
import numpy as np

from pyNastran.utils import object_attributes, object_methods
from pyNastran.op2.result_objects.op2_objects import _write_table_header, Date
from pyNastran.op2.op2_interface.write_utils import export_to_hdf5
#from pyNastran.op2.writer.utils import fix_table3_types

# restricted b/c we dont support 64-bit writing
float_types = (float, np.float32)
integer_types = (int, np.int32)

#                                                                       ?           ?       ?                                     ?
#good = (4, 2, 4, 8, 1464878927, 538976327, 8, 4, -1, 4, 4, 7, 4, 28, 101, 0, 0, 0, 0,   0, 1, 28, 4, -2, 4, 4, 1, 4, 4, 0, 4, 4, 2, 4, 8,  1464878927, 538976327, 8, 4,                   -3, 4, 4, 1, 4, 4, 0, 4, 4, 146, 4)
#bad  = (4, 2, 4, 8, 1464878927, 538976327, 8, 4, -1, 4, 4, 7, 4, 28, 102, 0, 0, 0, 512, 0, 0, 28, 4, -2, 4, 4, 1, 4, 4, 0, 4, 4, 7, 4, 28, 1464878927, 538976327, 9, 27, 19, 0, 1, 28, 4, -3, 4, 4, 1, 4, 4)
[docs] class GridPointWeight: def __init__(self, reference_point: int, MO: np.ndarray, S: np.ndarray, mass: np.ndarray, cg: np.ndarray, IS: np.ndarray, IQ: np.ndarray, Q: np.ndarray, approach_code: int=1, table_code: int=13, title: str='', subtitle: str='', label: str='', superelement_adaptivity_index: str=''): """ .. seealso:: http://www.6dof.com/index.php?option=com_content&view=article&id=298:output-from-the-grid-point-weight-generator&catid=178:courses-and-trainings&Itemid=61 """ # The Grid Point Weight Generator (GPWG) module computes the rigid body # mass properties of an entire structure with respect to a user specified point and with # respect to the center of mass. Output from the module is requested by a PARAM # GRDPNT card in the Bulk Data Deck which specifies from which grid point mass # computations are to be referenced. Optionally, the absence of a specific grid point # (i.e. PARAM, GRDPNT, 0) automatically causes the origin of the basic # coordinate system to be utilized as a reference. The mass properties are initially # defined in the basic coordinate system. Subsequently, the mass properties are # transformed to principal mass axes and to principal inertia axes. The actual printout # is composed of several elements. These are: self.reference_point = reference_point assert isinstance(reference_point, int), f'reference_point={reference_point!r}; type={type(reference_point)}' # M0 RIGID BODY MASS MATRIX IN BASIC COORDINATE SYSTEM # This is the rigid body mass matrix of the entire structure in # the basic coordinate system with respect to a reference point # chosen by the analyst. self.MO = MO assert MO.shape == (6, 6), MO.shape # S TRANSFORMATION MATRIX FOR SCALAR MASS PARTITION # S is the transformation from the basic coordinate system to the # set of principal axes for the 3 x 3 scalar mass partition of the # 6 x 6 mass matrix. The principal axes for just the scalar # partition are known as the principal mass axes. self.S = S assert S.shape == (3, 3), S.shape self.mass = mass assert mass.shape == (3,), mass.shape # XC.G. YC.G. ZC.G. # It is possible in NASTRAN to assemble a structural model having # different values of mass in each coordinate direction at a grid # point. This can arise, for example, by assembling scalar mass # components or from omitting some components by means of bar # element pin flags. Consequently three distinct mass systems are # assembled one in each of the three directions of the principal # mass axes (the S system). This third tabulation has five columns. # The first column lists the axis direction in the S coordinates. # The second column lists the mass associated with the appropriate # axis direction. The final three columns list the x, y, and z # coordinate distances from the reference point to the center of # mass for each of the three mass systems. self.cg = cg assert cg.shape == (3, 3), cg.shape # I(S) INERTIAS RELATIVE TO C.G. # This is the 3 x 3 mass moment of inertia partition with respect # to the center of gravity referred to the principal mass axes # (the S system). # # This is not necessarily a diagonal matrix because the # determination of the S system does not involve second moments. # The values of inertias at the center of gravity are found from # the values at the reference point employing the # parallel axes rule. self.IS = IS assert IS.shape == (3, 3), IS.shape # I(Q) PRINCIPAL INERTIAS # The principal moments of inertia at the center of gravity are displayed # in matrix form with reference to the Q system of axes. The Q system is # obtained from an eigenvalue analysis of the I(S) matrix. self.IQ = IQ assert IQ.shape == (3, ), f'IQ.shape={IQ.shape}; IQ=\n{IQ}' # Q TRANSFORMATION MATRIX I(Q) = Q^T*IBAR(S)*Q # Q is the coordinate transformation between the S axes and the Q axes. # IBAR(S) is the same as I(s) except that the signs of the off-diagonal # terms are reversed. self.Q = Q assert Q.shape == (3, 3), Q.shape self.title = title self.subtitle = subtitle self.label = label self.superelement_adaptivity_index = subtitle self.approach_code = approach_code self.table_code = table_code
[docs] def export_to_hdf5(self, group, log) -> None: """exports the object to HDF5 format""" export_to_hdf5(self, group, log)
[docs] def object_attributes(self, mode: str='public', keys_to_skip=None, filter_properties: bool=False) -> list[str]: if keys_to_skip is None: keys_to_skip = [] my_keys_to_skip = [ 'object_methods', 'object_attributes', ] return object_attributes(self, mode=mode, keys_to_skip=keys_to_skip+my_keys_to_skip, filter_properties=filter_properties)
[docs] def object_methods(self, mode: str='public', keys_to_skip=None): if keys_to_skip is None: keys_to_skip = [] my_keys_to_skip = [] my_keys_to_skip = [ 'object_methods', 'object_attributes', ] return object_methods(self, mode=mode, keys_to_skip=keys_to_skip+my_keys_to_skip)
def __eq__(self, weight) -> bool: msg = '' if not self.reference_point == weight.reference_point: msg += f'reference_point: {self.reference_point} -> {weight.reference_point}\n' if not np.array_equal(self.MO, weight.MO): msg += f'reference_point: {self.MO} -> {weight.MO}\n' if not np.array_equal(self.S, weight.S): msg += f'reference_point: {self.S} -> {weight.S}\n' if not np.array_equal(self.mass, weight.mass): msg += f'reference_point: {self.mass} -> {weight.mass}\n' if not np.array_equal(self.cg, weight.cg): msg += f'reference_point: {self.cg} -> {weight.cg}\n' if not np.array_equal(self.IS, weight.IS): msg += f'reference_point: {self.IS} -> {weight.IS}\n' if not np.array_equal(self.IQ, weight.IQ): msg += f'reference_point: {self.IQ} -> {weight.IQ}\n' if not np.array_equal(self.Q, weight.Q): msg += f'reference_point: {self.Q} -> {weight.Q}' if msg: raise ValueError('GridPointWeight:\n' + msg) return True
[docs] def get_stats(self, key: str='', short: bool=True) -> str: key2 = f'[{key!r}]' if short: msg = (f'GridPointWeight{key2}: ref_point=%s mass=%g; ' '[reference_point, M0, S, mass, cg, IS, IQ, Q]\n' % ( self.reference_point, self.mass.max())) else: RB = self.MO msg = ( f'GridPointWeight{key2}:' f' reference_point={self.reference_point:d}\n' f' mass=[{self.mass[0]:10g} {self.mass[1]:10g} {self.mass[2]:10g}]\n' f' cg = [{self.cg[0, 0]:10g} {self.cg[0, 1]:10g} {self.cg[0, 2]:10g}]\n' f' [{self.cg[1, 0]:10g} {self.cg[1, 1]:10g} {self.cg[1, 2]:10g}]\n' f' [{self.cg[2, 0]:10g} {self.cg[2, 1]:10g} {self.cg[2, 2]:10g}]\n\n' f' MO = [{RB[0, 0]:10g} {RB[0, 1]:10g} {RB[0, 2]:10g} {RB[0, 3]:10g} {RB[0, 4]:10g} {RB[0, 5]:10g}]\n' f' [{RB[1, 0]:10g} {RB[1, 1]:10g} {RB[1, 2]:10g} {RB[1, 3]:10g} {RB[1, 4]:10g} {RB[1, 5]:10g}]\n' f' [{RB[2, 0]:10g} {RB[2, 1]:10g} {RB[2, 2]:10g} {RB[2, 3]:10g} {RB[2, 4]:10g} {RB[2, 5]:10g}]\n' f' [{RB[3, 0]:10g} {RB[3, 1]:10g} {RB[3, 2]:10g} {RB[3, 3]:10g} {RB[3, 4]:10g} {RB[3, 5]:10g}]\n' f' [{RB[4, 0]:10g} {RB[4, 1]:10g} {RB[4, 2]:10g} {RB[4, 3]:10g} {RB[4, 4]:10g} {RB[4, 5]:10g}]\n' f' [{RB[5, 0]:10g} {RB[5, 1]:10g} {RB[5, 2]:10g} {RB[5, 3]:10g} {RB[5, 4]:10g} {RB[5, 5]:10g}]\n\n' f' IS = [{self.IS[0, 0]:10g} {self.IS[0, 1]:10g} {self.IS[0, 2]:10g}]\n' f' [{self.IS[1, 0]:10g} {self.IS[1, 1]:10g} {self.IS[1, 2]:10g}]\n' f' [{self.IS[2, 0]:10g} {self.IS[2, 1]:10g} {self.IS[2, 2]:10g}]\n\n' f" IQ = [{self.IQ[0]:10g} {'':10s} {'':10s}]\n" f" [{'':10s} {self.IQ[1]:10g} {'':10s}]\n" f" [{'':10s} {'':10s} {self.IQ[2]:10g}]\n\n" f' Q = [{self.Q[0, 0]:10g} {self.Q[0, 1]:10g} {self.Q[0, 2]:10g}]\n' f' [{self.Q[1, 0]:10g} {self.Q[1, 1]:10g} {self.Q[1, 2]:10g}]\n' f' [{self.Q[2, 0]:10g} {self.Q[2, 1]:10g} {self.Q[2, 2]:10g}]\n' ) return msg
def __repr__(self) -> str: f = StringIO() page_stamp = 'PAGE %i' page_num = 1 self.write_f06(f, page_stamp, page_num) msg = f.getvalue() return msg def _write_table_3(self, op2_file: BinaryIO, fascii: TextIO, new_result: bool, table_name: bytes, itable: int=-3) -> None: import inspect frame = inspect.currentframe() call_frame = inspect.getouterframes(frame, 2) fascii.write('%s.write_table_3: %s\n' % (self.__class__.__name__, call_frame[1][3])) if new_result and itable != -3: header = [ 4, 146, 4, ] else: header = [ 4, itable, 4, 4, 1, 4, 4, 0, 4, 4, 146, 4, ] op2_file.write(pack(b'%ii' % len(header), *header)) fascii.write('table_3_header = %s\n' % header) #op2_file.write(pack('12i', *[4, itable, 4, #4, 1, 4, #4, 0, 4, #4, 146, 4, #])) approach_code = self.approach_code table_code = self.table_code #isubcase = self.isubcase #random_code = self.random_code #format_code = 1 isubcase = 0 num_wide = 79 # self.num_wide #acoustic_flag = self.acoustic_flag if hasattr(self, 'acoustic_flag') else 0 reference_point = self.reference_point #reference_point = 22 #thermal = self.thermal title = b'%-128s' % self.title.encode('ascii') subtitle = b'%-128s' % self.subtitle.encode('ascii') # missing superelement_adaptivity_index label = b'%-128s' % self.label.encode('ascii') #1, 13, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ftable3 = b'i' * 50 + b'128s 128s 128s' #print(self.get_stats()) table3 = [ approach_code, table_code, reference_point, isubcase, 0, 0, 0, 0, 0, num_wide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, title, subtitle, label, ] #table3 = fix_table3_types(table3, size=4) n = 0 for i, val, ftable3i in zip(count(), table3, ftable3.decode('ascii')): assert val is not None, 'i=%s val=%s ftable3i=%s\n%s' % (i, val, ftable3i, self.get_stats()) if isinstance(val, integer_types): n += 4 assert ftable3i == 'i', 'i=%s val=%s type=%s' % (i, val, ftable3i) elif isinstance(val, float_types): n += 4 assert ftable3i == 'f', 'i=%s val=%s type=%s' % (i, val, ftable3i) else: val = cast(str, val) n += len(val) assert n == 584, n data = [584] + table3 + [584] fmt = b'i' + ftable3 + b'i' #op2_file.write(pack(fascii, '%s header 3c' % table_name, fmt, data)) fascii.write('%s header 3c = %s\n' % (table_name, data)) #j = 7 #print(ftable3[:j]) #print(table3[:j]) #pack(ftable3[:j], *table3[:j]) op2_file.write(pack(fmt, *data))
[docs] def write_op2(self, op2_file: BinaryIO, op2_ascii: TextIO, date: Date, endian: bytes=b'<') -> int: itable = -1 import inspect #allowed_tables = [ #'OUGV1', 'BOUGV1', 'BOPHIG', 'BOPG1', #'OUPV1', #'OQP1', 'OQMG1', 'OQG1', 'OQGV1', 'OPNL1', #'OPG1', 'OPGV1', #'OAGATO1', 'OAGCRM1', 'OAGNO1', 'OAGPSD1', 'OAGRMS1', #'OQGPSD1', #'OCRPG', 'OCRUG', 'OUG1', #'OUGV1PAT', #] #assert self.table_name in allowed_tables, self.table_name table_name = 'OGPWG' frame = inspect.currentframe() call_frame = inspect.getouterframes(frame, 2) op2_ascii.write(f'{self.__class__.__name__}.write_op2: {call_frame[1][3]}\n') subtable_name = b'OGPWG' if itable == -1: _write_table_header(op2_file, op2_ascii, date, table_name, subtable_name) itable = -3 #s = Struct(op2_format) #unused_node = self.node_gridtype[:, 0] #gridtype = self.node_gridtype[:, 1] #format_table4_1 = Struct(self._endian + b'15i') #format_table4_2 = Struct(self._endian + b'3i') # table 4 info #ntimes = self.data.shape[0] #nnodes = self.data.shape[1] #nnodes_device = self.node_gridtype[:, 0] * 10 + self.device_code #(2+6) => (node_id, gridtypei, t1i, t2i, t3i, r1i, r2i, r3i) #ntotal = nnodes * (2 + 6) #print('shape = %s' % str(self.data.shape)) #assert nnodes > 1, nnodes #assert ntotal > 1, ntotal #unused_device_code = self.device_code #fascii.write(' ntimes = %s\n' % self.ntimes) #fmt = '%2i %6f' #print('ntotal=%s' % (ntotal)) #for itime in range(self.ntimes): # good = (4, -4, 4, 4, 1, 4, 4, 0, 4, 4, 78, 4, 312, 1057795080, 0, 0, 0, 0, 0, 0, 1057795080, 0, 0, 0, 1111254630, 0, 0, 1057795080, 0, -1036229018, 0, 0, 0, 0, 1143715840, -1451229184, 0, 0, 0, -1036229018, -1451229184, 1169886464, 0, 0, 1111254630, 0, 0, 0, 1171293184, 1065353216) #bad = (4, -4, 4, 4, 1, 4, 4, 0, 4, 4, 78, 4, 312, 1057795080, 0, 0, 0, 0, 0, 0, 1057795080, 0, 0, 0, 1111254630, 0, 0, 1057795080, 0, -1036229018, 0, 0, 0, 0, 1143715840, -1451229184, 0, 0, 0, -1036229018, -1451229184, 1169886464, 0, 0, 1111254630, 0, 0, 0, 1171293184, 1065353216, 0, 0, 0, 1065353216, 0, 0, 0, 1065353216, 1057795080, 0, -2147483648, 0, 1057795080, 1118530999, 0, -2147483648, 1057795080, 1118530999, 0, 0, 1143715840, 696254464, 0, 696254464, 1156812654, 0, 0, 0, 1160033719, 1143715840, 1156812654, 1160033719, 1065353216, 0, 0, 0, 1065353216, 0, 0, 0, 1065353216, 312, -5, 4, 4, 1, 4, 4, 0, 4, 4, 0, 4, 4, 4, 2, 4, 8, 1447515471, 538976305) ntotal = 78 # 79 * 4 = 316 new_result = True self._write_table_3(op2_file, op2_ascii, new_result, table_name, itable) # record 4 itable -= 1 # -4 header = [4, itable, 4, 4, 1, 4, 4, 0, 4, 4, ntotal, 4, 4*ntotal] op2_file.write(pack(b'%ii' % len(header), *header)) op2_ascii.write('r4 [4, 0, 4]\n') op2_ascii.write(f'r4 [4, {itable:d}, 4]\n') op2_ascii.write('r4 [4, %i, 4]\n' % (4*ntotal)) # ------------------------------------------------------- fmt = endian + b'78f' mcg = np.zeros((3, 4), dtype=self.cg.dtype) mcg[:, 0] = self.mass mcg[:, 1:] = self.cg data = (self.MO.ravel().tolist() + self.S.ravel().tolist() + mcg.ravel().tolist() + self.IS.ravel().tolist() + self.IQ.ravel().tolist() + self.Q.ravel().tolist()) assert None not in data, data msgi = pack(fmt, *data) op2_file.write(msgi) # ------------------------------------------------------- itable -= 1 header = [4 * ntotal, 4, itable, 4, 4, 1, 4, 4, 0, 4, 4, 0, 4, ] op2_file.write(pack(endian + b'13i', *header)) op2_ascii.write('footer = %s\n' % header) return itable
[docs] def write_f06(self, f06_file: TextIO, page_stamp: str, page_num: int) -> int: """ writes the f06 Parameters ---------- f06_file : file / StringIO a file-like object page_stamp : str the page formatter (e.g., 'PAGE %i') page_num : int the active page number Returns ------- page_num : int the new page number """ msg = [' O U T P U T F R O M G R I D P O I N T W E I G H T G E N E R A T O R'] msg.append('0 REFERENCE POINT = %i' % self.reference_point) # MO msg.append(' M O') for i in range(6): msg.append(' * %13.6E %13.6E %13.6E %13.6E %13.6E %13.6E *' % tuple(self.MO[i, :])) msg.append(' S') for i in range(3): msg.append(' * %13.6E %13.6E %13.6E *' % tuple(self.S[i, :])) msg.append(' DIRECTION') msg.append(' MASS AXIS SYSTEM (S) MASS X-C.G. Y-C.G. Z-C.G.') msg.append(' X %12.6E %13.6E %13.6E %13.6E' % (self.mass[0], self.cg[0, 0], self.cg[0, 1], self.cg[0, 2])) msg.append(' Y %12.6E %13.6E %13.6E %13.6E' % (self.mass[1], self.cg[1, 0], self.cg[1, 1], self.cg[1, 2])) msg.append(' Z %12.6E %13.6E %13.6E %13.6E' % (self.mass[2], self.cg[2, 0], self.cg[2, 1], self.cg[2, 2])) msg.append(' I(S)') for i in range(3): msg.append(' * %13.6E %13.6E %13.6E *' % tuple(self.IS[i, :])) msg.append(' I(Q)') msg.append(' * %13.6E %13s %13s *' % (self.IQ[0], '', '')) msg.append(' * %13s %13.6E %13s *' % ('', self.IQ[1], '')) msg.append(' * %13s %13s %13.6E *' % ('', '', self.IQ[2])) msg.append(' Q') for i in range(3): msg.append(' * %13.6E %13.6E %13.6E *' % tuple(self.Q[i, :])) msg.append('\n' + page_stamp % page_num + '\n') f06_file.write('\n'.join(msg)) return page_num + 1
[docs] def make_grid_point_weight(reference_point: int, MO: np.ndarray, approach_code: int=1, table_code: int=13, title: str='', subtitle: str='', label: str='', superelement_adaptivity_index: str='') -> GridPointWeight: """creates a grid point weight table""" Mtt_ = MO[:3, :3] Mrr_ = MO[3:, 3:] Mtr_ = MO[:3, 3:] Mtd = np.diag(Mtt_) delta = np.linalg.norm(Mtd) e_ = [Mtt_[0, 1], Mtt_[0, 2], Mtt_[1, 2]] epsilon = np.linalg.norm(e_) #print(Mtd) #print(Mte) #print(Mtd) #print(Mte) if epsilon/delta > 0.001: unused_eigvals, S = np.linalg.eigh(Mtt_) #print('S1:') #print(S) #print(f'eigvals = {eigvals}') msg = ( '*** USER WARNING MESSAGE 3042 MODULE = GPWG\n' f'INCONSISTENT SCALAR MASSES HAVE BEEN USED. EPSILON/DELTA = {epsilon/delta:.7E}\n') print(msg) #print('S*:') #print(S) else: S = np.eye(3, dtype=Mtt_.dtype) #iswap = [] #if np.sign(S[0, 0]) != np.sign(Mtt_[0, 0]): #mass[0] *= -1. #S[:, 0] *= -1 #iswap.append(0) #if np.sign(S[1, 1]) != np.sign(Mtt_[1, 1]): #iswap.append(1) #if S[1, 1] < 0.: #iswap.append(1) #if S[2, 2] < 0.: #iswap.append(2) #if abs(S[0, 0]) < np.abs(S[:, 0]).max(): #print('swap0') #iswap.append(0) #if S[0, 0] < 0.: #S[:, 0] *= -1 #if abs(S[1, 1]) < np.abs(S[1, 0]).max(): #iswap.append(1) #if abs(S[0, 0]) < np.abs(S[1, 0]): #iswap.append(2) #if iswap: #i1, i2 = iswap #print(f'swap; {iswap}') #m1, m2 = mass[iswap] #mass[[i2, i1]] = mass[iswap] #S[[i2, i1], :] = S[iswap, :] #S[:, [i2, i1]] = S[:, iswap] #print('S2:') #print(S) #print('S3:') #S = np.array([ #[.432, 0.902, 0.], #[-.902, .432, 0.], #[0., 0., 1.], #]) #print(S) Mtt = S.T @ Mtt_ @ S # Mt Mtr = S.T @ Mtr_ @ S Mrr = S.T @ Mrr_ @ S # Mr = I(Q)? #print('---------') #print(Mtt) #cg = Mtr / mass[:, np.newaxis] mx, my, mz = Mtt[0, 0], Mtt[1, 1], Mtt[2, 2] mass = np.hstack([mx, my, mz]) cg = np.vstack([ [Mtr[0, 0], -Mtr[0, 2], Mtr[0, 1]], # Xx, Yx, Zx [Mtr[1, 2], Mtr[1, 1], -Mtr[1, 0]], # Xy, Yy, Zy [-Mtr[2, 1], Mtr[2, 0], -Mtr[2, 2]], # Xz, Yz, Zz ]) if abs(mx) > 0: cg[0, :] /= mx if abs(my) > 0: cg[1, :] /= my if abs(mz) > 0: cg[2, :] /= mz Xx, Yx, Zx = cg[0, :] Xy, Yy, Zy = cg[1, :] Xz, Yz, Zz = cg[2, :] IS = np.zeros((3, 3), dtype=MO.dtype) IS[0, 0] = Mrr[0, 0] - my * Zy ** 2 - mz * Yz ** 2 IS[1, 1] = Mrr[1, 1] - mz * Xz ** 2 - mx * Zx ** 2 IS[2, 2] = Mrr[2, 2] - mx * Yx ** 2 - my * Xy ** 2 IS[1, 0] = IS[0, 1] = -Mrr[0, 1] - mz * Xz * Yz IS[2, 0] = IS[0, 2] = -Mrr[0, 2] - my * Xy * Zy IS[2, 1] = IS[1, 2] = -Mrr[1, 2] - mx * Yx * Zx neg_off_diag = np.array([ [1, -1, -1], [-1, 1, -1], [-1, -1, 1]], dtype=MO.dtype) IQi = neg_off_diag * IS #print(IQi) IQ, Q = np.linalg.eigh(IQi) #IQ = np.diag(Q.T @ IS @ Q) weight = GridPointWeight( reference_point, MO, S, mass, cg, IS, IQ, Q, approach_code=approach_code, table_code=table_code, title=title, subtitle=subtitle, label=label, superelement_adaptivity_index=superelement_adaptivity_index) return weight