Download pdf - Blender With Open Foam

Transcript
  • CombinedUseofBlenderwithOpenFOAMG.DouglasBaldwin

    AbstractBlenderfromblender.orgcontainsapowerful,widelyaccepted,opensource,surfacemeshgenerationtoolthatwasdevelopedforthedigitalartscommunity.Furthermore,BlenderincludesarobustandwelldocumentedPythonapplicationprogramminginterface(API)whichfacilitatesthedevelopmentofusertoolsformeshmanipulation,layeredmanifolds,andimport/export.

    TheauthordevelopedaPythonscriptandtechniqueformanipulatingandexportingBlenderobjectsintoCalculiXforhexagonalgridgeneration,whicharethenexportedintoOpenFOAMformat.Thebenefitofthisapproachisthatmanifoldsallowabsolutecontrolofmaximumcellgrowthratesfromtheboundarylayerouttotheedgeofthecomputationaldomain,whilealsodirectingthepathofstackedhexagonalcellstoavoidskew.ThistechniquewasusedtostreamlineanaircraftfuselageusingapurehexagonalgridwithOpenFOAM,andthenimportthegridintoScientificSimulationsNSU3Dforauthoritativedraganalysis.

    Thetechniqueisripewithpossibilitiesfordevelopingmeshesformanyclassesofsimulations.Highlightsofthehexahedralgridsusedintheaircraftstreamliningeffortwillbeshownanddiscussedbelow,followedbyanillustrativegridthatcombineshexahedralcellsattheboundarylayerwithtetrahedralcellsinthebulkflow.ThispaperwillconcludewithacopyofthePythonscriptandadiscussionofhowitmaybefurtherdeveloped.Theauthorhasnointentionatthistimeofleadingfurtherdevelopmentofthisscriptduetootherdemandsonhistime.Itishopedthatotherstoowillfindvalueinthisapproachandperhapscarryitforward.

    FuselageStreamliningIngeneral,Blendermeshesarecomprisedofbothtrianglesandquadrilaterals.Forthefuselagestreamliningproject,itwasdecidedtouseexclusivelyquadrilateralsforthesurface.Illustrationsofthefinalsurfaceareprovidedbelow.Noticethepinkvertices.Theonlyverticiesdefinedbytheuserarethoseshowninpink.AlloftheotherverticiesareautomaticallygeneratedbyBlenderwhenthesubsurfmodifierisappliedtotheobject.Thestrengthofthelinesconnectinganytwopinkverticiesiscontrolledbythecreasefeature.ItisnotthepurposeofthispapertoprovideatutorialonBlender,subsurf,andcrease.ManyexcellentBlendertutorialsarereadilyavailableontheinternet.Noticehoweverthetechniqueofhavingevenlyspacepinkverticiestomaintainarelativelyconsistentgridsize.ThecloseupillustrationbelowrevealsbettertheindividualquadrilateralelementsautomaticallygeneratedbytheBlendersubsurfmodifier.AlsonotethetwodifferentcoloredBlendermaterialsusedontheobject.TheseBlendermaterialseventuallytranslatetoOpenFOAMpatches.Thedecisiontohavetwopatchesforthisfuselagemodelisunrelatedtothepresenttopicandwillnotbediscussedfurthertoavoidaconfusingdigression.

    Presentedatthe3rdOpenFOAMWorkshop,Milan,Italy,1011July2008.

  • ManifoldssurroundingthisfuselageobjectwerecreatedbyusingthePythonscriptthatwillbeprovidedtowardstheendofthispaper.Theprocedureforcreatingmanifoldsisthatacopyofthebaseobjectiscreatedbytheuser,andthenanautomaticalgorithmmoveseachpinkvertexalongitsnormalbyauserspecifiedamount,makingautomaticadjustmentsuntilallcomputergeneratedverticieshavealsomovedapproximatelyalongtheirnormalsbyapproximatelythesamedistance.Asabyproductofthisalgorithm,colorcodedrepresentationsofcellheight,aspectratio,andskewaregeneratedasavisualaidformanualtweakingofthemanifoldverticies.Thefirstmanifoldsurroundsthefuselage/baseobjectasshownintheillustrationbelow.

    Thefollowingillustrationsshowthecolorcodedrepresentationsofcellheight,aspectratio,andskew,inthatorder.Thecolorcodesfortheseillustrationshavethefollowingmeanings.Fortheheightandaspectratioillustrations,bluerepresentstheminimumwithintherangeofvaluesandredrepresentsthemaximumwithintherangeofvalues.Forskew,bluethroughredrepresenttherangeofzerotoninetydegreesin12.5degreeincrements.

  • Thedesigngoalforthisfuselagegridwastohaveacellheightatthefuselagewithy+intherangeof1to10,andacellgrowthfactorof1.15extendingtotheedgeofthecomputationaldomain,whichwasapproximately10timesthereferencelengthawayfromthefuselageinalldirections.Aseriesoffourmanifoldswereneededtoavoidhighskewangles.Ascanbeseeninthefollowingtwoillustrations,themanifoldsfurtherawayfromthefuselagebecomebecomemorespherelike.Thefirstthreemanifoldsareshowninthecutawayillustrationbelow,followedbyanillustrationofthefourthmanifoldenclosingthethirdmanifold.Noticethatthefourthandlargestmanifoldhastwomaterialsassigned,shownasblueandred,whichrepresenttheinletpatchandtheoutletpatch.

  • TheuserinterfaceforthePythonscriptisshownbelow.Sofar,wehaveonlydiscussedthemanifoldgenerationcapabilitiesofthisscriptwhicharecontrolledbytheDisplacementSliderandtheApplybutton.TheunitsoftheDisplacementSliderareequivalenttotheaverageedgelengthofthemanifoldquads.Theprocedureforcreatingamanifoldisasfollows:1)duplicatethetheBlenderObject;2)whileinEditModeselecttheverticesthatwillbedisplaced;and3)clickontheApplybutton.Onlytheselectedverticeswillbedisplaced.ThestandardBlenderUndocommandcanbeusedtomovetheverticesbacktotheiroriginalpositionifneeded.

    Thecolumnofbuttonsandslidersontheleftsideoftheuserinterfaceareusedtospecifythegridcharacteristics,andthentheExportbuttonispressedtoexporttheselectedmanifoldsasasolidgeometryinCalculiXformat.WhenthebuttonlabeledMeshtheboundarylayerhasbeendepressed,aboundarylayermanifoldwillbeautomaticallygeneratedfortheoriginal/baseobject,withadisplacementdistanceasspecifiedbytheDisplacementslider.ThisbuttonisusefulforrelativelysimplegeometrieswhenperformingmultipleiterationsofmeshgenerationandOpenFOAManalysis.Theverticesofthebaseobjectcanbetweaked,andthenanewboundarylayermanifoldisautomaticallyproducedeachtimetheExportbuttonisclicked.Formorecomplexgeometriessuchasthefuselageshownabove,theboundarylayermanifoldcanbemanuallygeneratedandthenmanuallytweakedeachtimethefuselageverticesaretweaked.

    Thenexttwoslidersspecifythecellheight.TheslidernamedTargetmaxaspectratioisusedtospecifythedesiredaspectratioofthefirstcell.OpenFOAMrejectsmesheshavinganycellaspectratiothatisgreaterthan1000.Thissliderisusefulforachievingasmally+whilestayingwithinanaspectratioof1000.Duetothenatureofthemeshingalgorithms,theactualaspectratioofthefirstcellmaybeslightlylargerorsmallerthanthespecifiedtarget.ThesliderCellGrowthFactorisusedtospecifythemaximumcellheightgrowthbetweenanytwostackedcells,andappliestotheentirecomputationaldomainfromthefirstcellatthebaseobjectouttothelastmanifold.

    ThenextthreebuttonsareusedtospecifyplanesofsymmetrynormaltotheX,Y,andZaxes,respectively.Undermostcircumstancestheseplanesofsymmetrywillneedtopassthroughtheorigin,butifnecessarytheycanbeoffsetbyusingtheaccompanyingsliders.TheunitsfortheseslidersareBlenderunits,whichforthepurposesofOpenFOAMwillusuallybemeters.Aswillbeseeninsubsequentillustrations,aplaneofsymmetrynormaltotheYaxiswasappliedwhenexportingthefuselagegrid.

  • WhentheExportbuttonisclicked,theuserisaskedtospecifythefolderandfilenamefortheCalculiX.fbdfile.Filegenerationusuallytakesonlyafewsecondsforlargemodels,andcertainlylessthanaminutefortheverylargestofmodels.IfBlenderisinitializedthroughacommandlineconsoleinterface,thensomeusefulstatisticsrelatedtotheresultingmeshareprintedinthisconsole.Also,theheight,aspectratio,andskewillustrationsasshownaboveareautomaticallygeneratedandplacedinBlenderslayers11,12,and13respectively.

    TheexportedfilecannowbeloadedintoCalculixbyusingthecommand:cgxbfilename.fbd.ForlargergridsthisloadprocesscantakeaverylongtimebecauseCalculiXautomaticallygeneratesageometricbodyforeachpairofquadsateachpairofmanifolds.Aftergeneratingthegeometry,CalculiXautomaticallygeneratesthemeshwhichalsotakessometime.ImmediatelyafterthefilecompletesloadingintoCalculiX,youhaveameshreadytoexportinOpenFOAMformat.First,typeinthesavecommand;thiswillsaveyouthetroubleofhavingCalculiXregeneratethegeometryifyoueverneedtoloadthisfileagain.AsimplecommandforexportingtoOpenFOAMatestmeshis:sendallfoampatchall.WhenyouaresatisfiedwithcheckMesh,youwillthenwanttospecifytheindividualpatchesinyoursendcommand.ThesepatchesweredefinedearlierbyusingBlendermaterials.AnexamplesendcommandwithpatchesissendallfoampatchinletpatchoutletwallyourObject.Also,ifplane(s)ofsymmetrywereusedinBlender,thenoneextrastepisneededinCalculiXbeforesendingthemeshwithindividualpatchestoOpenFOAM.UsethecommandsetrsymmetrysenotSymmetrytoremovethenonsymmetryfacesfromthesymmetryset,andthenincludethephrasesymmetryPlanesymmetryinyoursendcommand,e.g.sendallfoampatchinletpatchoutletwallyourObjectsymmetryPlanesymmetry.VerylittleproficiencywithCalculiXisnecessary,thoughitwouldnothurttolearnsomeoftheotherfeaturesofthistool.

    SampleparaFoamplotsofthefinalfuselagegridareshownbelow.

  • Theabovefourplotsshow:1)thesurfacequadsofthefuselage,2)thesymmetryplanecloseintothefuselage,revealingthefinestructureattheboundarylayer,3)thesymmetryplaneshowingthe1st,2nd,and3rdmanifolds,and4)thesymmetryplaneofthefullcomputationaldomain,outtothe4thmanifold.

    AfterseveraliterationsbetweenBlenderandOpenFOAM,afuselagegeometryhavingnoflowseparationwasachieved.TheOpenFOAMLift/Dragtoolwasusedtoestimatethedragcoefficients.ThegridwasthendeliveredtoScientificSimulationsLLC,whereanimporttoolwasdevelopedforconvertingtheOpenFOAMpurehexgridintoaNSU3DgridforfurtherCFDanalysis.UsingthesameoperatingconditionsandsameSpalartAllmaraswallmodel,thedifferenceinpredicteddragwassignificant.NSU3D,whichhasbeenpubliclyvalidatedforthesekindsofstreamlinedfuselagesattheAIAACFDDragWorkshop,predicted30%lessdragthanOpenFOAM.Furthermore,NSU3Dacceptscellaspectratiosofatleast10,000,whichallowedforafinerresolutionofthegridatthewallwithouttheneedtofurtherrefinethefuselagesurfacemesh.Together,BlenderandOpenFOAMwereapowerfulcombinationoffreetoolsfordevelopingthisstreamlined,lowdragfuselage.

    CombiningwithtetrahedralsCalculiXcanexporttoOpenFOAMonlypurehexahedralgrids,andassuchislimited.Somecasescannotbemodeledwithpurehex,stackedgrids.Forinstance,aneffortwasmadetousetheabovetechniquestodevelopasamplecoarsegridoftheAhmedwindtunnelexperiment.Unfortunately,thespacebetweenthebottomoftheautomobileandthetestsectionfloorbecamecrowedwithmanyhigh

  • aspectratiocells.Abetterapproachistohavequadrahedralsattheboundarylayercombinedwithtetrahedralsfillingtheremainderofthecomputationaldomain.Anattemptatcreatingsuchasamplegridwasundertaken,usingBlenderwithCalculiXfortheboundarylayerandNetgenforthebulkflowfield.Blenderimagesfromthisgridgenerationexperimentareshownbelow.ThefirstimageshowstheAhmedbodyandthefirstmanifold.ThesetwoobjectswereexportedtoCalculixusingthetechniquesdescribedabove.Thesecondimageshowsthetunnel,whichwascreatedbyextrudingacopyofthefirstmanifoldandadjustingitsverticies.

  • ThetunnelobjectwasexportedfromBlenderinstereolithography(STL)format,andthenreadintoNetgenfortetrahedralmeshgeneration.Sincethecavityofthetunnelobjectwasoriginallyacopyofthefirstmanifold,thisprovidesaperfectinterfaceforpotentiallyusingthestitchMeshtoolinOpenFOAM.BoththeCalculiXgeneratedboundarylayermeshandtheNetgenbulkflowmeshwerecombinedinOpenFOAMusingmergeMeshes.Animageofthecombinedmeshesisshownbelow,whichincludesthetunnelinletontheleft,thesymmetryplane,thesurfaceoftheAhmedbody,andthetunneloutletontheright.ThenextimageshowsthattheAhmedbodyhasaquadsurfacewithhexahedralcells.Followingthisisacloseupimageoftheinterfacebetweenthehexahedralcellsandthetetrahedralcells.Unfortunately,stitchMeshwasunabletoremovetheinterfacepatches.ItwouldappearthatstitchMeshisunderactivedevelopmentandshouldeventuallybecapableofremovingthisinterface.

  • FurtherusesandfurtherdevelopmentsBlenderhastheabilitytoimportSTLobjects,andthePythonscriptdescribedinthispapercanbeusedtocreateaboundarylayermeshontheseSTLobjects.OneapproachistoletCalculiXconverteachtrilateralintothreequadrilaterals,andthenusethetechniquesdescribedaboveforcreatingahexahedralmesh.AnotherapproachwouldbetomodifythePythonscripttohaveitoutputthehexahedralgriddirectlytoOpenFOAMformat,whichwoulddramaticallyspeedupthemeshgenerationprocess.DirectexportfromBlenderwouldallowgenerationofprismcells,whichcouldbestackeddirectlyontotheSTLtrilaterals.

    AkeyarchitecturalfeatureoftheBlenderdatamodelprovidesthefoundationformanifolddevelopment.Eachmeshobjectincludesalinkedlistofvertices.Whenameshobjectiscopied,thenewmeshobjectcontainsthesameverticiesinthesamelinkedlistorder.Thecoordinatesoftheseverticiesmaybechangewithoutchangingtheirorderwithinthelinkedlist.Bystrategicplacementoftheverticiesofthenewmeshrelativetotheoriginalmesh,acollectionofuniform,lowskewhexahedralsand/orprismscanbegenerated.ThisarchitecturalfeaturewasexploitedtogeneratetheCalculiXbodiesfromtheBlendermanifolds.ThissamearchitecturalfeaturecouldbeexploitedtodirectlygenerateanOpenFOAMmeshcomprisedofhexahedralsand/orprismswithauniformgrowthfactorextendingfromthebodywalluptothefirstmanifold,orfurthertoasecondmanifold,etc.TheoutertwomanifoldscanthenbeexportedasanSTLmeshfortetrahedralmeshgenerationinNetgen.Blenderhasaveryefficientmeshmanipulationkernel,andwhencombinedwithPythonscriptscanrapidlyexportlargeobjects.Thescriptprovidedbelowisbothusefulasis,andpotentiallyevenmorevaluablewithadirectexporttoOpenFOAMcapability.

    Alsoworthnoting,modificationstoCalculiXweredevelopedtoreducememoryallocationrequirementsandincreaseprecision.Amodificationwasneededwhengeneratingthefuselagegridinordertoavoidmallocerrorsona32bitmachine.ThemodifiedsourcefilenamedfoamFaces.cwaspostedtotheCalculiXsupportgroupsiteonYahoo.Also,CalculiXoutputsOpenFOAMgridcoordinatesinfloatformat,andtheformatstatementinthefilewrite2foam.ccaneasilybechangedtoexponentialformatforimprovedprecision.

    ConclusionsAcombinationofBlenderandCalculixwasusedtogeneratepurehexahedralgridsforthepurposeofstreamlininganaircraftfuselage.Thistechniquecanpotentiallybeextendedtomixedhexahedral/tetrahedralgridsbyemployingNetgen.Furthermore,thePythonscriptforexportingBlendergeometryinCalculiXformatcouldthroughmodificationdirectlyexporttoOpenFOAMformat,whichwouldallowgenerationofastackedprismboundarylayergridontopofanSTLobject.ThisPythonscriptisveryusefulasis,anditsvaluetotheOpenFOAMcommunitycouldbesignificantlyenhancedbyaddingtheserelativelyminormodifications.

  • Pythonscript

    #!BPY

    #######################################################################Export_fbdv0.2forBlender

    #ThisscriptletsyouexportmanifoldstoCalculixformat(.fbd)

    #(c)2007G.DouglasBaldwin(dougATbaldwintechnologyDOTcom)#releasedunderBlenderArtisticLicense

    ######################################################################

    """Name:'CalculixExport(.fbd)...'Blender:Group:'Export'Tooltip:'ExportselectedobjectstoCalculixFormat(.fbd)'"""

    __author__="DougBaldwin"__version__="0.2"

    __bpydoc__="""\ThisscriptexportsmanifoldstoCalculixFormat(.fbd).

    Usage:

    Createabasemeshobject,thenmakeafirstcopyofthisobject.Afteracopyismadeverticesofanyobjectmayberepositioned,butvertices,lines,andfacesmayneitherbeaddednordeleted.Successivecopiesshouldbestretchedintoeverlargermanifolds.Thisscriptwillcreatea3DCalculixmeshsuccessivelyfromthebasemeshtothefirstcopy,thenfromthefirstcopytothesecondcopy,etc.

    TheDisplacementbuttonisusefulforstretchingthemanifolds.Thisfunctiondisplacestheselectedverticesoftheselectedobjectinthedirectionnormaltothelocalsurface.

    Thegoalistodisplacetheverticesofeachmanifoldgenerallynormaltoitsprecedingmesh,whilealsoreshapingasneeded.Graphicplotsoffirstcellheight,aspectratio,andskewareoutputtolayers11,12,and13.

  • BlenderMaterialnamesofthefirstandlastobjectwillbeexportedasCalculixsetsforgeneratingpatches.

    TheGUIparametersTargetAspectRatioandGrowthFactorareusedforcalculatingthehexcellheightatthebasemeshobject,andtheratioofsuccessivecellheightsextendingtotheoutermostmanifold.ThevaluesTargetAspectRatioandGrowthFactorarethemaximumvaluesfortheentirehexmesh,regardlessofanyundulationsinthemanifolds.AspectRatioiscalculatedtobethesquarerootofthequadsurfacedividedbythefirstcellheightnormaltothequadsurface.

    Symmetryplanesmaybetoggledon/offandpositionedalongtheX,Y,andZaxes.Ifoneormoresymmetryplanesaretoggledon,theexportedfilewillincludeasetofexternalsurfacescalled"symmetry".Symmetryplanesaregenerallyusefulonlywhenverticesofthebaseobjectandmanifoldslieonthesymmetryplane.

    Selectallobjectstobeexported,withtheoutermostobjectactive.PresstheExportbuttontoexport,thenselectthefilelocationandfilename.PresstheExitbuttontoexitthescript.

    """

    importBlenderfromBlenderimportScene,Window,Materialfrommathimportceil,log,sqrt,floor,acos,pi

    #=================================#===WriteFBDCalculixFormat===#=================================fromBlender.BGLimport*fromBlender.Drawimport*importBPyMessagesimportbpy

    #ParametersX_Plane=Create(0)Y_Plane=Create(1)Z_Plane=Create(0)X_Location=Create(0.0)Y_Location=Create(0.0)Z_Location=Create(0.0)growth=Create(1.15)aspect=Create(1000)mesh_BL=Create(0)

  • factor=Create(1.0)

    #EventsEVENT_NOEVENT=1EVENT_EXPORT=2EVENT_EXIT=3EVENT_APPLY=4

    #######################################################GUIdrawing######################################################defdraw():globalX_Plane,Y_Plane,Z_Plane,X_Location,Y_Location,Z_Locationglobalgrowth,aspect,mesh_BL,factorglobalEVENT_NOEVENT,EVENT_EXPORT,EVENT_EXIT

    ##########TitlesglClear(GL_COLOR_BUFFER_BIT)glRasterPos2d(8,183)Text("Exportwithoptionalsymmetryplane(s)")

    glRasterPos2d(250,85)Text("Displaceselectedverticesnormaltothesubsurf")

    #########ParametersGUIButtons

    X_Plane=Toggle("X:",EVENT_NOEVENT,10,55,18,18,X_Plane.val,"ToggleXsymmetryplane");

    X_Location=Slider("Location:",EVENT_NOEVENT,30,55,200,18,X_Location.val,20.000,20.0000,1,"Xplanelocation");

    Y_Plane=Toggle("Y:",EVENT_NOEVENT,10,75,18,18,Y_Plane.val,"ToggleYsymmetryplane");

    Y_Location=Slider("Location:",EVENT_NOEVENT,30,75,200,18,Y_Location.val,20.000,20.0000,1,"Yplanelocation");

    Z_Plane=Toggle("Z:",EVENT_NOEVENT,10,95,18,18,Z_Plane.val,"ToggleZsymmetryplane");

    Z_Location=Slider("Location:",EVENT_NOEVENT,30,95,200,18,Z_Location.val,20.000,20.0000,1,"Zplanelocation");

    growth=Number("CellGrowthFactor:",EVENT_NOEVENT,10,115,220,18,growth.val,1.00,2.00,"Ratioofcellheightsindirectionnormaltothebaseobject")

    aspect=Number("Targetmaxaspectratio:",EVENT_NOEVENT,10,135,220,18,aspect.val,100.0,2000.0,"Targetaspectratiooffirstcelllayer")

    mesh_BL=Toggle("Meshtheboundarylayer",EVENT_NOEVENT,10,155,220,18,mesh_BL.val,"Generateameshextrudednormaltothebaseobject");

    factor=Slider("Displacement:",EVENT_NOEVENT,250,55,260,18,factor.val,1.000,10.000,1,

  • "Magnituderelativetoaveragesubsurfedgelength");

    #########ExportandExitButtonsglRasterPos2d(8,36)Text("Note:Selectallmanifolds")Button("Export",EVENT_EXPORT,10,10,80,18,"ExporttoCalculixfile")

    Button("Apply",EVENT_APPLY,250,10,80,18,"Applydisplacementtotheactiveobject")

    Button("Exit",EVENT_EXIT,430,10,80,18,"Exitscript")

    defevent(evt,val):if(evt==QKEYandnotval):

    Exit()

    defbevent(evt):# globalEVENT_NOEVENT,EVENT_EXPORT,EVENT_EXIT

    #########ManagesGUIeventsif(evt==EVENT_EXIT):

    Exit()elif(evt==EVENT_EXPORT):

    ifnotBlender.Object.GetSelected():BPyMessages.Error_NoActive()return

    Blender.Window.FileSelector(write_ui,'FBDExport',Blender.sys.makename(ext='.fbd'))

    Blender.Redraw()elif(evt==EVENT_APPLY):manDisplace(factor.val)

    Register(draw,event,bevent)

    defmanDisplace(factor):sce=bpy.data.scenes.activeob_act=sce.objects.activeifnotob_actorob_act.type!='Mesh':

    BPyMessages.Error_NoMeshActive()return

    is_editmode=Window.EditMode()Window.EditMode(0)Window.WaitCursor(1)

    displace(ob_act,factor)

  • #Restoreeditmodeifitwasenabledifis_editmode:Window.EditMode(1)

    Window.WaitCursor(0)

    defwrite_ui(filename):globalgrowth,aspect,mesh_BL,factor

    #openfileifnotfilename.lower().endswith('.fbd'):

    filename+='.fbd'file=open(filename,'wb')file.write('asgnsC\n')#Calculixautogeneratedsurfacestobeginwith"C"

    #initializevaluest=Blender.sys.time()me=[]ratio=[]bl=Nonescn=Scene.GetCurrent()obs=[obforobinscn.objects.context]obList=obs

    ifmesh_BL.val==1:#createboundarylayerobjectscn.objects.selected=[obs[len(obs)1]]Blender.Object.Duplicate(mesh=1)bl=scn.objects.selected[0]#Selectverticesinbasemeshmesh=bl.getData(mesh=1)forvinmesh.verts:

    v.sel=1displace(bl,factor.val)obList.insert(len(obList)1,bl)

    n=len(obList)foriinrange(n):

    me.append(Blender.Mesh.New())#createanewmeshme[i].getFromObject(obList[i],0,0)#getsubsurfmeshme[i].transform(obList[i].matrix)#scaleandrotateasneededwritePoints(file,me[i],i)#writemeshpointswriteLines(file,me[i],i)#writemeshlineswriteSurfaces(file,me[i],i)#writemeshsurfacesandpatchnamesifi!=0:

    writeThickness(file,me[i],me[i1],i)writeBodies(file,me[i],me[i1],i)

  • #calculateandgeneratedivandbiaminH,maxH,ratio=heightAnalysis(me)dH=1.0/aspect.valforiinreversed(range(0,n1)):

    dH=dH/ratio[i]height=0.0div=0whileheight=2:surfacePlots(obList,firstDiv,growth.val)

    #generatesymmetrysetwhilealsogenerating3Dmeshmats=Blender.Material.get()formatinmats:

    file.write('comp%sd\n'%mat.name)file.write('SETAnotSymmetryse%s\n'%mat.name)file.write('compnotSymmetryd\n')

    file.write('eltyallhe8\n')file.write('meshall\n')file.write('setasymmetryseall\n')file.write('setrsymmetrysenotSymmetry\n')file.write('plotmeall\n')file.write('plussall\n')file.close()ifmesh_BL==1andn==2:

    PupMenu('Returningboundarylayerobjectwithbaseobject')else:

    ifbl!=None:scn.objects.unlink(bl)scn.objects.selected=obs#Timingthescriptisagoodwaytobeawareonanyspeedhitswhenscriptingprint'Scriptfinishedin%.2fseconds'%(Blender.sys.time()t)

    defwritePoints(file,mi,i):#writeoutallpointsinthismesh

  • forvinmi.verts:file.write('PNTP%x%x'%(i,v.index))file.write('%.6f%.6f%.6f\n'%tuple(v.co))

    defwriteLines(file,mi,i):#writeoutalllinesinthismeshforeinmi.edges:

    file.write('LINEL%x%xP%x%xP%x%x1\n'%\(i,e.index,i,e.v1.index,i,e.v2.index))

    defwriteThickness(file,m1,m0,i):forjinrange(len(m1.verts)):

    m1vji=m1.verts[j].indexfile.write('LINEM%x%xP%x%xP%x%x2\n'%\(i,m1vji,i,m1vji,i1,m0.verts[j].index))file.write('SETA%s%slM%x%x\n'%\("thickness",i1,i,m1vji))

    defheightAnalysis(me):ratio=[]foriinrange(len(me)2):

    ratio.append(0.0)forf0,f1,f2inzip(me[i].faces,me[i+1].faces,me[i+2].faces):

    upperH=abs((f0.centf1.cent)*(f0.no+f1.no)/2)lowerH=abs((f1.centf2.cent)*(f1.no+f2.no)/2)ratio[i]=max(ratio[i],upperH/lowerH)

    n=len(me)2f0=me[n].faces[0]f1=me[n+1].faces[0]h=abs((f0.centf1.cent)*(f0.no+f1.no)/2)minH=hmaxH=hratio.append(h/sqrt(f1.area))forf0,f1inzip(me[n].faces,me[n+1].faces):

    h=abs((f0.centf1.cent)*(f0.no+f1.no)/2)minH=min(minH,h)maxH=max(maxH,h)ratio[n]=min(ratio[n],h/sqrt(f1.area))

    returnminH,maxH,ratio

    defsurfacePlots(obs,firstDiv,growth):heights=[]aspectRatios=[]skews=[]mat=[]

  • factor=0foriinrange(firstDiv):

    factor=factor+pow(growth,i)factor=1/factor

    scn=Scene.GetCurrent()

    meH=Blender.Mesh.New('height')#createanewmeshmeH.getFromObject(obs[len(obs)1],0,0)#getsubsurfmeshmeH.transform(obs[len(obs)1].matrix)#scaleandrotateasneededobH=scn.objects.new(meH)obH.layers=[11]

    meAR=Blender.Mesh.New('aspectRatio')#createanewmeshmeAR.getFromObject(obH,1,0)#copymeshobAR=scn.objects.new(meAR)obAR.layers=[12]

    meSkew=Blender.Mesh.New('skew')#createanewmeshmeSkew.getFromObject(obH,1,0)#copymeshobSkew=scn.objects.new(meSkew)obSkew.layers=[13]

    me1=Blender.Mesh.New()#createanewmeshme1.getFromObject(obs[len(obs)2],0,0)#getsubsurfmeshme1.transform(obs[len(obs)2].matrix)#scaleandrotateasneeded

    forf0,f1inzip(meH.faces,me1.faces):vC=f1.centf0.centheights.append(abs(vC*(f0.no+f1.no)/2)*factor)aspectRatios.append(sqrt(f0.area)/heights[len(heights)1])cosine=min(1,vC*f0.no/sqrt(vC*vC))skews.append(acos(cosine))

    minH=min(heights)maxH=max(heights)minAR=min(aspectRatios)maxAR=max(aspectRatios)print"min/maxfirstcellheight",minH,maxHprint"min/maxfirstcellAR",minAR,maxAR

    mat.append(Material.New())mat[0].rgbCol=[0.,0.,1.]mat.append(Material.New())mat[1].rgbCol=[0.,0.5,1.]mat.append(Material.New())mat[2].rgbCol=[0.,1.,1.]

  • mat.append(Material.New())mat[3].rgbCol=[0.,1.,5.]mat.append(Material.New())mat[4].rgbCol=[0.,1.,0.]mat.append(Material.New())mat[5].rgbCol=[1.,1.,0.]mat.append(Material.New())mat[6].rgbCol=[1.,0.5,0.]mat.append(Material.New())mat[7].rgbCol=[1.,0.,0.]

    meH.materials=matmeAR.materials=matmeSkew.materials=mat

    obH.setMaterials(mat)obAR.setMaterials(mat)obSkew.setMaterials(mat)

    hRange=maxHminHforf0,hinzip(meH.faces,heights):

    f0.mat=int(floor(7.999*(hminH)/hRange))ARRange=maxARminARforf0,ARinzip(meAR.faces,aspectRatios):

    f0.mat=int(floor(7.999*(ARminAR)/ARRange))forf0,sinzip(meSkew.faces,skews):

    ifs>pi/2.0:f0.mat=7else:f0.mat=int(floor(7.999*(2.0*s/pi)))

    Blender.Redraw()

    defwriteSurfaces(file,m,i):key_index={}foreinm.edges:

    key_index[e.key]=e.indexforjinrange(len(m.faces)):

    mfi=m.faces[j].indexfile.write('GSURA%x%x+BLEND'%(i,mfi))forkinm.faces[j].edge_keys:

    file.write('+L%x%x'%(i,key_index[k]))file.write('\n')ifm.materials!=[]:

    mat=m.materials[m.faces[j].mat]ifmat!=None:

    file.write('SETA%ssA%x%x\n'%(mat.name,i,mfi))

  • defwriteBodies(file,m1,m0,i):globalX_Plane,Y_Plane,Z_Plane,X_Location,Y_Location,Z_Location

    forjinrange(len(m1.faces)):m1fi=m1.faces[j].index#cutatsymmetryplanesasspecifiedbyGUIif((X_Plane.val==0orm1.faces[j].cent[0]>X_Location.val)and\(Y_Plane.val==0orm1.faces[j].cent[1]>Y_Location.val)and\(Z_Plane.val==0orm1.faces[j].cent[2]>Z_Location.val)):

    file.write('bodyB%x%xA%x%xA%x%x\n'%\(i,m1fi,i,m1fi,\i1,m0.faces[j].index))file.write('SETAbodsbB%x%x\n'%\(i,m1fi))

    defdisplace(ob,factor):

    # Getsubsurfmeshandcalculateitsnormalsme0=Blender.Mesh.New()me0.getFromObject(ob,0,0)me0.calcNormals()

    # Createdictionaryofsubsurfverticestofacesvert_faces=dict([(v.index,[])forvinme0.verts])forfinme0.faces:

    forvinf.verts:vert_faces[v.index].append(f.index)

    # Calculatetargetheightsofselectedsubsurfvertexnormalsheights=[]displacements=[]totalH=0nFaces=0forviinme0.verts.selected():

    forfiinvert_faces[vi]:totalH+=sqrt(me0.faces[fi].area)nFaces+=1

    hFace=totalH/nFacesforviinme0.verts.selected():

    hTotal=0nFaces=0 forfiinvert_faces[vi]:

    hTotal+=hFace/abs(me0.verts[vi].no*me0.faces[fi].no)nFaces+=1

    hNormal=hTotal/nFacesheights.append(abs(hNormal*factor))

  • displacements.append(hNormal*factor)

    loop=1count=0

    # Iteratebasemeshdisplacementsneededtoachievetargetheightswhileloop==1andcount1e8:loop=1count+=1scn.objects.unlink(obCopy)

    print"AverageErrorSquare=",sumErrorSquare/len(heights)print"Loopcount=",count

    # Applydisplacementstobasemeshme=ob.getData(mesh=1)forvi,dinzip(me.verts.selected(),displacements):

    me.verts[vi].co+=me.verts[vi].no*d

    scn.objects.active=ob

    Combined Use of Blender with OpenFOAMAbstractFuselage StreamliningCombining with tetrahedralsFurther uses and further developmentsConclusionsPython script

Recommended