def generateLocalCoords(inst2SR, pointsBySR, asminfo, uniqueSuffix): # new dict to index points by part name, rather than by SHAPE_REPRESENTATION pointer localCoords = {} CGs = {} logger = logging.getLogger() try: for (key, value) in inst2SR.iteritems(): localCoords.update([[key, pointsBySR[value]]]) except IndexError: cad_library.exitwitherror('Error in creating the dictionary to index points by part name - ' + 'Probably due to corrupted or erronoeus STEP file', -1, 'AbaqusSTEP.py') # The step order needs to be increased by at least 1 to account for the fact that the step order # starts at 0 and not 1. # If root parent has only one child, then the Creo assembly is an assembly with only 1 immediate child. # In this case, the top level parent in the metrics file will not match the top level in the Creo file. # ie, test bench name != creo parent name. Increase the step order by 2 in this case. for child in asminfo.componentsdict.values(): if child.cyphyid == asminfo.root.cyphyid: continue # Ignore root entry if not child.is_assembly(): componentName = child.cadmodelname.upper() + uniqueSuffix + str(child.steporder + 1) CG = child.centerofgravity CGs.update([[componentName, (CG[0], CG[1], CG[2])]]) else: pass for (key, value) in CGs.iteritems(): localCoords[key].update([['CG_'+key, value]]) return localCoords, CGs
def runAbaqusStandard(myModel, args): """ Submit AbaqusStandard job and check for convergence. """ logger = logging.getLogger() jobName = 'staticFEAAnalysis' logger.info( "**********************************************************************************" + '\n') logger.info("Creating the static analysis job and submitting it" + '\n') try: myJob = mdb.Job(name=jobName, model=myModel.name, description='Static FEA job', multiprocessingMode=DEFAULT, numCpus=args.parallelCores, numDomains=args.parallelCores, memory=args.ramAllocated, memoryUnits=PERCENTAGE, parallelizationMethodExplicit=DOMAIN) except: cad_library.exitwitherror( 'Error during creating and submitting the standard ' 'nonadaptive analysis process\n', -1, 'AbaqusRun.py') try: myJob.submit() myJob.waitForCompletion() except: read_msg_file(jobName) read_msg_file(jobName) return jobName
def createThermalConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName=None): """ Dispatch function to create thermal boundary condition/load. """ if regionName is None: try: regionName = 'BodyThermConst_' + str(randint(1, 1000)) except AbaqusError: # try again in case generated int already was created regionName = 'BodyThermConst_' + str(randint(1, 1000)) if entry['Treatment'] == 'InitialTemperature': createInitialTemperatureConstraint(myModel, myAsm, entry) try: globals()[str('create' + entry['Treatment'] + 'Constraint')]( myModel, myAsm, entry, myStep, amp, instName, regionName) except KeyError: if entry['Treatment'] == 'AmbientTemperature': pass else: cad_library.exitwitherror( 'Specified thermal treatment ' + entry['Treatment'] + ' is not yet supported.', -1, 'AbaqusThermal.py')
def calcGeoScaleFac(unitLength): """ Calculates scaling factor to be applied to each numerical value's units. """ logger = logging.getLogger() logger.info("Calculating geometry scale factor" + '\n') # Calculate geometry scale factor (with respect to meters) if unitLength == 'millimeter': unitScale = 0.001 unitShort = 'mm' elif unitLength == 'inch': unitScale = 0.0254 unitShort = 'in' elif unitLength == 'meter': unitScale = 1.0 unitShort = 'm' else: cad_library.exitwitherror("ValueError: Length unit not supported", -1) logger.info( "**********************************************************************************" + '\n') logger.info("Length unit is " + str(unitShort) + '\n') logger.info("Unit scale of " + str(unitScale) + ' will be used during the analysis\n') logger.info( "**********************************************************************************" + '\n') return unitScale, unitShort
def defineThermalElements(myAsm, regionPick, args): """ Set thermal element type based on standard/explicit analysis. """ try: if args.dynamicExplicit: elemLibrary = EXPLICIT else: elemLibrary = STANDARD elemType1 = mesh.ElemType(elemCode=C3D20RT, elemLibrary=elemLibrary) elemType2 = mesh.ElemType(elemCode=UNKNOWN_WEDGE, elemLibrary=elemLibrary) elemType3 = mesh.ElemType(elemCode=C3D10MT, elemLibrary=elemLibrary, secondOrderAccuracy=OFF, hourglassControl=DEFAULT, distortionControl=DEFAULT) myAsm.setMeshControls(regions=regionPick, elemShape=TET, technique=FREE, sizeGrowthRate=1.05) myAsm.setElementType(regions=(regionPick, ), elemTypes=( elemType1, elemType2, elemType3, )) except: cad_library.exitwitherror( 'Error trying to assign thermal-type elements for mesh.', -1, 'AbaqusThermal.py')
def generateThermalConstructs(thermalSetXML, loadBCLib, asminfo): """ Dispatch function to create entry in load dictionary for all thermal constructs. """ for thermal in thermalSetXML: # for each load definition: loadBCLib.append({}) # add new dictionary thermalLoadType = thermal.get( 'LoadType') # look for SpecifiedTemperature load if (thermalLoadType == 'InitialTemperature' or thermalLoadType == 'AmbientTemperature'): loadBCLib.pop() continue else: check_for_conflicting_loads(loadBCLib, thermal) try: if thermalLoadType == 'Convection': generateConvectionDict(thermal, loadBCLib, thermalSetXML) else: globals()[str('generate' + thermalLoadType + 'Dict')]( thermal, loadBCLib) except KeyError: cad_library.exitwitherror( 'Specified thermal treatment is not yet supported.', -1, 'AbaqusThermal.py') if thermal.find( 'Geometry' ): # Apply construct only to specified geometry, otherwise to whole body if thermalLoadType == 'HeatGeneration': msg = 'Heat Generation block incorrectly applied to geometry construct within a component. ' + \ 'Block should only be applied to entire component/assembly. Please revise ' + \ 'your GME model and re-run simulation.' cad_library.exitwitherror(msg, -1, 'AbaqusThermal.py') grabGeometry(thermal.find('Geometry'), loadBCLib) loadBCLib[-1].update([['Component', False]]) else: # If load is applied to whole component, need to check if component has children. # If it does, need to create library entries for each child, as the assembly isn't # added to Abaqus model, each of its children are. compChildren = asminfo.componentsdict[thermal.find( 'Component').get('ComponentID')].children if len(compChildren) > 0: # Finish current entry, but set ComponentID to first child loadBCLib[-1].update([['ComponentID', compChildren[0].cyphyid]]) loadBCLib[-1].update([['Component', True] ]) # Apply constraint to entire instance for child in xrange(1, len(compChildren)): # For remaining children (if app.), copy previous entry under remaining ComponentIDs # Can't use line below as set comprehension not available in Python 2.6 # loadBCLib.append({x: loadBCLib[-1][x] for x in loadBCLib[-1].keys()}) d = {} for x in loadBCLib[-1].keys(): d[x] = loadBCLib[-1][x] loadBCLib.append(d) loadBCLib[-1]['ComponentID'] = compChildren[child].cyphyid else: loadBCLib[-1].update([[ 'ComponentID', thermal.find('Component').get('ComponentID') ]]) loadBCLib[-1].update([['Component', True] ]) # Apply constraint to entire instance
def createINP(myAsm, key, myModel, parallelCores, ramAllocated): """ Create an INP file of the current part. """ eRange = len(myAsm.instances[key].elements ) # Determine the number of mesh elements of the current part # Create a set form those elements and name it as wholeInstance myAsm.Set(elements=myAsm.instances[key].elements[0:eRange], name='wholeInstance') inpName = key + '_temp' # Determine the name of the INP file based on the name of the current part try: myJob = mdb.Job(name=inpName, model=myModel.name, description='Static FEA job', multiprocessingMode=DEFAULT, numCpus=parallelCores, numDomains=1, memory=ramAllocated, parallelizationMethodExplicit=DOMAIN ) # Create a job inside the Abaqus/CAE myJob.writeInput( consistencyChecking=ON) # Create an input file from that job except: cad_library.exitwitherror('Error during creating the INP file', -1, 'AbaqusCAE_ADAMS.py') return inpName
def createHeatGenerationConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply heat generation load in Abaqus model. """ logger = logging.getLogger() try: #MPdict = myAsm.getMassProperties(regions=(myAsm.instances[instName],),) #vol = MPdict['volume'] #if vol is None: # cad_library.exitwitherror('Error getting volume from part instance ' + instName, -1, 'AbaqusThermal.py') #else: #vol_heat_rate = float(entry['HeatGeneration']) / float(vol) logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Heat Generation. \n') region = (myAsm.instances[instName].cells, ) HeatGenName = regionName + '-HeatGen' myModel.BodyHeatFlux(name=HeatGenName, createStepName=myStep.name, region=region, magnitude=float(entry['HeatGeneration']), distributionType=UNIFORM, amplitude=amp) except: cad_library.exitwitherror( 'Error creating the Heat Generation constraint.', -1, 'AbaqusThermal.py')
def setInitialTemperature(thermal, myAsm, instName): """ Create and set initial temperature. Only applied to component level, not geometry. """ logger = logging.getLogger() try: logger.info("Defining initial temperature for " + str(thermal.find('Component').get('ComponentID')) + '\n') except AttributeError: cad_library.exitwitherror( 'Initial temperature specified for geometric subset of component. ' + 'Initial temperature can only be applied to component/assembly.', -1) tUnits = thermal.get('Unit') tMagUnconv = float(thermal.get('Value')) # magnitude of temperature tMag = tempConv(tMagUnconv, tUnits) logger.info("Initial Temperature Magnitude = " + str(tMag) + '\n') try: region = (myAsm.instances[instName].cells, ) initTempName = instName + '-InitTemp' mdb.models['Model-1'].Temperature( name=initTempName, createStepName='Initial', region=region, distributionType=UNIFORM, crossSectionDistribution=CONSTANT_THROUGH_THICKNESS, magnitudes=(tMag, )) except: cad_library.exitwitherror('Error setting initial temperature.', -1, 'AbaqusThermal.py')
def runAbaqusDynamic(myModel, args): """ Submit dynamic step job (either AbaqusStandard or AbaqusExplicit) and check for convergence. """ logger = logging.getLogger() jobName = 'dynamicFEAAnalysis' logger.info("**********************************************************************************" + '\n') logger.info("Creating the dynamic analysis job and submitting it" + '\n') try: myJob = mdb.Job(name=jobName, model=myModel.name, description='Dynamic FEA job', multiprocessingMode=DEFAULT, numCpus=args.parallelCores, numDomains=args.parallelCores, memory=args.ramAllocated, memoryUnits=PERCENTAGE, parallelizationMethodExplicit=DOMAIN) except: cad_library.exitwitherror('Error during creating and submitting the dynamic ' + 'analysis process.', -1, 'AbaqusRun.py') # MSG file is not populated for Abaqus/Explicit runs try: myJob.submit() myJob.waitForCompletion() except: if not args.dynamicExplicit: read_msg_file(jobName) # Check log file for issue else: cad_library.exitwitherror('Explicit Dynamic job failed. Please check logs, message files, etc. ' 'Contact ISIS helpdesk if needed.', -1, 'AbaqusRun.py') if not args.dynamicExplicit: read_msg_file(jobName) return jobName
def createConvectionConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply convection interaction in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: regionMask = myMask(entry['FaceIDs'][0]) maskRegion = myAsm.instances[instName].faces.getSequenceFromMask( mask=(regionMask, ), ) else: regionMask = myAsm.instances[instName].faces maskRegion = regionMask.getSequenceFromMask( mask=('[#ff ]', ), ) # Apply to entire body logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Convection. \n') region = myAsm.Surface(side1Faces=maskRegion, name=regionName) convecName = regionName + '-ConvecHeat' myModel.FilmCondition(name=convecName, createStepName=myStep.name, surface=region, definition=EMBEDDED_COEFF, filmCoeff=entry['Convection'], filmCoeffAmplitude=amp, sinkTemperature=entry['AmbientTemperature'], sinkAmplitude=amp) except: cad_library.exitwitherror('Error creating convection heat constraint.', -1, 'AbaqusThermal.py')
def run_patran_post_processing(self): # Post-Processing call patran_pp_name = 'Patran_PP.py' patran_pp_path = os.path.join(self.meta_bin_cad, patran_pp_name) if not os.path.isfile(patran_pp_path): cad_library.exitwitherror( 'Can\'t find {}. Do you have the META toolchain installed properly?', -1, format(patran_pp_name)) post_processing_args = "{} {} {}".format( "..\\AnalysisMetaData.xml", "..\\..\\RequestedMetrics.xml", "..\\..\\testbench_manifest.json" ) pp_command = 'runPostProcessing.bat' with open(pp_command, 'wb') as cmd_file_out: meta_python_path = sys.executable cmd_text = '"{}" "{}" {}'.format( meta_python_path, patran_pp_path, post_processing_args) cmd_file_out.write(cmd_text) print("Starting {}...".format(pp_command)) pp_result = self.call_subprocess(pp_command) return pp_result
def checkOverlap(odb_inst, jobName): """ Check ODB file for overlapping nodes (components) and exit if any exist. """ logger = logging.getLogger() overlapCheck = False try: overlapCheck = odb_inst.rootAssembly.elementSets[ 'ErrElemVolSmallNegZero'] except: pass if overlapCheck: logger.info( "There are elements in the model with zero or negative volume" + '\n') logger.info("Possibly parts are overlapping each other excessively" + '\n') logger.info("Unable to run the analyis, please fix your CAD model" + '\n') logger.info("Terminating" + '\n') CreateOverlapPNG(jobName, overlapCheck, os.getcwd()) logger.info( "Check \"results/abcdef/Analysis/Abaqus/Contour_and_BC_plots/Overlapping_Elements_#.png\" " "files to determine problematic parts/elements" + '\n') cad_library.exitwitherror( 'Overlapping parts in thed design. Please see log file.', -1, 'AbaqusDataCheck.py')
def createHeatFluxConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply surface heat flux load in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: regionMask = myMask(entry['FaceIDs'][0]) maskRegion = myAsm.instances[instName].faces.getSequenceFromMask( mask=(regionMask, ), ) else: regionMask = myAsm.instances[instName].faces maskRegion = regionMask.getSequenceFromMask( mask=('[#ff ]', ), ) # Apply to entire body logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Surface Heat Flux. \n') region = myAsm.Surface(side1Faces=maskRegion, name=regionName) surfFluxName = regionName + '-SurfHeatFlux' myModel.SurfaceHeatFlux(name=surfFluxName, createStepName=myStep.name, region=region, magnitude=entry['HeatFlux'], distributionType=UNIFORM, amplitude=amp) except: cad_library.exitwitherror( 'Error creating surface heat flux constraint.', -1, 'AbaqusThermal.py')
def createSpecifiedTemperatureConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply specified temperature boundary condition in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: tempFace = entry['FaceIDs'][0] instances = entry['Instance'] faces = myAsm.instances[instances].faces region = regionToolset.Region(faces=faces[tempFace:tempFace + 1]) else: region = (myAsm.instances[instName].cells, ) # Apply BC to entire part logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Specified Temperature. \n') specTempName = regionName + '-SpecTemp' myModel.TemperatureBC(name=specTempName, createStepName=myStep.name, region=region, magnitude=entry['SpecifiedTemperature'], distributionType=UNIFORM, amplitude=amp) # create specified temperature BC except: cad_library.exitwitherror( 'Error creating specified temperature constraint.', -1, 'AbaqusThermal.py')
def modifyMetaDataFile(xmlname, asminfo, uniqueSuffix, asmIdentifier): """ Update meta data file with internal unique Abaqus instance names. """ try: tree = ET.ElementTree() tree.parse(xmlname) except Exception, inst: cad_library.exitwitherror('Unexpected error opening ' + xmlname + str(inst), 1, 'AbaqusMain.py')
def run_patran_post_processing(self): # Post-Processing call patran_pp_name = 'Patran_PP.py' patran_pp_path = os.path.join(self.meta_bin_cad, patran_pp_name) if not os.path.isfile(patran_pp_path): cad_library.exitwitherror( 'Can\'t find {}. Do you have the META toolchain installed properly?', -1, format(patran_pp_name)) post_processing_args = "{} {} {}".format( "..\\AnalysisMetaData.xml", "..\\..\\RequestedMetrics.xml", "..\\..\\testbench_manifest.json") pp_command = 'runPostProcessing.bat' with open(pp_command, 'wb') as cmd_file_out: meta_python_path = sys.executable cmd_text = '"{}" "{}" {}'.format(meta_python_path, patran_pp_path, post_processing_args) cmd_file_out.write(cmd_text) print("Starting {}...".format(pp_command)) pp_result = self.call_subprocess(pp_command) return pp_result
def SetupViewportPNG(myOdb, fileName, reqMetricSet, maxStressStep=None): try: myViewport = session.Viewport(name='Contour Plot', origin=(0, 0), width=200, height=100) myViewport.setValues(displayedObject=myOdb) mySteps = myOdb.steps numSteps = len(mySteps) session.printOptions.setValues(rendition=COLOR, vpDecorations=OFF, vpBackground=OFF) text = {'S': 'MPa', 'U': 'm', 'TEMP': 'K'} for metric in reqMetricSet: t = myOdb.userData.Text(name='Text-1', text='Units: ' + text[metric], offset=(0, 0), font='-*-arial-medium-r-normal-*-*-120-*-*-p-*-*-*') myViewport.plotAnnotation(annotation=t) if metric == 'S' and maxStressStep in mySteps.keys(): stepKey = mySteps.keys()[maxStressStep] myViewport.odbDisplay.commonOptions.setValues(visibleEdges=EXTERIOR) step = mySteps[stepKey] CreateViewportPNG(myOdb, metric, fileName, myViewport, step) else: for i in range(numSteps): myViewport.odbDisplay.commonOptions.setValues(visibleEdges=EXTERIOR) stepKey = mySteps.keys()[i] step = mySteps[stepKey] CreateViewportPNG(myOdb, metric, fileName, myViewport, step) except KeyError: cad_library.exitwitherror(('KeyError', -1, 'ABQ_CompletePostProcess.py [SetupViewportPNG()]')) except AbaqusException, value: cad_library.exitwitherror('AbaqusException: ' + str(value), -1, 'ABQ_CompletePostProcess.py [SetupViewportPNG]')
def getUnitLength(asminfo): distUnits = [] for child in asminfo.componentsdict.values(): distUnits.append(child.units.distance) if not len(set(distUnits)) == 1: cad_library.exitwitherror("Non-consistent unit scale. All parts should " "have the same distance units.", -1) return distUnits[0]
def CreateOverlapPNG(jobName, overlapCheck, root): """ Generate PNG files displaying locations of overlapping nodes relative to entire design. """ try: myOdb = odbAccess.openOdb(path=jobName + '.odb') resultsDir = os.path.join(root, jobName) if not os.path.exists(resultsDir): os.mkdir(resultsDir) mainDir = os.path.join(root, jobName, "Contour_and_BC_plots") if not os.path.exists(mainDir): os.mkdir(mainDir) os.chdir(mainDir) myViewport = session.viewports['Viewport: 1'] myViewport.setValues(displayedObject=myOdb) for k in range(len(overlapCheck.elements)): overlappingElems = overlapCheck.elements[k] for i in range(len(overlappingElems)): overlappingElem = overlappingElems[i] highlight(overlappingElem) myViewport.view.setValues(session.views['Iso']) myViewport.view.zoom(0.8) session.printToFile("Overlapping_Elements_1", PNG, (myViewport, )) myViewport.view.setValues(cameraPosition=(987.505, -35.8282, 7.68834), cameraUpVector=(0, 1, 0)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_2", PNG, (myViewport, )) session.viewports['Viewport: 1'].view.setValues( nearPlane=757.99, farPlane=1200.36, width=542.18, height=365.72, cameraPosition=(0.996667, 36.7201, -977.094), cameraUpVector=(0.0, 1.0, 0.0), cameraTarget=(-0.87486, -35.267, 7.11584)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_3", PNG, (myViewport, )) session.viewports['Viewport: 1'].view.setValues( nearPlane=759.096, farPlane=1215.06, width=542.971, height=366.255, cameraPosition=(-91.9079, -1009.75, -32.4658), cameraUpVector=(-1.0, 0.0, 0.0), cameraTarget=(1.67948, -27.8817, -0.616374)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_4", PNG, (myViewport, )) except: cad_library.exitwitherror('Error in creating overlap PNG files.', -1, 'AbaqusDataCheck.py') os.chdir(root)
def modifyMetaDataFile(xmlname, asminfo, uniqueSuffix, asmIdentifier): """ Update meta data file with internal unique Abaqus instance names. """ try: tree = ET.ElementTree() tree.parse(xmlname) except Exception, inst: cad_library.exitwitherror( 'Unexpected error opening ' + xmlname + str(inst), 1, 'AbaqusMain.py')
def runNastran(): os.chdir(os.getcwd() + '\\Analysis\\Nastran') callsubprocess(sys.executable + ' \"' + cad_library.META_PATH + 'bin\\CAD\Nastran.py\" ..\\Nastran_mod.nas') #if result != 0: # cad_library.exitwitherror('CADJobDriver.py: Nastran.py returned with code: ' + str(result),-1) patranscript = cad_library.META_PATH + 'bin\\CAD\\Patran_PP.py' if not os.path.isfile(patranscript): cad_library.exitwitherror('Can\'t find ' + patranscript + '. Do you have the META toolchain installed properly?', -1) callsubprocess(sys.executable + ' \"' + patranscript + '\" ..\\Nastran_mod.nas Nastran_mod.xdb ..\\AnalysisMetaData.xml ..\\..\\RequestedMetrics.xml ..\\..\\testbench_manifest.json')
def getUnitLength(asminfo): distUnits = [] for child in asminfo.componentsdict.values(): distUnits.append(child.units.distance) if not len(set(distUnits)) == 1: cad_library.exitwitherror( "Non-consistent unit scale. All parts should " "have the same distance units.", -1) return distUnits[0]
def ADAMS_setup_INP(myAsm, key, asminfo, instRef, instAssemblyRef, myModel, parallelCores, ramAllocated): """ Manipulates Abaqus model to provide correctly formatted INP file. """ try: lodFileID = instRef[key]['ComponentID'] except KeyError: try: lodFileID = instAssemblyRef[key]['ComponentID'] except KeyError: cad_library.exitwitherror('LOD file not found for ' + str(key), -1, 'AbaqusCAE_ADAMS.py') lodFileName = 'LT_' + lodFileID + '.lod' lodFilePath = os.path.join(os.getcwd(), lodFileName) # Constrain every vertice of the part in x, y and z directions with soft-springs constrainWithSoftSprings(key, myAsm) # Read the markers from the LOD files and define them in the Abaqus assembly as reference points refPointRef = readAndDefineMarkers(myAsm, lodFilePath) # Get the nodes inside the bounding box of the part which is connected to the current part (refPntOtherComp, sortedOtherComp) = getBoundingNodes(asminfo, key, instRef, myModel, myAsm) # Define MPCs between the reference points (markers) and the corresponding surfaces on the part defineMPCs(sortedOtherComp, refPntOtherComp, refPointRef, instRef, myAsm, myModel, key) inpName = createINP(myAsm, key, myModel, parallelCores, ramAllocated) # Create an INP file of the current part # Clean the current model of the Abaqus/CAE from the previous part itself and its constraints cleanModel(myModel, myAsm) # Define the previously created INP file of the current part as the temporary INP file inpTempFileName = inpName + '.inp' # Define the location of the temporary INP file and store it inpTempFilePath = os.path.join(os.getcwd(), inpTempFileName) with open(inpTempFilePath, 'r') as inpTempFile: # Determine upto which point the temporary INP file needs to be merged with the final INP file stopLine = parseInpTemp(inpTempFile) with open(lodFilePath, 'r') as lodFile: # Determine from which point the LOD file generated by Adams needs to be merged with the final INP file startLine = parseLOD(lodFile) with open(inpTempFilePath, 'r') as inpTempFile: with open(lodFilePath, 'r') as lodFile: # Define the name of the final INP file by using the name of the current part inpFileName = key + '.inp' # Define the location of the final INP file and store it inpFilePath = os.path.join(os.getcwd(), inpFileName) # Create the final INP file by opening and closing it open(inpFilePath, 'a').close() # Merge temporary INP file and LOD file to create the final INP file createFinalInp(inpFilePath, inpTempFile, lodFile, stopLine, startLine) os.remove(inpTempFilePath)
def runCreoAssembler(): isisext = os.environ.get('PROE_ISIS_EXTENSIONS') if isisext is None: cad_library.exitwitherror ('PROE_ISIS_EXTENSIONS env. variable is not set. Do you have the META toolchain installed properly?', -1) createasm = os.path.join(isisext,'bin','CADCreoParametricCreateAssembly.exe') if not os.path.isfile(createasm): cad_library.exitwitherror ('Can\'t find CADCreoParametricCreateAssembly.exe. Do you have the META toolchain installed properly?', -1) #logdir = os.path.join(workdir,'log') result = os.system('\"' + createasm + '" -i CADAssembly.xml') return result
def callsubprocess(cmd, failonexit = True): global outputcmds if outputcmds == True: print cmd try: result = subprocess.call(cmd) except Exception as e: cad_library.exitwitherror('Failed to execute: ' + cmd + ' Error is: ' + e.message, -1) if result != 0 and failonexit: cad_library.exitwitherror('The command ' + cmd + ' exited with value: ' + result, -1)
def callsubprocess(cmd, failonexit=True): global outputcmds if outputcmds == True: print cmd try: result = subprocess.call(cmd) except Exception as e: cad_library.exitwitherror( 'Failed to execute: ' + cmd + ' Error is: ' + e.message, -1) if result != 0 and failonexit: cad_library.exitwitherror( 'The command ' + cmd + ' exited with value: ' + result, -1)
def createInitialTemperatureConstraint(myModel, myAsm, entry): """ Apply initial temperature boundary condition in Abaqus model. """ try: instances = entry['Instance'] region = (myAsm.instances[instances].cells, ) initTempName = instances + '-InitTemp' myModel.Temperature(name=initTempName, createStepName='Initial', region=region, distributionType=UNIFORM, crossSectionDistribution=CONSTANT_THROUGH_THICKNESS, magnitudes=entry['InitialTemperature']) except: cad_library.exitwitherror('Error creating initial temperature.', -1, 'AbaqusThermal.py')
def CalculateMetrics(frdfile, components, reqMetricsFile, elementMapFile): # Parse FRD results file logger = logging.getLogger() logger.info('FUNCTION: CalculateMetrics\n') frd = cad_library.CalculixResults() frd.parse_frd(frdfile + '.frd') # Determine which metrics are requested for which GME component instance IDs try: tree = ElementTree() tree.parse(reqMetricsFile) except Exception, inst: cad_library.exitwitherror('Unexpected error opening ' + reqMetricsFile + str(inst), -1)
def runCalculix(): isisext = os.environ['PROE_ISIS_EXTENSIONS'] os.chdir(os.getcwd() + "\\Analysis\\Calculix") if isisext is None: cad_library.exitwitherror ('PROE_ISIS_EXTENSIONS env. variable is not set. Do you have the META toolchain installed properly?', -1) deckconvexe = os.path.join(isisext,'bin','DeckConverter.exe') callsubprocess(deckconvexe + ' -i ..\\Nastran_mod.nas') with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'Software\CMS\CalculiX', 0, _winreg.KEY_READ | _winreg.KEY_WOW64_32KEY) as key: bconvergedpath = _winreg.QueryValueEx(key, 'InstallLocation')[0] callsubprocess(bconvergedpath+'\\CalculiX\\bin\\ccx.bat -i ..\\Nastran_mod') metapython = os.path.join(cad_library.META_PATH, 'bin', 'Python27', 'Scripts', 'python.exe') calculix_pp = os.path.join(cad_library.META_PATH, 'bin', 'CAD', 'ProcessCalculix.py') callsubprocess(metapython + " " + calculix_pp + " -o ..\\Nastran_mod.frd -p ..\\AnalysisMetaData.xml -m ..\\..\\RequestedMetrics.xml -j ..\\..\\testbench_manifest.json -e PSolid_Element_Map.csv")
def runNastran(): os.chdir(os.getcwd() + '\\Analysis\\Nastran') callsubprocess(sys.executable + ' \"' + cad_library.META_PATH + 'bin\\CAD\Nastran.py\" ..\\Nastran_mod.nas') #if result != 0: # cad_library.exitwitherror('CADJobDriver.py: Nastran.py returned with code: ' + str(result),-1) patranscript = cad_library.META_PATH + 'bin\\CAD\\Patran_PP.py' if not os.path.isfile(patranscript): cad_library.exitwitherror( 'Can\'t find ' + patranscript + '. Do you have the META toolchain installed properly?', -1) callsubprocess( sys.executable + ' \"' + patranscript + '\" ..\\Nastran_mod.nas Nastran_mod.xdb ..\\AnalysisMetaData.xml ..\\..\\RequestedMetrics.xml ..\\..\\testbench_manifest.json' )
def runCreoAssembler(): isisext = os.environ.get('PROE_ISIS_EXTENSIONS') if isisext is None: cad_library.exitwitherror( 'PROE_ISIS_EXTENSIONS env. variable is not set. Do you have the META toolchain installed properly?', -1) createasm = os.path.join(isisext, 'bin', 'CADCreoParametricCreateAssembly.exe') if not os.path.isfile(createasm): cad_library.exitwitherror( 'Can\'t find CADCreoParametricCreateAssembly.exe. Do you have the META toolchain installed properly?', -1) #logdir = os.path.join(workdir,'log') result = os.system('\"' + createasm + '" -i CADAssembly.xml') return result
def CreateOverlapPNG(jobName, overlapCheck, root): """ Generate PNG files displaying locations of overlapping nodes relative to entire design. """ try: myOdb = odbAccess.openOdb(path=jobName + '.odb') resultsDir = os.path.join(root, jobName) if not os.path.exists(resultsDir): os.mkdir(resultsDir) mainDir = os.path.join(root, jobName, "Contour_and_BC_plots") if not os.path.exists(mainDir): os.mkdir(mainDir) os.chdir(mainDir) myViewport = session.viewports['Viewport: 1'] myViewport.setValues(displayedObject=myOdb) for k in range(len(overlapCheck.elements)): overlappingElems = overlapCheck.elements[k] for i in range(len(overlappingElems)): overlappingElem = overlappingElems[i] highlight(overlappingElem) myViewport.view.setValues(session.views['Iso']) myViewport.view.zoom(0.8) session.printToFile("Overlapping_Elements_1", PNG, (myViewport,)) myViewport.view.setValues(cameraPosition=(987.505, -35.8282, 7.68834), cameraUpVector=(0, 1, 0)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_2", PNG, (myViewport,)) session.viewports['Viewport: 1'].view.setValues(nearPlane=757.99, farPlane=1200.36, width=542.18, height=365.72, cameraPosition=(0.996667, 36.7201, -977.094), cameraUpVector=(0.0, 1.0, 0.0), cameraTarget=(-0.87486, -35.267, 7.11584)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_3", PNG, (myViewport,)) session.viewports['Viewport: 1'].view.setValues(nearPlane=759.096, farPlane=1215.06, width=542.971, height=366.255, cameraPosition=(-91.9079, -1009.75, -32.4658), cameraUpVector=(-1.0, 0.0, 0.0), cameraTarget=(1.67948, -27.8817, -0.616374)) myViewport.view.fitView() session.printToFile("Overlapping_Elements_4", PNG, (myViewport,)) except: cad_library.exitwitherror('Error in creating overlap PNG files.', -1, 'AbaqusDataCheck.py') os.chdir(root)
def call_subprocess(self, cmd, failonexit=True): global print_cmds if print_cmds is True: print cmd result = 0 try: result = subprocess.call(cmd) except Exception as e: cad_library.exitwitherror('Failed to execute: ' + cmd + ' Error is: ' + e.message, -1) if result != 0 and failonexit: cad_library.exitwitherror('The command {} exited with value: {}'.format(cmd, result), -1) return result
def createInitialTemperatureConstraint(myModel, myAsm, entry): """ Apply initial temperature boundary condition in Abaqus model. """ try: instances = entry['Instance'] region = (myAsm.instances[instances].cells, ) initTempName = instances + '-InitTemp' myModel.Temperature( name=initTempName, createStepName='Initial', region=region, distributionType=UNIFORM, crossSectionDistribution=CONSTANT_THROUGH_THICKNESS, magnitudes=entry['InitialTemperature']) except: cad_library.exitwitherror('Error creating initial temperature.', -1, 'AbaqusThermal.py')
def defineThermalElements(myAsm, regionPick, args): """ Set thermal element type based on standard/explicit analysis. """ try: if args.dynamicExplicit: elemLibrary = EXPLICIT else: elemLibrary = STANDARD elemType1 = mesh.ElemType(elemCode=C3D20RT, elemLibrary=elemLibrary) elemType2 = mesh.ElemType(elemCode=UNKNOWN_WEDGE, elemLibrary=elemLibrary) elemType3 = mesh.ElemType(elemCode=C3D10MT, elemLibrary=elemLibrary, secondOrderAccuracy=OFF, hourglassControl=DEFAULT, distortionControl=DEFAULT) myAsm.setMeshControls(regions=regionPick, elemShape=TET, technique=FREE, sizeGrowthRate=1.05) myAsm.setElementType(regions=(regionPick,), elemTypes=(elemType1, elemType2, elemType3,)) except: cad_library.exitwitherror('Error trying to assign thermal-type elements for mesh.', -1, 'AbaqusThermal.py')
def generateThermalConstructs(thermalSetXML, loadBCLib, asminfo): """ Dispatch function to create entry in load dictionary for all thermal constructs. """ for thermal in thermalSetXML: # for each load definition: loadBCLib.append({}) # add new dictionary thermalLoadType = thermal.get('LoadType') # look for SpecifiedTemperature load if (thermalLoadType == 'InitialTemperature' or thermalLoadType == 'AmbientTemperature'): loadBCLib.pop() continue else: check_for_conflicting_loads(loadBCLib, thermal) try: if thermalLoadType == 'Convection': generateConvectionDict(thermal, loadBCLib, thermalSetXML) else: globals()[str('generate' + thermalLoadType + 'Dict')](thermal, loadBCLib) except KeyError: cad_library.exitwitherror('Specified thermal treatment is not yet supported.', -1, 'AbaqusThermal.py') if thermal.find('Geometry'): # Apply construct only to specified geometry, otherwise to whole body if thermalLoadType == 'HeatGeneration': msg = 'Heat Generation block incorrectly applied to geometry construct within a component. ' + \ 'Block should only be applied to entire component/assembly. Please revise ' + \ 'your GME model and re-run simulation.' cad_library.exitwitherror(msg, -1, 'AbaqusThermal.py') grabGeometry(thermal.find('Geometry'), loadBCLib) loadBCLib[-1].update([['Component', False]]) else: # If load is applied to whole component, need to check if component has children. # If it does, need to create library entries for each child, as the assembly isn't # added to Abaqus model, each of its children are. compChildren = asminfo.componentsdict[thermal.find('Component').get('ComponentID')].children if len(compChildren) > 0: # Finish current entry, but set ComponentID to first child loadBCLib[-1].update([['ComponentID', compChildren[0].cyphyid]]) loadBCLib[-1].update([['Component', True]]) # Apply constraint to entire instance for child in xrange(1, len(compChildren)): # For remaining children (if app.), copy previous entry under remaining ComponentIDs # Can't use line below as set comprehension not available in Python 2.6 # loadBCLib.append({x: loadBCLib[-1][x] for x in loadBCLib[-1].keys()}) d = {} for x in loadBCLib[-1].keys(): d[x] = loadBCLib[-1][x] loadBCLib.append(d) loadBCLib[-1]['ComponentID'] = compChildren[child].cyphyid else: loadBCLib[-1].update([['ComponentID', thermal.find('Component').get('ComponentID')]]) loadBCLib[-1].update([['Component', True]]) # Apply constraint to entire instance
def run_creo_assembler(self): create_asm = os.path.join(cad_library.META_PATH, 'bin', 'CAD', 'Creo', 'bin', 'CADCreoParametricCreateAssembly.exe') if not os.path.isfile(create_asm): cad_library.exitwitherror( 'Cannot find CADCreoParametricCreateAssembly.exe. Do you have the META toolchain installed properly?', -1) # logdir = os.path.join(workdir, 'log') result = os.system('\"' + create_asm + '" -i CADAssembly.xml') STATUS_DLL_NOT_FOUND = 0xC0000135 if result & 0xffffffff == STATUS_DLL_NOT_FOUND: cad_library.exitwitherror( 'CADCreoParametricCreateAssembly.exe returned STATUS_DLL_NOT_FOUND. Be sure Udm (64 bit) and Visual C++ Redistributable for Visual Studio 2012 are installed.', result) return result
def createHeatGenerationConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply heat generation load in Abaqus model. """ logger = logging.getLogger() try: #MPdict = myAsm.getMassProperties(regions=(myAsm.instances[instName],),) #vol = MPdict['volume'] #if vol is None: # cad_library.exitwitherror('Error getting volume from part instance ' + instName, -1, 'AbaqusThermal.py') #else: #vol_heat_rate = float(entry['HeatGeneration']) / float(vol) logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Heat Generation. \n') region = (myAsm.instances[instName].cells, ) HeatGenName = regionName + '-HeatGen' myModel.BodyHeatFlux(name=HeatGenName, createStepName=myStep.name, region=region, magnitude=float(entry['HeatGeneration']), distributionType=UNIFORM, amplitude=amp) except: cad_library.exitwitherror('Error creating the Heat Generation constraint.', -1, 'AbaqusThermal.py')
def createINP(myAsm, key, myModel, parallelCores, ramAllocated): """ Create an INP file of the current part. """ eRange = len(myAsm.instances[key].elements) # Determine the number of mesh elements of the current part # Create a set form those elements and name it as wholeInstance myAsm.Set(elements=myAsm.instances[key].elements[0:eRange], name='wholeInstance') inpName = key + '_temp' # Determine the name of the INP file based on the name of the current part try: myJob = mdb.Job(name=inpName, model=myModel.name, description='Static FEA job', multiprocessingMode=DEFAULT, numCpus=parallelCores, numDomains=1, memory=ramAllocated, parallelizationMethodExplicit=DOMAIN) # Create a job inside the Abaqus/CAE myJob.writeInput(consistencyChecking=ON) # Create an input file from that job except: cad_library.exitwitherror('Error during creating the INP file', -1, 'AbaqusCAE_ADAMS.py') return inpName
def SetupViewportPNG(myOdb, fileName, reqMetricSet, maxStressStep=None): try: myViewport = session.Viewport(name='Contour Plot', origin=(0, 0), width=200, height=100) myViewport.setValues(displayedObject=myOdb) mySteps = myOdb.steps numSteps = len(mySteps) session.printOptions.setValues(rendition=COLOR, vpDecorations=OFF, vpBackground=OFF) text = {'S': 'MPa', 'U': 'm', 'TEMP': 'K'} for metric in reqMetricSet: t = myOdb.userData.Text( name='Text-1', text='Units: ' + text[metric], offset=(0, 0), font='-*-arial-medium-r-normal-*-*-120-*-*-p-*-*-*') myViewport.plotAnnotation(annotation=t) if metric == 'S' and maxStressStep in mySteps.keys(): stepKey = mySteps.keys()[maxStressStep] myViewport.odbDisplay.commonOptions.setValues( visibleEdges=EXTERIOR) step = mySteps[stepKey] CreateViewportPNG(myOdb, metric, fileName, myViewport, step) else: for i in range(numSteps): myViewport.odbDisplay.commonOptions.setValues( visibleEdges=EXTERIOR) stepKey = mySteps.keys()[i] step = mySteps[stepKey] CreateViewportPNG(myOdb, metric, fileName, myViewport, step) except KeyError: cad_library.exitwitherror( ('KeyError', -1, 'ABQ_CompletePostProcess.py [SetupViewportPNG()]')) except AbaqusException, value: cad_library.exitwitherror( 'AbaqusException: ' + str(value), -1, 'ABQ_CompletePostProcess.py [SetupViewportPNG]')
def createHeatFluxConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply surface heat flux load in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: regionMask = myMask(entry['FaceIDs'][0]) maskRegion = myAsm.instances[instName].faces.getSequenceFromMask(mask=(regionMask,),) else: regionMask = myAsm.instances[instName].faces maskRegion = regionMask.getSequenceFromMask(mask=('[#ff ]', ), ) # Apply to entire body logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Surface Heat Flux. \n') region = myAsm.Surface(side1Faces=maskRegion, name=regionName) surfFluxName = regionName + '-SurfHeatFlux' myModel.SurfaceHeatFlux(name=surfFluxName, createStepName=myStep.name, region=region, magnitude=entry['HeatFlux'], distributionType=UNIFORM, amplitude=amp) except: cad_library.exitwitherror('Error creating surface heat flux constraint.', -1, 'AbaqusThermal.py')
def createSpecifiedTemperatureConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply specified temperature boundary condition in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: tempFace = entry['FaceIDs'][0] instances = entry['Instance'] faces = myAsm.instances[instances].faces region = regionToolset.Region(faces=faces[tempFace:tempFace+1]) else: region = (myAsm.instances[instName].cells, ) # Apply BC to entire part logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Specified Temperature. \n') specTempName = regionName + '-SpecTemp' myModel.TemperatureBC(name=specTempName, createStepName=myStep.name, region=region, magnitude=entry['SpecifiedTemperature'], distributionType=UNIFORM, amplitude=amp) # create specified temperature BC except: cad_library.exitwitherror('Error creating specified temperature constraint.', -1, 'AbaqusThermal.py')
def call_subprocess(self, cmd, failonexit=True): global print_cmds if print_cmds is True: print cmd result = 0 try: result = subprocess.call(cmd) except Exception as e: cad_library.exitwitherror( 'Failed to execute: ' + cmd + ' Error is: ' + e.message, -1) if result != 0 and failonexit: cad_library.exitwitherror( 'The command {} exited with value: {}'.format(cmd, result), -1) return result
def checkOverlap(odb_inst, jobName): """ Check ODB file for overlapping nodes (components) and exit if any exist. """ logger = logging.getLogger() overlapCheck = False try: overlapCheck = odb_inst.rootAssembly.elementSets['ErrElemVolSmallNegZero'] except: pass if overlapCheck: logger.info("There are elements in the model with zero or negative volume" + '\n') logger.info("Possibly parts are overlapping each other excessively" + '\n') logger.info("Unable to run the analyis, please fix your CAD model" + '\n') logger.info("Terminating" + '\n') CreateOverlapPNG(jobName, overlapCheck, os.getcwd()) logger.info("Check \"results/abcdef/Analysis/Abaqus/Contour_and_BC_plots/Overlapping_Elements_#.png\" " "files to determine problematic parts/elements" + '\n') cad_library.exitwitherror('Overlapping parts in thed design. Please see log file.', -1, 'AbaqusDataCheck.py')
def parseStep(cadAssemblyXMLTree, stepDir): """ Parse STEP file. """ logger = logging.getLogger() logger.info("Defining the path for the STEP file" + '\n') try: testBenchName = cadAssemblyXMLTree.get("Name") stepName = testBenchName + '_asm.stp' stepPath = os.path.join(stepDir, stepName) step = mdb.openStep(fileName=stepPath) except TypeError: cad_library.exitwitherror('Error finding top level assembly STEP file.', -1, 'AbaqusParse.py') except Texterror: cad_library.exitwitherror('Error opening the step file.', -1, 'AbaqusParse.py') logger.info("Opening the STEP file " + str(stepName) + ' and converting it into raw data' + '\n') logger.info("**********************************************************************************" + '\n') return stepPath, testBenchName, step
def read_msg_file(job_name, maxNumberIter=None): """ read Abaqus MSG file to determine job ending condition. """ logger = logging.getLogger() logger.info( "**********************************************************************************" + '\n') logger.info("Parsing Abaqus MSG file for job ending condition... \n") fname = str(job_name) + '.msg' try: msg = open(fname, 'rb') except IOError: found = False if maxNumberIter is not None: # Adaptive run that finished before maxNumberIterations while int(maxNumberIter) > 0: maxNumberIter -= 1 try: fname = job_name[:-1] + str(maxNumberIter) + '.msg' logger.info(fname) msg = open(fname, 'rb') # Try opening different iter found = True break except IOError: continue if not found: cad_library.exitwitherror( 'Adaptive iteration message file could not be found!', -1, 'AbaqusRun.py') finally: m = msg.read() # Check for divergence message along with ending error statement # (avoids case of initial divergence but convergence before job completion) if (m.find( " ***NOTE: THE SOLUTION APPEARS TO BE DIVERGING. CONVERGENCE IS JUDGED UNLIKELY." ) != -1 and m.find(" ***ERROR: TOO MANY ATTEMPTS MADE FOR THIS INCREMENT") != -1): err = "ENDING CONDITION: 'ERROR - Too many attempts made for this increment. \n" \ "The solution appears to be diverging. Convergence is judged unlikely.'\n\nFAILED" cad_library.exitwitherror(err, -1, 'AbaqusRun.py') elif m.find("THE ANALYSIS HAS BEEN COMPLETED") != -1: logger.info( "ENDING CONDITION: 'SUCCESS - 'The analysis has been completed.'\n" ) else: cad_library.exitwitherror( "UNKNOWN ENDING CONDITION: Please look at abaqus msg file.\n\n" "FAILED", -1, 'AbaqusRun.py') try: msg.close() except UnboundLocalError: # msg file was not found, but exception wasn't raised. While this isn't expected, it has been thrown # in the past. Since the simulation has ended with a failed condition, try throwing a generic exception. cad_library.exitwitherror( 'Issue with Abaqus-issued *.msg file. Analysis has most likely failed.', -1)
def createConvectionConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName): """ Apply convection interaction in Abaqus model. """ logger = logging.getLogger() try: if not entry['Component']: regionMask = myMask(entry['FaceIDs'][0]) maskRegion = myAsm.instances[instName].faces.getSequenceFromMask(mask=(regionMask,),) else: regionMask = myAsm.instances[instName].faces maskRegion = regionMask.getSequenceFromMask(mask=('[#ff ]', ), ) # Apply to entire body logger.info('Creating load/BC on entirety of ' + instName + ' with treatment Convection. \n') region = myAsm.Surface(side1Faces=maskRegion, name=regionName) convecName = regionName + '-ConvecHeat' myModel.FilmCondition(name=convecName, createStepName=myStep.name, surface=region, definition=EMBEDDED_COEFF, filmCoeff=entry['Convection'], filmCoeffAmplitude=amp, sinkTemperature=entry['AmbientTemperature'], sinkAmplitude=amp) except: cad_library.exitwitherror('Error creating convection heat constraint.', -1, 'AbaqusThermal.py')
def check_for_conflicting_loads(loadBCLib, thermal): """ This function compares the current thermal element to loads previously added to to the load library and throws an error if a conflict arises. EG, a surface heat flux is applied to a face of a plate, and then another, different surface heat flux is applied for the entire plate. With no way of determining precedence, an error is thrown. """ loadType = thermal.get('LoadType') for entry in loadBCLib: if 'Treatment' in entry: if entry['Treatment'] == loadType: try: cId = thermal.find('Component').get('ComponentID') # applied to component except AttributeError: # applied to geometry continue #cId = thermal.find('Geometry/Features/Feature').get('ComponentID') if entry['ComponentID'] == cId and float(entry[loadType]) != float(thermal.get('Value')): cad_library.exitwitherror('Multiple constraints of treatment ' + loadType + ' are associated with ComponentID ' + str(cId) + '.' ' No way of determining precendence - analysis is' + ' aborting. Please correct your test bench.', -1, 'AbaqusCAE.py')
def createThermalConstraint(myModel, myAsm, entry, myStep, amp, instName, regionName=None): """ Dispatch function to create thermal boundary condition/load. """ if regionName is None: try: regionName = 'BodyThermConst_' + str(randint(1, 1000)) except AbaqusError: # try again in case generated int already was created regionName = 'BodyThermConst_' + str(randint(1, 1000)) if entry['Treatment'] == 'InitialTemperature': createInitialTemperatureConstraint(myModel, myAsm, entry) try: globals()[str('create' + entry['Treatment'] + 'Constraint')](myModel, myAsm, entry, myStep, amp, instName, regionName) except KeyError: if entry['Treatment'] == 'AmbientTemperature': pass else: cad_library.exitwitherror('Specified thermal treatment ' + entry['Treatment'] + ' is not yet supported.', -1, 'AbaqusThermal.py')
def generateConvectionDict(thermal, loadBCLib, thermalSetXML): """ Generate convection entry in load dictionary. """ logger = logging.getLogger() logger.info("Defining heat convection BC" + '\n') loadBCLib[-1].update([['Treatment', 'Convection']]) # No conversion needed for convection: [J/(s.(m^2 K))] ==[W/(m^2K)] tMag = float(thermal.get('Value')) # magnitude of temperature loadBCLib[-1].update([['Convection', tMag]]) # store temperature value # Look for ambient temperature load - REQUIRED for convection ambient = False for therm in thermalSetXML: if therm.get('LoadType') == 'AmbientTemperature': ambient = True sink = tempConv(float(therm.get('Value')), therm.get('Unit')) loadBCLib[-1].update([['AmbientTemperature', sink]]) if not ambient: cad_library.exitwitherror('No ambient temperature found! Needed for convection load!', -1, 'AbaqusThermal.py') logger.info("Convection coefficient = " + str(tMag) + '\n') logger.info("Ambient Temperature = " + str(sink) + '\n')
def runAbaqusModal(myModel, args): """ Submit modal analysis job and check for convergence. """ logger = logging.getLogger() jobName = 'modalAnalysis' logger.info("**********************************************************************************" + '\n') logger.info("Creating the modal analysis job and submitting it" + '\n') try: myJob = mdb.Job(name=jobName, model=myModel.name, description='Modal Analysis job', multiprocessingMode=DEFAULT, numCpus=args.parallelCores, numDomains=args.parallelCores, memory=args.ramAllocated, memoryUnits=PERCENTAGE, parallelizationMethodExplicit=DOMAIN) except: cad_library.exitwitherror('Error during creating and submitting the modal ' + 'analysis process', -1, 'AbaqusRun.py') try: myJob.submit() myJob.waitForCompletion() except: read_msg_file(jobName) return jobName
def setInitialTemperature(thermal, myAsm, instName): """ Create and set initial temperature. Only applied to component level, not geometry. """ logger = logging.getLogger() try: logger.info("Defining initial temperature for " + str(thermal.find('Component').get('ComponentID')) + '\n') except AttributeError: cad_library.exitwitherror('Initial temperature specified for geometric subset of component. ' + 'Initial temperature can only be applied to component/assembly.', -1) tUnits = thermal.get('Unit') tMagUnconv = float(thermal.get('Value')) # magnitude of temperature tMag = tempConv(tMagUnconv, tUnits) logger.info("Initial Temperature Magnitude = " + str(tMag) + '\n') try: region = (myAsm.instances[instName].cells, ) initTempName = instName + '-InitTemp' mdb.models['Model-1'].Temperature(name=initTempName, createStepName='Initial', region=region, distributionType=UNIFORM, crossSectionDistribution=CONSTANT_THROUGH_THICKNESS, magnitudes=(tMag,)) except: cad_library.exitwitherror('Error setting initial temperature.', -1, 'AbaqusThermal.py')
def run_nastran(self): cwd = os.path.abspath(os.getcwd()) nastran_dir = os.path.join(cwd, 'Analysis', 'Nastran') os.chdir(nastran_dir) nastran_py_cmd = ' \"' + cad_library.META_PATH + 'bin\\CAD\Nastran.py\" ..\\Nastran_mod.nas' self.call_subprocess(sys.executable + nastran_py_cmd) # Post-Processing call if not self.run_pp: return 0 else: pp_result = self.run_patran_post_processing() if pp_result != 0: msg = "Patran Post Processing failed." cad_library.exitwitherror(msg, -1)
def runCalculix(): isisext = os.environ['PROE_ISIS_EXTENSIONS'] os.chdir(os.getcwd() + "\\Analysis\\Calculix") if isisext is None: cad_library.exitwitherror( 'PROE_ISIS_EXTENSIONS env. variable is not set. Do you have the META toolchain installed properly?', -1) deckconvexe = os.path.join(isisext, 'bin', 'DeckConverter.exe') callsubprocess(deckconvexe + ' -i ..\\Nastran_mod.nas') with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r'Software\CMS\CalculiX', 0, _winreg.KEY_READ | _winreg.KEY_WOW64_32KEY) as key: bconvergedpath = _winreg.QueryValueEx(key, 'InstallLocation')[0] callsubprocess(bconvergedpath + '\\CalculiX\\bin\\ccx.bat -i ..\\Nastran_mod') metapython = os.path.join(cad_library.META_PATH, 'bin', 'Python27', 'Scripts', 'python.exe') calculix_pp = os.path.join(cad_library.META_PATH, 'bin', 'CAD', 'ProcessCalculix.py') callsubprocess( metapython + " " + calculix_pp + " -o ..\\Nastran_mod.frd -p ..\\AnalysisMetaData.xml -m ..\\..\\RequestedMetrics.xml -j ..\\..\\testbench_manifest.json -e PSolid_Element_Map.csv" )
def run_nastran_post_process(self, in_BDF_FileName): # nastran_py_cmd = ' \"' + cad_library.META_PATH + 'bin\\CAD\Nastran.py\" ..\\Nastran_mod.nas' nastran_py_cmd = ' \"' + cad_library.META_PATH + 'bin\\CAD\Nastran.py\" ' + in_BDF_FileName self.call_subprocess(sys.executable + nastran_py_cmd) # Post-Processing call if not self.run_pp: return 0 else: pp_result = self.run_patran_post_processing() if not os.path.exists("_SUCCEEDED_PatranPostProcessing.TXT"): cad_library.exitwitherror( "vPatranPostProcess.pcl failed. See .\log\PatranPostProcessing_Session.log " + "and .\log\PatranPostProcessing_Application.log", -1) if pp_result != 0: msg = "Patran Post Processing failed." cad_library.exitwitherror(msg, -1)
def generateConvectionDict(thermal, loadBCLib, thermalSetXML): """ Generate convection entry in load dictionary. """ logger = logging.getLogger() logger.info("Defining heat convection BC" + '\n') loadBCLib[-1].update([['Treatment', 'Convection']]) # No conversion needed for convection: [J/(s.(m^2 K))] ==[W/(m^2K)] tMag = float(thermal.get('Value')) # magnitude of temperature loadBCLib[-1].update([['Convection', tMag]]) # store temperature value # Look for ambient temperature load - REQUIRED for convection ambient = False for therm in thermalSetXML: if therm.get('LoadType') == 'AmbientTemperature': ambient = True sink = tempConv(float(therm.get('Value')), therm.get('Unit')) loadBCLib[-1].update([['AmbientTemperature', sink]]) if not ambient: cad_library.exitwitherror( 'No ambient temperature found! Needed for convection load!', -1, 'AbaqusThermal.py') logger.info("Convection coefficient = " + str(tMag) + '\n') logger.info("Ambient Temperature = " + str(sink) + '\n')