inpRW Update 2023.10.6

inpRW inpRW has a new main release, dated October 6, 2023. The files are available in the inpRW Files post.
 

 

This update corrects problems with sub-input files, variable node
elements, leading comments, and it adds more tests.
 

A summary of the major changes follows. Please note that there will be
some breaking changes to the API. I have done my best to document all
such changes in these notes, so it is imperative that you read these
before updating and trying to run an existing script. I will try to
minimize API changes in the future, but the performance and robustness
of inpRW will trump API stability concerns for the near future.

The major features of this update are the following:

  • * Improved handling of all multi-input file jobs (for example,
    *INCLUDE, *MANIFEST, INPUT parameter of multiple keywords).
    * Added "_subinps" attribute to "inpKeyword" class; this is
    used only for *INCLUDE and *MANIFEST blocks and should
    contain only "inpRW" instances.
  • * "inpRW" formerly created sub-instances of the "inpRW" class,
    but used the "keywords" attribute of the parent instance for
    the child.
  • * When parsing sub-input files (*MANIFEST, *INCLUDE), a new
    "inpRW" instance is created for the sub-file, and that
    instance is placed in the parent block’s "_subinps", and the
    sub-inpRW instance’s "keywords" attribute is added to the
    parent block’s suboptions attribute.
  • * The "_elementTypeDictionary" is more useful and more accurate.
    Each entry is now a new "elType" class instead of a dictionary. *
    inpRW should now accurately understand all element types except
    for submodel or user elements. Variable node elements were a
    particular problem before.
  • * Removed function inpKeyword.inpKeyword._getElementNodeNum() and
    replaced it with "inpKeyword.findElementNodeNum()".
  • * Better handling of leading comments (i.e. comment lines before
    the first keyword block). Previous releases would have
    difficulties in some cases.
  • * Corrected a bug related to parsing *REBAR LAYER keywords.
  • * Additional tests added for inpRW functionality.
  • * Addressed an error when the string ‘INF’ would be converted to a
    "Decimal" instance instead of treated as a string.
  • * Added "__repr__()" and "__str__()" functions to the "inpRW" class
    so they produce useful information.
  • * Renamed install.bat to install_to_3DEXPERIENCE.bat to clarify its
    purpose.
  • * Corrected several bugs related to string productions, which
    affected the accuracy of input file writing.
  • * Corrected a bug where elements from multiple *ELEMENT keyword
    blocks would override the elements attribute of shared node
    instances.
  • * Removed python3_inpRW.bat and python3_inpRW.sh from the test
    suite. test_all.bat and test_all.sh instead set the INPRW_TEST
    environment variable which point to the desired Python
    interpreter, and the tests have been rewritten to use INPRW_TEST.
  • * Expanded the documentation on Installation and Usage
    Instructions. The different options for installing inpRW should
    be more clear. There is also a new section called Using inpRW
    with Keyword Edit in 3DEXPERIENCE, which includes a video showing
    how to install "inpRW" to **3D**EXPERIENCE and call "inpRW" from
    a Keyword Edit script.

Unless otherwise noted, if a term can refer to a module name or a
class name, I am using it to refer to the class name. Thus, inpKeyword
is short-hand for inpKeyword.inpKeyword in these update notes.


Performance Improvements:

 

N/A


Modified signatures:

 

  • * "inpKeyword.inpKeyword.__str__()"
    Added *includeSubData=True* parameter


Modified Modules:

 

This is a summary of all the modules which have seen some code
change. The details are in later sections of this document.

  • * "inpRW._inpR"
  • * "inpRW._inpW"
  • * "inpRW"
  • * "csid"
  • * "eval2"
  • * "inpDecimal"
  • * "inpKeyword"
  • * "inpRWErrors"
  • * "mesh"
  • * "config"
  • * "config_re"
  • * "elType"


Modified Classes:

 

