@@ -355,12 +355,19 @@ def _read(self):
355355
356356 # --- Tables that can be detected based on the "Label" (second entry on line)
357357 # NOTE: MJointID1, used by SubDyn and HydroDyn
358- NUMTAB_FROM_LAB_DETECT = ['NumAlf' , 'F_X' , 'MemberCd1' , 'MJointID1' , 'NOutLoc' , 'NOutCnt' , 'PropD' ,'Diam' ,'Type' ,'LineType' ]
359- NUMTAB_FROM_LAB_DIM_VAR = ['NumAlf' , 'NKInpSt' , 'NCoefMembers' , 'NMembers' , 'NMOutputs' , 'NMOutputs' , 'NPropSets' ,'NTypes' ,'NConnects' ,'NLines' ]
360- NUMTAB_FROM_LAB_VARNAME = ['AFCoeff' , 'TMDspProp' , 'MemberProp' , 'Members' , 'MemberOuts' , 'MemberOuts' , 'SectionProp' ,'LineTypes' ,'ConnectionProp' ,'LineProp' ]
361- NUMTAB_FROM_LAB_NHEADER = [2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ]
362- NUMTAB_FROM_LAB_NOFFSET = [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]
363- NUMTAB_FROM_LAB_TYPE = ['num' , 'num' , 'num' , 'mix' , 'num' , 'sdout' , 'num' ,'mix' ,'mix' ,'mix' ]
358+ NUMTAB_FROM_LAB_DETECT = ['NumAlf' , 'F_X' , 'MemberCd1' , 'MJointID1' , 'NOutLoc' , 'NOutCnt' , 'PropD' ]
359+ NUMTAB_FROM_LAB_DIM_VAR = ['NumAlf' , 'NKInpSt' , 'NCoefMembers' , 'NMembers' , 'NMOutputs' , 'NMOutputs' , 'NPropSets' ]
360+ NUMTAB_FROM_LAB_VARNAME = ['AFCoeff' , 'TMDspProp' , 'MemberProp' , 'Members' , 'MemberOuts' , 'MemberOuts' , 'SectionProp' ]
361+ NUMTAB_FROM_LAB_NHEADER = [2 , 2 , 2 , 2 , 2 , 2 , 2 ]
362+ NUMTAB_FROM_LAB_NOFFSET = [0 , 0 , 0 , 0 , 0 , 0 , 0 ]
363+ NUMTAB_FROM_LAB_TYPE = ['num' , 'num' , 'num' , 'mix' , 'num' , 'sdout' , 'num' ]
364+ # MoorDyn Version 1 and 2 (with AUTO for LAB_DIM_VAR)
365+ NUMTAB_FROM_LAB_DETECT += ['Diam' ,'Type' ,'LineType' , 'Attachment' ]
366+ NUMTAB_FROM_LAB_DIM_VAR += ['NTypes:AUTO' ,'NConnects' ,'NLines:AUTO' , 'AUTO' ]
367+ NUMTAB_FROM_LAB_VARNAME += ['LineTypes' ,'ConnectionProp' ,'LineProp' , 'Points' ]
368+ NUMTAB_FROM_LAB_NHEADER += [ 2 , 2 , 2 , 2 ]
369+ NUMTAB_FROM_LAB_NOFFSET += [ 0 , 0 , 0 , 0 ]
370+ NUMTAB_FROM_LAB_TYPE += ['mix' ,'mix' ,'mix' , 'mix' ]
364371 # SubDyn
365372 NUMTAB_FROM_LAB_DETECT += ['GuyanDampSize' , 'YoungE' , 'YoungE' , 'EA' , 'MatDens' ]
366373 NUMTAB_FROM_LAB_DIM_VAR += [6 , 'NPropSets' , 'NXPropSets' , 'NCablePropSets' , 'NRigidPropSets' ]
@@ -484,6 +491,19 @@ def _read(self):
484491 i += 1 ;
485492 self .readBeamDynProps (lines ,i )
486493 return
494+ elif line .upper ().find ('OUTPUTS' )> 0 :
495+ if 'Points' in self .keys () and 'dtM' in self .keys ():
496+ OutList ,i = parseFASTOutList (lines ,i + 1 )
497+ d = getDict ()
498+ d ['label' ] = 'Outlist'
499+ d ['descr' ] = ''
500+ d ['tabType' ] = TABTYPE_FIL # TODO
501+ d ['value' ] = OutList
502+ self .addComment ('------------------------ OUTPUTS --------------------------------------------' )
503+ self .data .append (d )
504+ self .addComment ('END' )
505+ self .addComment ('------------------------- need this line --------------------------------------' )
506+ return
487507
488508 # --- Parsing of standard lines: value(s) key comment
489509 line = lines [i ]
@@ -601,7 +621,6 @@ def _read(self):
601621 self .data .append (dd )
602622
603623 d ['label' ] = NUMTAB_FROM_LAB_VARNAME [ii ]
604- d ['tabDimVar' ] = NUMTAB_FROM_LAB_DIM_VAR [ii ]
605624 if d ['label' ].lower ()== 'afcoeff' :
606625 d ['tabType' ] = TABTYPE_NUM_WITH_HEADERCOM
607626 else :
@@ -611,10 +630,28 @@ def _read(self):
611630 d ['tabType' ] = TABTYPE_NUM_SUBDYNOUT
612631 else :
613632 d ['tabType' ] = TABTYPE_MIX_WITH_HEADER
614- if isinstance (d ['tabDimVar' ],int ):
633+ # Finding table dimension (number of lines)
634+ tabDimVar = NUMTAB_FROM_LAB_DIM_VAR [ii ]
635+ if isinstance (tabDimVar , int ): # dimension hardcoded
636+ d ['tabDimVar' ] = tabDimVar
615637 nTabLines = d ['tabDimVar' ]
616638 else :
617- nTabLines = self [d ['tabDimVar' ]+ labOffset ]
639+ # We either use a variable name or "AUTO" to find the number of rows
640+ tabDimVars = tabDimVar .split (':' )
641+ for tabDimVar in tabDimVars :
642+ d ['tabDimVar' ] = tabDimVar
643+ if tabDimVar == 'AUTO' :
644+ # Determine table dimension automatically
645+ nTabLines = findNumberOfTableLines (lines [i + nHeaders :], break_chars = ['---' ,'!' ,'#' ])
646+ break
647+ else :
648+ try :
649+ nTabLines = self [tabDimVar + labOffset ]
650+ break
651+ except KeyError :
652+ #print('Cannot determine table dimension using {}'.format(tabDimVar))
653+ # Hopefully this table has AUTO as well
654+ pass
618655
619656 d ['label' ] += labOffset
620657 #print('Reading table {} Dimension {} (based on {})'.format(d['label'],nTabLines,d['tabDimVar']));
@@ -758,10 +795,13 @@ def mat_tostring(M,fmt='24.16e'):
758795 s += '\n ' .join ('\t ' .join ('{:15.8e}' .format (x ) for x in y ) for y in d ['value' ])
759796 elif d ['tabType' ]== TABTYPE_FIL :
760797 #f.write('{} {} {}\n'.format(d['value'][0],d['tabDetect'],d['descr']))
798+ label = d ['label' ]
799+ if 'kbot' in self .keys (): # Moordyn has no 'OutList' label..
800+ label = ''
761801 if len (d ['value' ])== 1 :
762- s += '{} {} {}' .format (d ['value' ][0 ],d [ ' label' ], d ['descr' ]) # TODO?
802+ s += '{} {} {}' .format (d ['value' ][0 ], label , d ['descr' ]) # TODO?
763803 else :
764- s += '{} {} {}\n ' .format (d ['value' ][0 ],d [ ' label' ], d ['descr' ]) # TODO?
804+ s += '{} {} {}\n ' .format (d ['value' ][0 ], label , d ['descr' ]) # TODO?
765805 s += '\n ' .join (fil for fil in d ['value' ][1 :])
766806 elif d ['tabType' ]== TABTYPE_NUM_BEAMDYN :
767807 # TODO use dedicated sub-class
@@ -1186,6 +1226,17 @@ def detectUnits(s,nRef):
11861226 return Units
11871227
11881228
1229+ def findNumberOfTableLines (lines , break_chars ):
1230+ """ Loop through lines until a one of the "break character is found"""
1231+ for i , l in enumerate (lines ):
1232+ for bc in break_chars :
1233+ if l .startswith (bc ):
1234+ return i
1235+ # Not found
1236+ print ('[FAIL] end of table not found' )
1237+ return len (lines )
1238+
1239+
11891240def parseFASTNumTable (filename ,lines ,n ,iStart ,nHeaders = 2 ,tableType = 'num' ,nOffset = 0 , varNumLines = '' ):
11901241 """
11911242 First lines of data starts at: nHeaders+nOffset
0 commit comments