def write_field(self, x_seq, y_seq, z_seq, vel=True, pot=True, perturbation=False): dim = [x_seq[-1], y_seq[-1], z_seq[-1]] x_grid = numpy.linspace(*x_seq) y_grid = numpy.linspace(*y_seq) z_grid = numpy.linspace(*z_seq) vertices = [ paraBEM.PanelVector3(x, y, z) for z in z_grid for y in y_grid for x in x_grid ] for vert in vertices: if pot: self.case.off_body_potential(vert) if vel or perturbation: self.case.off_body_velocity(vert) with open(self._dir + "/field.vtk", "w") as _file: writer = VtkWriter() writer.structed_grid(_file, "field_data", dim) writer.points(_file, vertices) if pot: _potential = [vert.potential for vert in vertices] writer.data(_file, _potential, "potential", data_type="POINT_DATA") if vel: _velocity = [vert.velocity for vert in vertices] writer.data(_file, _velocity, "velocity", _type="VECTORS", data_type="POINT_DATA") if perturbation: _velocity = [ vert.velocity.x - self.case.v_inf.x for vert in vertices ] writer.data(_file, _velocity, "velocity", data_type="POINT_DATA")
def from_OBJ(cls, path): def load_obj_file(path): trailing_edges = [] panels = [] vertices = [] with open(path, "r") as inp: text_list = inp.readlines() for line in text_list: chars = line.split() if chars[0] == "v": vertices.append([float(number) for number in chars[1:]]) elif chars[0] == "f": panels.append([int(number) - 1 for number in chars[1:]]) elif chars[0] == "l": trailing_edges.append( [int(number) - 1 for number in chars[1:]]) return vertices, panels, trailing_edges def sort_and_order(panels, vertices): # deleting all vertices not used by the mesh # overwrites the panels and return the new vertices list orderd_vert_nr = list(set([vert for pol in panels for vert in pol])) vertices_set = [vertices[i] for i in orderd_vert_nr] mesh_dict = dict(zip(orderd_vert_nr, range(len(orderd_vert_nr)))) panels = [[mesh_dict[vert] for vert in pol] for pol in panels] return panels, vertices_set def sort_wake(trailing_edges): # makes a orderd list of the trailing_edge w_temp = trailing_edges[0] trailing_edges.pop(0) i = 0 j = 0 # stop if there is an error in the data while len(trailing_edges) and j < 10000: if trailing_edges[i][0] == w_temp[0]: w_temp = [trailing_edges[i][1]] + w_temp trailing_edges.pop(i) elif trailing_edges[i][1] == w_temp[0]: w_temp = [trailing_edges[i][0]] + w_temp trailing_edges.pop(i) elif trailing_edges[i][0] == w_temp[-1]: w_temp = w_temp + [trailing_edges[i][1]] trailing_edges.pop(i) elif trailing_edges[i][1] == w_temp[-1]: w_temp = w_temp + [trailing_edges[i][0]] trailing_edges.pop(i) i = int((i + 1) * (i < (len(trailing_edges) - 1))) j += 1 # abbort if j == 10000: this means that the trailing_edge is not a single line # this has to be exdented to wakes consisting of more than one wake edge !!! return w_temp def wake_from_mesh(trailing_edges, vertices, vertices_set): # replacing vertices with mesh vertices norm = lambda x, y: ((x[0] - y[0])**2 + (x[1] - y[1])**2 + (x[2] - y[2])**2)**(0.5) vert_dict = dict(zip(range(len(vertices)), vertices)) max_size = 0.0001 wake_dict = {} for i in trailing_edges: v1 = vert_dict[i] for j, v2 in enumerate(vertices_set): if norm(v1, v2) < max_size: wake_dict[i] = j return wake_dict mesh = cls() vertices, panels, trailing_edges = load_obj_file(path) panels, vertices_set = sort_and_order(panels, vertices) mesh.vertices = [ paraBEM.PanelVector3(*vertex) for vertex in vertices_set ] mesh.panels = [ paraBEM.Panel3([mesh.vertices[nr] for nr in pol]) for pol in panels ] if len(trailing_edges) > 0: trailing_edges = sort_wake(trailing_edges) wake_dict = wake_from_mesh(trailing_edges, vertices, vertices_set) mesh.trailing_edges = [ mesh.vertices[wake_dict[i]] for i in trailing_edges ] return mesh
# -*- coding: utf-8 -*- from __future__ import division import os import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import paraBEM from paraBEM.pan3d import doublet_3_0_n0, doublet_3_0_sphere, doublet_3_0_vsaero from paraBEM.utils import check_path pnt1 = paraBEM.PanelVector3(-0.5, -0.5, 0) pnt2 = paraBEM.PanelVector3(0.5, -0.5, 0) pnt3 = paraBEM.PanelVector3(0.5, 0.5, 0) pnt4 = paraBEM.PanelVector3(-0.5, 0.5, 0) source = paraBEM.Panel3([pnt1, pnt2, pnt3, pnt4]) x = np.linspace(-0, 5, 500) y = [] for xi in x: target = paraBEM.PanelVector3(xi, 0., 0.1) panel_infl = doublet_3_0_vsaero(target, source) point_infl = doublet_3_0_n0(target, source) y.append([panel_infl, point_infl, abs(panel_infl - point_infl)]) y = list(zip(*y)) plt.figure(figsize=(8, 3)) plt.gcf().subplots_adjust(bottom=0.15) plt.ylabel("Einfluss")
from __future__ import division import numpy as np import matplotlib matplotlib.use('Agg') from matplotlib import pyplot as plt import paraBEM from paraBEM.pan3d import doublet_3_0_sphere, doublet_3_0_n0 x_range = [-1, 0, 1] y_range = [-1, 0, 1] points = [paraBEM.PanelVector3(x, y, 0) for y in y_range for x in x_range] panel_indices = [[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]] panels = [ paraBEM.Panel3([points[index] for index in indices]) for indices in panel_indices ] mue = [1, 1, 1, 100] mue_mid = sum(mue) / 4 mid_pan = paraBEM.Panel3([points[0], points[2], points[8], points[6]]) def infl_near(point): out = 0 target = paraBEM.Vector3(*point) for i, pan in enumerate(panels): out += mue[i] * doublet_3_0_sphere(target, pan) return out
import paraBEM from paraBEM.pan3d import doublet_3_0_vsaero, doublet_3_0_vsaero_v, doublet_3_0_sphere from paraBEM.vtk_export import VtkWriter import numpy from paraBEM.utils import check_path v1 = paraBEM.PanelVector3(-0.5, -0.5, 0) v2 = paraBEM.PanelVector3(0.5, -0.5, 0) v3 = paraBEM.PanelVector3(0.5, 0.5, 0) v4 = paraBEM.PanelVector3(-0.5, 0.5, 0) p = paraBEM.Panel3([v1, v2, v3, v4]) # p = paraBEM.Panel3([v1, v2, v3]) # triangle p.potential = 1. n = 50 a = numpy.linspace(-1, 1, n).tolist() b = [paraBEM.PanelVector3(i, j, k) for i in a for j in a for k in a] pot = [doublet_3_0_sphere(i, p) for i in b] vel = [doublet_3_0_vsaero_v(i, p) for i in b] writer = VtkWriter() with open(check_path("results/panel_influence.vtk"), "w") as _file: writer.structed_grid(_file, "duplet", [n, n, n]) writer.points(_file, b) writer.data(_file, pot, name="potential", _type="SCALARS",
import numpy as np import paraBEM from paraBEM import pan3d v1 = paraBEM.PanelVector3(-0.5, -0.5, 0) v2 = paraBEM.PanelVector3(0.5, -0.5, 0) v3 = paraBEM.PanelVector3(0.5, 0.5, 0) v4 = paraBEM.PanelVector3(-0.5, 0.5, 0) p = paraBEM.Panel3([v1, v2, v3, v4]) v5 = paraBEM.Vector3(0.5, 0, 0.5) v6 = paraBEM.Vector3(0.4999, 0, 0) v7 = paraBEM.Vector3(0.5, 0.0, 0) v8 = paraBEM.Vector3(0.5001, 0, 0) checklist = [v1, v2, v3, v4, v5, v6, v7, v8, p.center] for v in checklist: dip, src = pan3d.doublet_src_3_0_vsaero(v, p) print(v, ": doublet:", dip, "source:", src)
def paraBEM_Panels(glider, midribs=0, profile_numpoints=None, num_average=0, symmetric=False, distribution=None): """return the vertices, panels and the trailing edge of a glider, as paraBEM objects. midribs: midribs of a cell spanwise. if num_average is greater then 0 ballooning will be disables profile_numpoints: coordinates of every rib, choordwise num_average: steps to average a cell profile symmetric: set to True if a symmetric result is expected (this will reduce evaluation time) """ # paraBEM is not a dependency of openglider so if problems occure here, get the module. import paraBEM if symmetric: glider = glider.copy() else: glider = glider.copy_complete() glider.close_rib(0) glider.close_rib() if profile_numpoints: glider.profile_x_values = Distribution.from_nose_cos_distribution( profile_numpoints, 0.2) if num_average > 0: glider.apply_mean_ribs(num_average) glider.close_rib() ribs = glider.return_ribs(midribs, ballooning=False) else: ribs = glider.return_ribs(midribs) # deleting the last vertex of every rib (no trailing edge gap) ribs = [rib[:-1] for rib in ribs] # get a numbered representation + flatten vertices i = 0 vertices = [] ribs_new = [] panels = [] sym_panels = [] trailing_edge = [] for rib in ribs: rib_new = [] for vertex in rib: rib_new.append(i) vertices.append(vertex) i += 1 rib_new.append(rib_new[0]) ribs_new.append(rib_new) ribs = ribs_new panel_nr = 0 for i, rib_i in enumerate(ribs[:-1]): rib_j = ribs[i + 1] if symmetric: if vertices[rib_j[0]][1] > 0.00001: trailing_edge.append(rib_i[0]) else: trailing_edge.append(rib_i[0]) if i == len(ribs[:-2]): trailing_edge.append(rib_j[0]) for k, _ in enumerate(rib_j[:-1]): l = k + 1 panel = [rib_i[k], rib_j[k], rib_j[l], rib_i[l]] if symmetric: sym = True add_panel = False for p in panel: if not vertices[p][ 1] > -0.000001: # if one point lies on the y- side sym = False # y- is the mirrored side if not vertices[p][ 1] < 0.0001: # if one point lies on the y+ side add_panel = True if add_panel: panels.append(panel) if sym: sym_panels.append(panel_nr) panel_nr += 1 else: panels.append(panel) vertices = [paraBEM.PanelVector3(*point) for point in vertices] panels = [ paraBEM.Panel3([vertices[nr] for nr in panel]) for panel in panels ] trailing_edge = [vertices[nr] for nr in trailing_edge] for nr in sym_panels: panels[nr].set_symmetric() return vertices, panels, trailing_edge
import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import paraBEM from paraBEM.pan3d import doublet_3_0_sphere as doublet from paraBEM.utils import check_path pnt1 = paraBEM.PanelVector3(-0.5, -0.5, 0) pnt2 = paraBEM.PanelVector3(0.5, -0.5, 0) pnt3 = paraBEM.PanelVector3(0.5, 0.5, 0) pnt4 = paraBEM.PanelVector3(-0.5, 0.5, 0) source = paraBEM.Panel3([pnt1, pnt2, pnt3, pnt4]) x = np.linspace(-4, 4, 100) y = [] for xi in x: target1 = paraBEM.PanelVector3(xi, 0., 0.0) target2 = paraBEM.PanelVector3(xi, 0, 0.5) target3 = paraBEM.PanelVector3(xi, 0, 1.0) val1 = doublet(target1, source) val2 = doublet(target2, source) val3 = doublet(target3, source) y.append([val1, val2, val3]) fig = plt.figure() ax1 = fig.add_subplot(131) ax1.plot(x, y)
import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import paraBEM from paraBEM.pan3d import src_3_0_vsaero from paraBEM.utils import check_path pnt1 = paraBEM.PanelVector3(-1, -1, 0) pnt2 = paraBEM.PanelVector3(1, -1, 0) pnt3 = paraBEM.PanelVector3(1, 1, 0) pnt4 = paraBEM.PanelVector3(-1, 1, 0) source = paraBEM.Panel3([pnt1, pnt2, pnt3, pnt4]) fig = plt.figure() x = np.arange(-4, 4, 0.01) y = [] for xi in x: target1 = paraBEM.Vector3(xi, 0, 0.0) target2 = paraBEM.Vector3(xi, 0, 0.5) target3 = paraBEM.Vector3(xi, 0, 1) val1 = src_3_0_vsaero(target1, source) val2 = src_3_0_vsaero(target2, source) val3 = src_3_0_vsaero(target3, source) y.append([val1, val2, val3]) ax1 = fig.add_subplot(131) ax1.plot(x, y)
import paraBEM from paraBEM import pan3d pnt1 = paraBEM.PanelVector3(-0.4, -0.5, 0) pnt2 = paraBEM.PanelVector3(0.5, -0.2, 0) pnt3 = paraBEM.PanelVector3(0.3, 0.5, 0) pnt4 = paraBEM.PanelVector3(-0.5, 0.5, 0) pnt5 = paraBEM.PanelVector3(0.0, 0, 1) pnt6 = paraBEM.PanelVector3(0.3, 0.3, 0.3) source = paraBEM.Panel3([pnt1, pnt2, pnt3, pnt4]) checklist = [pnt1, pnt2, pnt3, pnt4, pnt5, pnt6, source.center] for trg_pnt in checklist: dip = pan3d.doublet_3_0_sphere(trg_pnt, source) print(trg_pnt, ": doublet:", dip)
def rib3d(airfoil, y_pos): out = [paraBEM.PanelVector3(coo[0], y_pos, coo[1]) for coo in airfoil.coordinates[:-1]] out.append(out[0]) out[0].wake_vertex = True return out