This is a summary of all the classes which have seen some code
change. The details are in later sections of this document.

  • * "inpRW._inpR.Read"
  • * "inpRW._inpW.Write"
  • * "inpRW.inpRW"
  • * "csid.csid"
  • * "csid.csiKeyString"
  • * "eval2.eval2"
  • * "inpDecimal.inpDecimal"
  • * "inpKeyword"
  • * "inpRWErrors.ElementIncorrectNodeNumError"
  • * "mesh.Element"
  • * "mesh.TotalNodeMesh"


Modified Functions:

 

  • * "inpRW._inpR.Read._readInclude()"
    Improves handling of reading sub-files of *INCLUDE. Removes
    leading and trailing whitespace from sub-file name when
    opening.
  • * "inpRW._inpR.Read._readManifest()"
    Improves handling of reading sub-files of *MANIFEST.
  • * "inpRW._inpR.Read._splitKeywords()"
    More accurately identifies comments prior to the first keyword
    block by using the pattern from
    "_getLeadingCommentsPattern()".
  • * "inpRW._inpW.Write.writeBlocks()"
    Accounts for changes to sub-input file data storage.
  • * "inpRW._inpW.Write.writeInp()"
    No longer sets "_firstItem" to "False" after writing leading
    comments.
  • * "inpRW.inpRW.__init__()"
    The outputFolder of a sub-instance of "inpRW" will first try
    to be read from the *inpName* passed to the sub-instance,
    otherwise it will use "_parentINP.outputFolder". Sub-instances
    of "inpRW" now use their own "inpKeywordSequence" for
    "keywords" instead of directly sharing the "_parentINP's"
    keywords attribute. The "sub-inpKeywordSequence's" contents
    will still be propagated to the parent "inpRW" instance
    internally.
  • * "inpRW.inpRW.parse()"
    Changes to account for new code to identify leading comments.
  • * "csid.csid.__str__()"
    String keys and/or values will now include quote symbols
    around them.
  • * "csid.csiKeyString.__eq__()"
    Will now automatically convert the *other* key to a
    "csiKeyString" if it is not already.
  • * "eval2.eval2()"
    Catch "DecimalInfError" and convert the text ‘INF’ to an
    "inpString" instead of an "inpDecimal.inpDecimal".
  • * "inpDecimal.inpDecimal.__new__()"
    Raises a "DecimalInfError" if ‘INF’ (not case-sensitive) is in
    *inputStr*. This addresses a niche bug and should not affect
    most users.
  • * "inpKeyword.inpKeyword.parseKWData()"
    Improved handling of keywords with subdata (i.e. those with
    the INPUT parameter).
  • * "inpKeyword.inpKeyword._formatDataLabelDict()"
    Improved handling of comments for *ELEMENT keyword blocks,
    specifically those with element definitions spanning more than
    1 dataline.
  • * "inpKeyword.inpKeyword._parseData()"
    Corrected incorrect function call to "_parseRebarLayer()" with
    the correct call to "_parseDataRebarLayer()".
  • * "inpKeyword.inpKeyword._parseDataElement()"
    Modifications to correct inaccurate handling of multi-line
    and/or variable node element definitions.
  • * "inpKeyword.inpKeyword._parseDataRebarLayer()"
    Removed some old code which was causing an error.
  • * "inpKeyword.inpKeyword._parseInputString()"
    Moved call of "_setMiscInpKeywordAttrs()" from
    "_parseKWLine()" to this function. Corrects rare problem with
    important parameters for a keyword block not being on the
    first keyword line. For example, an error would be raised if
    the NSET parameter of an *NSET keyword block was not on the
    first keyword line.
  • * "inpKeyword.inpKeyword._parseKWLine()"
    Moved call of "_setMiscInpKeywordAttrs()" to
    "_parseInputString()" from this function.
  • * "inpKeyword.inpKeyword.__str__()"
    Added *includeSubData* parameter (default to "True"). This
    will not be used by end-users in most cases. Setting this
    parameter to "False" allows "inpRW" to omit writing sub data
    to the main input file. The default behavior is identical to
    the previous release.
  • * "inpRWErrors.ElementIncorrectNodeNumError.__str__()"
    New options to account for new *nodeNum* data types (i.e.
    "set" or "int").
  • * "mesh.Element.__init__()"
    Updated to account for changes to "_elementTypeDictionary".
  • * "mesh.Element.checkNumberNodes()"
    Updated to account for changes to "_elementTypeDictionary".
  • * "mesh.Element.__str__()"
    Corrected a problem with string production for multi-line
    elements.
  • * "mesh.TotalNodeMesh.setNodesConnectedElements()"
    Corrected a bug which overrode the elements connected to a
    node if the node was connected to different elements defined
    in multiple *ELEMENT keyword blocks.


