Example Scenarios¶
This guide is intended to show some common and simple operations that can be performed with inpRW. It will introduce you to some of the key functions, but it does not provide the full documentation for these functions. That information can be found in the API Reference.
Example input file¶
This example input file was created in Abaqus/CAE and will be used for all examples mentioned in this article. To follow along, copy the text of the input file and save it as example_inp.inp.
Expand to see example_inp.inp
*Heading
** Job name: example_inp Model name: Model-1
** Generated by: Abaqus/CAE 2021.HF9
*Preprint, echo=NO, model=NO, history=NO, contact=NO
** ----------------------------------------------------------------
**
** PART INSTANCE: Part-1-1
**
*Node
1, 0., 0., 0.
2, 5., 0., 0.
3, 0., 5., 0.
4, 5., 5., 0.
*Element, type=S4R
1, 1, 2, 4, 3
*Nset, nset=Part-1-1_shell_set, generate
1, 4, 1
*Elset, elset=Part-1-1_shell_set
1,
** Section: shell_section
*Shell Section, elset=Part-1-1_shell_set, material=steel
0.5, 5
*System
*Nset, nset=Set-2
2,
*Nset, nset=Set-3
3,
*Nset, nset=Set-4
2, 4
*Nset, nset=origin
1,
**
** MATERIALS
**
*Material, name=steel
*Elastic
210000., 0.3
**
** BOUNDARY CONDITIONS
**
** Name: BC-2 Type: Displacement/Rotation
*Boundary
Set-2, 2, 2
Set-2, 3, 3
Set-2, 4, 4
Set-2, 5, 5
Set-2, 6, 6
** Name: BC-3 Type: Displacement/Rotation
*Boundary
Set-3, 1, 1
Set-3, 3, 3
Set-3, 4, 4
Set-3, 5, 5
Set-3, 6, 6
** Name: fix_origin Type: Displacement/Rotation
*Boundary
origin, 1, 1
origin, 2, 2
origin, 3, 3
origin, 4, 4
origin, 5, 5
origin, 6, 6
** ----------------------------------------------------------------
**
** STEP: Step-1
**
*Step, name=Step-1, nlgeom=YES
*Static
1., 1., 1e-05, 1.
**
** BOUNDARY CONDITIONS
**
** Name: Load Type: Displacement/Rotation
*Boundary
Set-4, 1, 1, 0.1
**
** OUTPUT REQUESTS
**
*Restart, write, frequency=0
*Output, field, frequency=1, variable=PRESELECT
**
** HISTORY OUTPUT: H-Output-1
**
*End Step
** ----------------------------------------------------------------
**
** STEP: Step-2
**
*Step, name=Step-2, nlgeom=YES
*Static
1., 1., 1e-05, 1.
**
** OUTPUT REQUESTS
**
*Restart, write, frequency=0
*Output, field, frequency=1, variable=PRESELECT
**
** HISTORY OUTPUT: H-Output-1
**
*End Step
Then run the following commands to generate the inp object:
import inpRW
inp = inpRW.inpRW('example_inp.inp', preserveSpacing=True, useDecimal=True, organize=True)
inp.parse()
You will obviously need to know the syntax of any keywords you wish to modify or create, so you will need to use the Abaqus Keywords Reference Guide to find this information.
This guide will use Python’s 0-based indexing for all such numbers.
Modifying data in an existing inpKeyword block¶
In this example, we will change the initial increment size in Step-1, and set the INC parameter of Step-1. We will use the following steps to accomplish this:
Find the
inpKeywordblocks to modifyModify the appropriate fields
First, we will change the initial increment size in Step-1. We need to find the inpKeyword block for Step-1.
In general, we can use findKeyword() to find a specific keyword block. However, inp has
two attributes which are shortcuts for locating steps. steps is a case- and space-insensitive
dictionary (csid) that uses the step name as the key. kwg is a csid with keys
corresponding to the unique keyword names in the input file. For example, inp.kwg['step']
is a list with all the *STEP keyword blocks, in the order they appear in the input file. Thus, we can easily select
the steps by their name or relative order using one of these two attributes.
For this example, we’ll use the steps approach. First, let’s check the contents of
inp.steps['step-1']:
In : inp.steps['step-1']
Out: [0, inpKeyword(name='Step', parameter=csid({' name': Step-1, ' nlgeom': YES}), data=[], path='self.keywords[16]', comments=[], suboptions=[...] Len 5)]
Since the entry contains a list with the relative step index (0) and the inpKeyword block,
and we want just the last item from the list (the inpKeyword block, we can use this command:
step1 = inp.steps['step-1'][-1]
Please note that steps is a csid with the step name as the key, and a value of
[relative step index, parsed keyword block]. If you would prefer to reference the steps by their relative order, you
could use the following command to retrieve the same block:
step1 = inp.sortKWs(inp.kwg['step'])[0]
Now that we found the step1 keyword block, we need to find the *STATIC block in that step. Since we created inp with organize=True, we can find *STATIC as the 0th suboption of step1 since the procedure must immediately follow *STEP in a valid input file. Then we merely change the 0th item of the 0th data line.
Please recall that floating point like numbers should be specified as decimals if
inpRW has been specified with useDecimal = True. We can also use inpDecimal,
which inherits from Decimal, but also captures the exact string formatting of its input string.
Since useDecimal was set when we instanced inpRW, we will use the following commands:
from inpDecimal import inpDecimal
static = step1.suboptions[0]
static.data[0][0] = inpDecimal('0.1')
Next, we will add the “INC=1000” parameter to the step1 inpKeyword block. We will accomplish this by creating
a new parameter csid with just the new parameter, and then updating the existing parameter csid.
We do not want to replace the parameter field (as was proposed in a previous version of the guide), as this would break
any shared memory references to items in the parameter field.
newpar = inpKeyword.createParamDictFromString(' INC=1000', ps=True)
step1.parameter.update(newpar)
Creating a new keyword block and inserting it into the inp data structure¶
There are several steps to creating a new inpKeyword block and inserting the block into inp.keywords.
Create the new
inpKeywordand populate the appropriate fieldsFind the desired location in
inp.keywordsto place the newinpKeywordblockInsert the new
inpKeywordUpdate
inp.keywords
In this example, we will create a “*OUTPUT, HISTORY” inpKeyword block, and add a “*ENERGY OUTPUT” suboption.
We need to import the inpKeyword module to create a new inpKeyword. We will use
makeDataList() to split up the output variables to multiple data lines.
We do not need to specify path for the inpKeyword; this will be handled by inp.updateInp(),
which will be called when we insert the keyword block.
from inpKeyword import inpKeyword
from misc_functions import makeDataList
vars = ['ALLAE', 'ALLCCDW', 'ALLCCE', 'ALLCCEN', 'ALLCCET', 'ALLCCSD', 'ALLCCSDN', 'ALLCCSDT', 'ALLCD',
'ALLFD', 'ALLIE', 'ALLKE', 'ALLPD', 'ALLSE', 'ALLVD', 'ALLDMD', 'ALLWK', 'ALLKL', 'ALLQB', 'ALLEE',
'ALLJD', 'ALLSD', 'ETOTAL']
eo = inpKeyword.inpKeyword(name='Energy Output', data=makeDataList(vars, 8))
eo._setMiscInpKeywordAttrs()
eo._dataParsed = True
oh = inpKeyword.inpKeyword(name='Output', parameter=inpKeyword.createParamDictFromString(' History, Frequency=1'))
oh._setMiscInpKeywordAttrs()
oh._dataParsed = True
oh.suboptions.append(eo)
Note that items for the inpKeyword can either be specified at creation, or they can be modified afterwards.
Let’s also add another keyword block; this one will modify the field controls. We’ll use a different technique to
create this inpKeyword block. We’ll specify the entire keyword block as a string, and let
the inpKeyword instance parse the string and generate the appropriate fields.
controlsKwText = '''*CONTROLS, parameter=field
,,,1.0'''
controlsKw = inpKeyword.inpKeyword(inputString=controlsKwText, **inp.inpKeywordArgs)
We pass inp.inpKeywordArgs to the inpKeyword instance to ensure we use the same parsing
settings we used for the rest of the input file.
Next, we need to find the right place to insert the new keyword blocks. Let’s insert it before *END STEP in step1.
step1 = inp.steps['Step-1'][-1] #step1 was assigned earlier in this tutorial, but it's included here for reference
step1end = inp.findKeyword(keywordName='End Step', parentBlock=step1)[0]
path = step1end.path
inp.insertKeyword(controlsKw, path=path, updateInpStructure=False)
inp.insertKeyword(oh, path=path)
Note that findKeyword() returns a list, so we grab the 0th (and only item if we setup the search properly).
Setting parentBlock for findKeyword() forces the function to check only suboptions of parentBlock.
Also note that insertKeyword() will place the new keyword ahead of whatever was at path. Thus, controlsKw
will be in front of step1end, and then oh will be in front of controlsKw.
Finally, note that insertKeyword() command will by default update path of every
inpKeyword (and their suboptions) in keywords after the location of the inserted keyword.
This can be turned off (set the updateInpStructure parameter to False) if you need to insert a lot of keywords and want to
update after inserting all keywords.
Deleting a keyword block¶
Deleting a keyword block is a relatively simple process.
Find the keyword block to delete
Call
deleteKeyword()
For this example, we will delete the *RESTART keyword blocks, as they are not used in this analysis, and the *OUTPUT, FIELD request in the second step, as it is unnecessary.
First, we find the *RESTART keyword blocks.
rblocks = inp.findKeyword(keywordName='Restart')
rblocks.reverse()
findKeyword() will return the valid blocks in the order it found them in the input file.
Recall that keywords inherits from the list type. If we remove an item from a list, all items after that item
will be moved to a different index. Thus, we reverse rblocks so we can delete from the back of the sequence, as
subsequent blocks to be deleted will be ahead of the previously deleted block in keywords.
Please note that you will normally not be able to sort a list of keywords using the default functions assorted with
list types if the input file was parsed with Organize = True. The keywords need to be sorted by their
path attributes, and this will be too complicated for the built-in ordering functions.
sortKWs() will sort any sequence of keywords in their proper order. findKeyword()
calls sortKWs(), so the keyword list will already be in order.
We will delete the keywords by passing path from a keyword block to the path parameter of deleteKeyword().
for block in rblocks:
inp.deleteKeyword(path=block.path, updateInpStructure=False)
inp.updateInp()
deleteKeyword() normally calls updateInp() when it executes, but we turned it
off in the loop. We manually call it after we deleted all the desired keyword blocks. Updating the inp structure can take
a significant amount of time for a large input file, especially if it is called multiple times unnecessarily.
Finally, we repeat the same process, except we are deleting just one block, the *OUTPUT, FIELD keyword block in the last step. Here are the commands for this task:
ofblock = inp.findKeyword(keywordName='Output', parentBlock=inp.sortKWs(inp.kwg['step'])[-1])[0]
inp.deleteKeyword(path=ofblock.path)
Writing the new input file¶
Now that we’ve made changes to the input file data structure, we merely need to write it out using the following command:
inp.writeInp()
This will create a new input file using the original name, but ending with “_NEW.inp”. If the original job was multiple files
(i.e. *INCLUDE), writeInp() will write the data out to the same relative file structure, while
appending jobSuffix to each file and adjusting the *INCLUDE keyword blocks in the parent file.
Complete Python Script¶
Here are all of the python commands used in this guide in the form of a single script:
Expand to see example.py
import inpRW
import inpKeyword
from inpDecimal import inpDecimal
from misc_functions import makeDataList
inp = inpRW.inpRW('example_inp.inp', preserveSpacing=True, useDecimal=True, organize=True)
inp.parse()
step1 = inp.steps['step-1'][-1]
static = step1.suboptions[0]
static.data[0][0] = inpDecimal('0.1')
newpar = inpKeyword.createParamDictFromString(' INC=1000', ps=True)
step1.parameter.update(newpar)
vars = ['ALLAE', 'ALLCCDW', 'ALLCCE', 'ALLCCEN', 'ALLCCET', 'ALLCCSD', 'ALLCCSDN', 'ALLCCSDT', 'ALLCD',
'ALLFD', 'ALLIE', 'ALLKE', 'ALLPD', 'ALLSE', 'ALLVD', 'ALLDMD', 'ALLWK', 'ALLKL', 'ALLQB', 'ALLEE',
'ALLJD', 'ALLSD', 'ETOTAL']
eo = inpKeyword.inpKeyword(name='Energy Output', data=makeDataList(vars, 8))
eo._setMiscInpKeywordAttrs()
eo._dataParsed = True
oh = inpKeyword.inpKeyword(name='Output', parameter=inpKeyword.createParamDictFromString(' History, Frequency=1'))
oh._setMiscInpKeywordAttrs()
oh._dataParsed = True
oh.suboptions.append(eo)
controlsKwText = '''*CONTROLS, parameter=field
,,,1.0'''
controlsKw = inpKeyword.inpKeyword(inputString=controlsKwText, **inp.inpKeywordArgs)
step1end = inp.findKeyword(keywordName='End Step', parentBlock=step1)[0]
path = step1end.path
inp.insertKeyword(controlsKw, path=path)
inp.insertKeyword(oh, path=path)
rblocks = inp.findKeyword(keywordName='Restart')
rblocks.reverse()
for block in rblocks:
inp.deleteKeyword(path=block.path, updateInpStructure=False)
inp.updateInp()
ofblock = inp.findKeyword(keywordName='Output', parentBlock=inp.sortKWs(inp.kwg['step'])[-1])[0]
inp.deleteKeyword(path=ofblock.path)
inp.writeInp()
Modified Input File¶
Here is the new input file, with all the changes performed in this guide:
Expand to see example_inp_NEW.inp
*Heading
** Job name: example_inp Model name: Model-1
** Generated by: Abaqus/CAE 2021.HF9
*Preprint, echo=NO, model=NO, history=NO, contact=NO
** ----------------------------------------------------------------
**
** PART INSTANCE: Part-1-1
**
*Node
1, 0., 0., 0.
2, 5., 0., 0.
3, 0., 5., 0.
4, 5., 5., 0.
*Element, type=S4R
1, 1, 2, 4, 3
*Nset, nset=Part-1-1_shell_set, generate
1, 4, 1
*Elset, elset=Part-1-1_shell_set
1,
** Section: shell_section
*Shell Section, elset=Part-1-1_shell_set, material=steel
0.5, 5
*System
*Nset, nset=Set-2
2,
*Nset, nset=Set-3
3,
*Nset, nset=Set-4
2, 4
*Nset, nset=origin
1,
**
** MATERIALS
**
*Material, name=steel
*Elastic
210000., 0.3
**
** BOUNDARY CONDITIONS
**
** Name: BC-2 Type: Displacement/Rotation
*Boundary
Set-2, 2, 2
Set-2, 3, 3
Set-2, 4, 4
Set-2, 5, 5
Set-2, 6, 6
** Name: BC-3 Type: Displacement/Rotation
*Boundary
Set-3, 1, 1
Set-3, 3, 3
Set-3, 4, 4
Set-3, 5, 5
Set-3, 6, 6
** Name: fix_origin Type: Displacement/Rotation
*Boundary
origin, 1, 1
origin, 2, 2
origin, 3, 3
origin, 4, 4
origin, 5, 5
origin, 6, 6
** ----------------------------------------------------------------
**
** STEP: Step-1
**
*Step, name=Step-1, nlgeom=YES, INC=1000
*Static
0.1, 1., 1e-05, 1.
**
** BOUNDARY CONDITIONS
**
** Name: Load Type: Displacement/Rotation
*Boundary
Set-4, 1, 1, 0.1
**
** OUTPUT REQUESTS
**
*Output, field, frequency=1, variable=PRESELECT
**
** HISTORY OUTPUT: H-Output-1
**
*Output, History, Frequency=1
*Energy Output
ALLAE,ALLCCDW,ALLCCE,ALLCCEN,ALLCCET,ALLCCSD,ALLCCSDN,ALLCCSDT
ALLCD,ALLFD,ALLIE,ALLKE,ALLPD,ALLSE,ALLVD,ALLDMD
ALLWK,ALLKL,ALLQB,ALLEE,ALLJD,ALLSD,ETOTAL
*CONTROLS, parameter=field
,,,1.0
*End Step
** ----------------------------------------------------------------
**
** STEP: Step-2
**
*Step, name=Step-2, nlgeom=YES
*Static
1., 1., 1e-05, 1.
**
** OUTPUT REQUESTS
**
*End Step