def pyFoamDict(self, application="foamStar"): d = DictProxy() d["waveType"] = waveTypeDict[self.waveType][application] if self.waveType != "noWaves": d["height"] = self.height d["period"] = self.period d["depth"] = self.depth d["refTime"] = self.startTime d["startTime"] = self.startTime d["rampTime"] = self.rampTime if self.waveType == "streamFunction": d["order"] = 25 if application == "foamExtend" or application == "swenseFoam": d["wind"] = Vector(0., 0., 0.) d["currentType"] = "constantCurrent" d["U0"] = Vector(0, 0., 0.) d["setEulerianCurrent"] = True d["EulerianCurrent"] = self.U0 d["waveDirection"] = Vector(*self.refDirection) d["phi"] = 0. #In wave2foam, with "EulerianCurrent", input is encounter period # d["period"] = 2*pi / omega2omegae(2*pi / self.period , v = self.U0, beta = 180.) elif application == "foamStar": if self.waveType != "noWaves": d["refDirection"] = Vector(*self.refDirection) d["U0"] = Vector(self.U0, 0., 0.) d["EulerianCurrent"] = 0.0 else: raise (Exception("Application not known {}".format(application))) return d
def pyFoamDict(self, application="foamStar"): d = DictProxy() if application == "foamStar": # for key, val in self.waveCondition.pyFoamDict(application = application).items(): # d[key] = val d["${}Wave".format(self.name)] = "" else: d["waveTheoryName"] = waveTypeDict[ self.waveCondition.waveType][application] if self.relax: r = DictProxy() if self.patchNames is None: r["zoneName"] = self.name + "Zone" # r["relaxationScheme"] = "spatial" r["origin"] = Vector(*self.origin) r["orientation"] = Vector(*self.orientation) # r["relaxationShape"] = "rectangular" else: r["relaxationScheme"] = "farfield" r["zoneName"] = self.name + "Zone" r["farfieldDistance"] = self.length r["blendingDistance"] = self.length * 0.95 r["farfieldPatchNames"] = self.patchNames d["relaxationZone"] = r return d
def __init__(self, p): """ :param x: x coordinate :type x: float :param y: y coordinate :type y: float :param z: z coordinate :type z: float """ # Ensure floats for the coordinates x = float(p[0]) y = float(p[1]) z = float(p[2]) # Construct parent vector class Vector.__init__(self,x,y,z) # Register the coordinates self.x = x self.y = y self.z = z self.duplicate = False self.id = self.__class__.vertexCount + 1 self.__class__.vertexCount += 1
def setMechanics(self, mass, cog, inertia, hullPatch): self["multiBodyFvMeshCoeffs"]["ship"]["mass"] = mass self["multiBodyFvMeshCoeffs"]["ship"]["CoRInitial"] = Vector(*cog) self["multiBodyFvMeshCoeffs"]["ship"]["momentOfInertia"] = tuple( inertia).__str__().replace(",", " ") self["multiBodyFvMeshCoeffs"]["ship"]["motionPatches"] = hullPatch self["multiBodyFvMeshCoeffs"][ "motionPatches"] = hullPatch #Sopheak: "it's safer to put it at both locations!" self["multiBodyFvMeshCoeffs"]["ship"]["loads"]["fluid"][ "patches"] = hullPatch
def p_list(self, p): '''list : '(' itemlist ')' ''' p[0] = self.condenseAllPreFixLists(p[2]) if not self.noVectorOrTensor and (len(p[2]) == 3 or len(p[2]) == 9 or len(p[2]) == 6): isVector = True for i in p[2]: try: float(i) except: isVector = False if isVector: if len(p[2]) == 3: p[0] = Vector(*p[2]) elif len(p[2]) == 9: p[0] = Tensor(*p[2]) else: p[0] = SymmTensor(*p[2])
def p_vector(self, p): '''vector : '(' number number number ')' ''' if self.noVectorOrTensor: p[0] = p[2:5] else: p[0] = Vector(*p[2:5])
def reset(self): pid = self.worker_index #os.getpid() # logger_g.info(f'{pid}') self.casename = 'baseCase_' + str(pid) self.csvfile = 'progress_' + str(pid) + '.csv' orig = SolutionDirectory(origcase, archive=None, paraviewLink=False) case = orig.cloneCase(self.casename) if self.states_type == 1: write_interval = ParsedParameterFile( path.join(self.casename, "system", "controlDict")) write_interval["writeInterval"] = self.update_frequency write_interval.writeFile() elif self.states_type == 2: write_interval = ParsedParameterFile( path.join(self.casename, "system", "controlDict")) write_interval["writeInterval"] = self.update_frequency write_interval.writeFile() # remove old log files with open(f'{self.casename}/logr.remove', 'a') as fp: subprocess.run(f'rm {self.casename}/log.*', shell=True, stdout=fp, stderr=subprocess.STDOUT) # remove old solution directories with open(f'{self.casename}/logr.remove', 'a') as fp: subprocess.run(f'rm -r {self.casename}/0.* {self.casename}/[1-9]*', shell=True, stdout=fp, stderr=subprocess.STDOUT) # remove old solution directories with open(f'{self.casename}/logr.remove', 'a') as fp: subprocess.run(f'rm -r {self.casename}/VTK', shell=True, stdout=fp, stderr=subprocess.STDOUT) # remove old solution directories # subprocess.run( # f'rm -r postProcessing', # shell=True, # stderr=subprocess.STDOUT # ) # set number of steps to 0 and start dynamic update self.number_steps = 0 self.stateFolders = [(i + 1) * self.write_interval - 1 for i in range(self.stateFrequency)] self.vel_square = [] self.itercount_prev = 0 # set up the case with random velicity condition between u = 4 to 8 m/s if self.single_velocity: self.vx = np.array( [self.vx_all[0]] ) #self.np_random.uniform(low=self.vx_low, high=self.vx_high, size=(1,)) #self.vx_all[0] # additional velicities to be added else: self.vx = self.np_random.uniform( low=self.vx_low, high=self.vx_high, size=( 1, )) #self.vx_all[0] # additional velicities to be added velBC = ParsedParameterFile(path.join(self.casename, "0", "U")) velBC["boundaryField"]["inlet"]["value"].setUniform( Vector(self.vx, 0, 0)) velBC.writeFile() # turbulence inlet parameters from experimental study nu = 6.7e-7 intensity = 0.00061 eddy_visc = 0.009 kinetic_energy = ParsedParameterFile(path.join(self.casename, "0", "k")) k = 1.5 * (self.vx[0] * intensity)**2 kinetic_energy["internalField"] = f"uniform {k}" kinetic_energy.writeFile() dissipation = ParsedParameterFile( path.join(self.casename, "0", "omega")) diss = int(k / (nu * eddy_visc)) dissipation["internalField"] = f"uniform {diss}" dissipation.writeFile() # convert solution files to vtk format with open(f'{self.casename}/logr.vtkoutput', 'wb') as fp: subprocess.run( f'$FOAM_APPBIN/foamToVTK {solveroptions} {self.casename}', shell=True, stdout=fp, stderr=subprocess.STDOUT) inlet = vtki.PolyData(f'./{self.casename}/VTK/inlet/inlet_0.vtk') Ub = inlet.cell_arrays['U'] Ub = np.array(Ub) mesh = vtki.UnstructuredGrid( f'./{self.casename}/VTK/{self.casename}_0.vtk') Um = mesh.cell_arrays['U'] Um = np.array(Um) Um = (np.sum(np.square(Um), axis=1)) Ub = (np.sum(np.square(Ub), axis=1)) U2 = np.average(Ub) + np.average(Um) if self.states_type == 1: self.state = np.array([U2]) elif self.states_type == 2: self.state = np.array([U2 for i in range(5)]) logger_m = logging.getLogger(__name__) logging.basicConfig(filename=f'foamstatus_{pid}.log', format='%(asctime)s | %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) # logger_m.info(f'{self.worker_index}') logger_m.info(f'{self.vx[0]} velocity assigned for {pid}') return np.array(self.state)
fem["mdFile"] = '"../{}"; selected ( '.format( mdFile) + len(modes2use) * '{} '.format(*modes2use) + ')' fem["datFile"] = '"../{}"'.format(datFile) fem["dmigMfile"] = '"../{}"'.format(dmigFile) fem["dmigKfile"] = '"../{}"'.format(dmigFile) fem["pchCoordinate"] = SymmTensor(*[0, 0, -draft, 0, 0, 0]) fem["pchScaleMode"] = scale fem["pchLengthUnit"] = 1 fem["pchMassUnit"] = 1 if not vtkOut: fem["outputToVTK"] = "no" fem["patches"] = "({})".format(hullPatch) fem["ySym"] = "(true)" if localPts is not None: if len(localPts) > 0: fem["pointList"] = "(localMotion)" fem["localMotion"] = [Vector(*pt) for pt in localPts] res["FEM_STRUCTURALMESH_VTU"] = fem return res class FlexFile(ReadWriteFile): """*.flex file """ @classmethod def Build(cls, case, donName, freq={}, damping=[],
base_case = 'airFoil2D' for mach in machs: for angle in angles: #clone template #copies directories 0, constant, and system clone_name = "/%s/airfoil-u%.1f-a%0.1f" % (path.join( getcwd(), copy_dir), mach, angle) clone = dire.cloneCase(clone_name) Ux = mach * speedOfSound * cos(radians(angle)) Uy = mach * speedOfSound * sin(radians(angle)) #read correct parameter file and change parameter velBC = ParsedParameterFile(path.join(clone_name, "0", "U")) velBC["internalField"].setUniform(Vector(Ux, Uy, 0)) velBC.writeFile() #edit controlDict to account for change in U controlDict = ParsedParameterFile( path.join(clone_name, "system", "controlDict")) controlDict["functions"]["forcesCoeffs"]["liftDir"] = Vector( -sin(radians(angle)), cos(radians(angle)), 0) controlDict["functions"]["forcesCoeffs"]["dragDir"] = Vector( cos(radians(angle)), sin(radians(angle)), 0) controlDict["functions"]["forcesCoeffs"][ "magUInf"] = mach * speedOfSound controlDict.writeFile() #implement parallelization print('Decomposing...')
# To be run using "Tools -> Python Shell -> Run Script" inside of paraFoam # assumes that one OpenFOAM-case is opened from PyFoam.Paraview import readerObject from PyFoam.Paraview.SimpleSources import Point, Sphere, Cube, Text, Line, Plane, Arrow, Glyph from PyFoam.Paraview.SimpleFilters import Group from PyFoam.Basics.DataStructures import Vector ro = readerObject() bnds = ro.getBounds() pl = Plane("Plane", ro.getCenter(), ro.getMax(), ro.getCenter() + Vector(1, 1, 1) ^ ro.getExtent()) ln = Line("Line", ro.getMin(), ro.getMax()) pt1 = Point("Point1", ro.getMin()) pt2 = Point("Point2", ro.getMax()) grp = Group("thePoints") grp.add(pt1) grp.add(pt2) sp = Sphere("Sphere", ro.getCenter()) cp = Cube("Cube", ro.getMin() - 0.2 * ro.getExtent(), ro.getMax() + 0.2 * ro.getExtent())
class SixDofDomainBody(ReadWriteFile): """SixDofDomainBody dictionnary """ @classmethod def Build(cls , case, mass, inertia, COG, nModes=0, donName=None) : res = cls( name = join(case, getFilePath("sixDofDomainBody") ), read = False ) res.header["class"] = "dictionary" res.header["object"] = "singleBody" res["mass"] = mass res["momentOfInertia"] = SymmTensor( *inertia ) res["cogInitial"] = Vector( *COG ) res["Xrel"] = "(0 0 0)" res["dotXrel"] = "(0 0 0)" res["omega"] = "(0 0 0)" res["EulerZYX"] = { "rollPitchYaw" : "(0 0 0)" } if nModes>0: res["modalData"] = { "readFromFile" : "constant/{}.flex".format(donName) } return res if __name__ == "__main__" : print(SixDofDomainBody.Build("test", 1000., 2000., '1 2 3'))
def makeVector(self, orig): """Convert a list or a tuple of length 3 to a vector for easier calculations""" return Vector(orig[0], orig[1], orig[2])
def getMax(self): """Get the minimum-vector of the bounds""" bnd = self.getBounds() return Vector(bnd[0][1], bnd[1][1], bnd[2][1])
from PyFoam.RunDictionary.ParsedParameterFile import WriteParameterFile from PyFoam.Basics.DataStructures import Dimension, Vector from os.path import join """ Convenience class to simply write "g" """ class Gravity(WriteParameterFile) : """ Gravity dictionnary """ def __init__(self , case, g = 9.81, version = "foamStar") : WriteParameterFile.__init__(self, name = join(case, "constant" , "g" ) ) self.header["class"] = "uniformDimensionedVectorField" self["dimensions"] = Dimension(*[0,1,-2,0,0,0,0]) self["value"] = Vector(*[0,0,-g]) if __name__ == "__main__" : print(Gravity("test"))
def main(argv=None): """ """ parser = OptionParser(usage="usage: %prog [options]", version="%prog ", description=__doc__) parser.add_option("-m", action="store", dest="mesh", type="string", default="", help="Specifies the mesh to work on") parser.add_option("-t", action="store", dest="template", type="string", default="template", help="""Specifies the template case, that will be cloned. (Default = template)""") parser.add_option( "-s", "--subpath", action="store", dest="subpath", type="string", default="", help="""Optional subpath. This should be used to sort custom parameter variations into the existing file structure. %mesh/(%subpath, optional)/%beta/%v """) parser.add_option("-b", action="store", dest="beta", type="float", default=0.0, help="Drift angle beta (Default = 0.0)") parser.add_option("-n", action="store", dest="steps", type="int", default=10, help="""Number of velocities between 0 and vMax. v=0 m/s will be neglected. (Default = 10)""") parser.add_option("-u", action="store", dest="u", type="string", default="0.0", help="Service speed in m/s (Default = 0.0m/s)") parser.add_option("-r", action="store", dest="dh", type="float", default=100.0, help="""Characteristic length of the flow. For ships this should be the shiplength. (Default = 100.0m)""") group = OptionGroup(parser, "Flag Options") group.add_option("--without-turbulence", action="store_true", dest="withoutTurbulence", help="""Do not look for the turbulence model and set the particular values in the boundary conditions. The values are calculated based on the equations presented in the Fluent (R) handbook.""") parser.add_option_group(group) (options, args) = parser.parse_args() try: u = float(options.u) v = linspace(0, u, options.steps + 1)[1:] except ValueError: exec "v = array(%s)" % options.u # Assemble the current working directory workingDir = path.join(getcwd(), options.mesh) # Put together the name of the target angle folder driftAngleName = "beta%.2f" % options.beta # Assemble the absolute path of the angle folder if not options.subpath: driftAngleDirectory = path.join(workingDir, driftAngleName) else: driftAngleDirectory = path.join(workingDir, options.subpath, driftAngleName) # Check if the directory exists, that should store the cases for the current # drift angle. if not path.exists(driftAngleDirectory): makedirs(driftAngleDirectory) else: raise IOError("Directory %s does already exist" % driftAngleDirectory) template = Case.case(path.join(getcwd(), options.mesh, options.template), archive=None, paraviewLink=False) template.addToClone("runCluster") template.addToClone("customRegexp") print "\nDrift angle beta = %.2f\n" % options.beta i = 1 for vI in v: print "Cloning case for v = %.3f" % vI # Clone the template case and open velocity boundary condition case = template.cloneCase(path.join(driftAngleDirectory, "v%02d" % i)) uFile = ParsedParameterFile(path.join(case.name, "0", "U")) # Rotate the velocity vector around z axis, according to the specified # drift angle. U = Vector(vI * math.cos(math.radians(options.beta)), vI * math.sin(math.radians(options.beta)), 0) # Update the boundary condition(s) with the respective values, that have # been calculated previously. uFile["internalField"].setUniform(U) for b in ["XMIN", "XMAX", "YMIN", "YMAX", "ZMIN", "ZMAX"]: patchType = uFile["boundaryField"][b]['type'] setPatch = False for inlet in ['value', 'inletValue', 'tangentialVelocity']: try: uFile["boundaryField"][b][inlet].setUniform(U) setPatch = True except KeyError: pass if setPatch: print "\tSetting patch: %s type %s" % (b, patchType) # Write changes to the boundary conditions uFile.writeFile() if not options.withoutTurbulence: print "\tFixing turbulence Dh =", options.dh case.writeTurbulence(options.dh, Utilities.mag(U)) # Update counter i += 1 print "\nDone!"