Modified Attributes:

 

  • * "config._elementTypeDictionary"
    The value for each element is now the new "elType" class
    instead of a "csid". "inpRW" has been updated to account for
    this change, but any user scripts which directly accessed this
    dictionary will need to be updated to account for the new
    structure. This dictionary should include more information
    about each element type, (description, valid solver, and
    number of nodes), and it identifies variable node elements
    (they use "numNodesSet" instead of "numNodesSet").


New Functions:

 

  • * "inpRW._inpR.Read._getLeadingCommentsPattern()"
    Finds the location where the first keyword block begins and
    returns a regular expression pattern to identify that
    location.
  • * "inpRW.inpRW.__repr__()"
    Produces a useful string representation of an "inpRW"
    instance.
  • * "inpRW.inpRW.__str__()"
    Produces a string which helps identify the input file which
    corresponds to this "inpRW.inpRW" instance.
  • * "inpKeyword.findElementNodeNum()"
    Replaces and simplifies
    "inpKeyword.inpKeyword._getElementNodeNum()". With the
    exception of user elements, sub-structure elements, and
    variable number elements, all Abaqus elements have a static
    number of nodes which can define them. Thus, this function
    simply performs a dictionary lookup in most cases. For
    variable node elements, this function looks up the valid
    number of nodes to define the element. Then, it keeps reading
    data lines until it finds a line which does not end with a
    comma. If the number of nodes is in the set of valid node
    numbers for the element type, this function returns an
    integer. If the number of nodes is not in the set, an
    "ElementIncorrectNodeNumError" is raised. For undefined
    element type labels, this function will read datalines until
    it finds one which does not end with a comma. It will return
    the number of nodes it thinks the element has. For accurate
    results with user or sub-structure elements, the user should
    add an entry to "inp._elementTypeDictionary" before calling
    "inp.parse".


New Attributes:

 

  • * "inpKeyword.inpKeyword._subinps"
    Contains sub "inpRW" instances for *INCLUDE and *MANIFEST
    blocks.
  • * "config_re.re25"
    Used to find leading comments prior to first keyword.
  • * "config_re.re26"
    Used to check if an element definition has been completed.


New Modules:

 

  • * "elType"
    Provides the "elType" class.
  • * paramTypes
    Internal only module, not yet shipped with "inpRW". The
    handling of *PARAMETER definition and references needs to be
    improved, and this module is the foundation of that future
    work.


New Classes:

 

  • * "elType.elType"
    Stores information about an Abaqus element type. Used for each
    entry in "_elementTypeDictionary" instead of sub "csid"
    instances. Includes the element description from the Abaqus
    documentation, the valid solver(s), and the number of nodes
    needed to define the element.
  • * "inpRWErrors.DecimalInfError"
    This exception is raised by "inpDecimal.inpDecimal.__new__()"
    if the input string is ‘INF’. It is meant to handle a very
    niche error.


Removed:

 

  • * "inpKeyword.inpKeyword._getElementNodeNum()"
    Replaced with "inpKeyword.findElementNodeNum()".
  • * Removed python3_inpRW.bat and python3_inpRW.sh from the test
    suite.


Automated Tests:

 

Added automated tests to the following items:

  • * "elType" module:
    all class functions
  • * "inpKeyword" module:
    * "findElementNodeNum()"
  • * "printKWandSuboptions()"
  • * "writeKWandSuboptions()"
  • * "_formatDataOutput()"
  • * "_formatDataLabelDict()"
  • * test_Example_Scenarios This test runs the example script from
    Example Scenarios page of the documentation.


Misc:

 

N/A