|
import keras |
|
import numpy |
|
import gradio |
|
import pandas |
|
import glob |
|
import os |
|
import shutil |
|
import math |
|
import platform |
|
import scipy.spatial |
|
import plotly.graph_objects as go |
|
import random |
|
from huggingface_hub import from_pretrained_keras |
|
|
|
def load_data(): |
|
|
|
from datasets import load_dataset |
|
|
|
S = 5 |
|
N = 1000 |
|
D = 3 |
|
F = 64 |
|
G = 32 |
|
|
|
data = load_dataset("cmudrc/wave-energy", data_files=["data.zip"], split='train') |
|
geometry = numpy.reshape(data['geometry'], (S*N, G*G*G)) |
|
curves = numpy.reshape(data['curves'], (S*N, D*F)) |
|
return None, None, S, N, D, F, G, curves, geometry |
|
|
|
|
|
from tensorflow.python.framework.ops import disable_eager_execution |
|
disable_eager_execution() |
|
|
|
class Mesh: |
|
def __init__(self): |
|
|
|
self.np = 0 |
|
self.nf = 0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = [] |
|
|
|
def combine_meshes(self, ob1, ob2): |
|
|
|
if ob1.nf < ob2.nf: |
|
coin_test = ob1.make_coin() |
|
coin_target = ob2.make_coin() |
|
else: |
|
coin_test = ob2.make_coin() |
|
coin_target = ob1.make_coin() |
|
|
|
deletion_list = [] |
|
for iF in range(numpy.size(coin_test[1, 1, :])): |
|
panel_test = coin_test[:, :, iF] |
|
for iFF in range(numpy.size(coin_target[1, 1, :])): |
|
panel_target = coin_target[:, :, iFF] |
|
if numpy.sum(panel_test == panel_target) == 12: |
|
coin_target = numpy.delete(coin_target, iFF, 2) |
|
deletion_list.append(iF) |
|
coin_test = numpy.delete(coin_test, deletion_list, 2) |
|
|
|
|
|
coin = numpy.concatenate((coin_test, coin_target), axis=2) |
|
self.np = numpy.size(coin[1, 1, :]) * 4 |
|
self.nf = numpy.size(coin[1, 1, :]) |
|
self.X = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Y = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Z = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.P = numpy.zeros((numpy.size(coin[1, 1, :]), 4), dtype=int) |
|
|
|
iP = 0 |
|
for iF in range(numpy.size(coin[1, 1, :])): |
|
for iC in range(4): |
|
self.X[iP] = coin[0, iC, iF] |
|
self.Y[iP] = coin[1, iC, iF] |
|
self.Z[iP] = coin[2, iC, iF] |
|
iP += 1 |
|
self.P[iF, 0] = 1 + iF * 4 |
|
self.P[iF, 1] = 2 + iF * 4 |
|
self.P[iF, 2] = 3 + iF * 4 |
|
self.P[iF, 3] = 4 + iF * 4 |
|
|
|
def make_coin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
def delete_horizontal_panels(self): |
|
coin = self.make_coin() |
|
apex = numpy.min(self.Z) |
|
zLoc = numpy.zeros(4) |
|
deletion_list = [] |
|
|
|
|
|
for iP in range(self.nf): |
|
for iC in range(4): |
|
zLoc[iC] = coin[2, iC, iP] |
|
if numpy.abs(numpy.mean(zLoc) - zLoc[0]) < 0.001 and numpy.mean(zLoc) > apex: |
|
deletion_list.append(iP) |
|
|
|
|
|
coin = numpy.delete(coin, deletion_list, 2) |
|
|
|
|
|
self.np = numpy.size(coin[1, 1, :]) * 4 |
|
self.nf = numpy.size(coin[1, 1, :]) |
|
self.X = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Y = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Z = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.P = numpy.zeros((numpy.size(coin[1, 1, :]), 4), dtype=int) |
|
|
|
iP = 0 |
|
for iF in range(numpy.size(coin[1, 1, :])): |
|
for iC in range(4): |
|
self.X[iP] = coin[0, iC, iF] |
|
self.Y[iP] = coin[1, iC, iF] |
|
self.Z[iP] = coin[2, iC, iF] |
|
iP += 1 |
|
self.P[iF, 0] = 1 + (iF) * 4 |
|
self.P[iF, 1] = 2 + (iF) * 4 |
|
self.P[iF, 2] = 3 + (iF) * 4 |
|
self.P[iF, 3] = 4 + (iF) * 4 |
|
|
|
|
|
|
|
|
|
def writeMesh(msh, filename): |
|
with open(filename, 'w') as f: |
|
f.write('{:d}\n'.format(msh.np)) |
|
f.write('{:d}\n'.format(msh.nf)) |
|
for iP in range(msh.np): |
|
f.write(' {:.7f} {:.7f} {:.7f}\n'.format(msh.X[iP], msh.Y[iP], msh.Z[iP])) |
|
for iF in range(msh.nf): |
|
f.write(' {:d} {:d} {:d} {:d}\n'.format(msh.P[iF, 0], msh.P[iF, 1], msh.P[iF, 2], msh.P[iF, 3])) |
|
return None |
|
|
|
|
|
|
|
class box: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'box' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[-self.length / 2.0, self.length / 2.0, -self.length / 2.0, self.length / 2.0, -self.length / 2.0, |
|
self.length / 2.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array([self.width / 2.0, self.width / 2.0, self.width / 2.0, self.width / 2.0, -self.width / 2.0, |
|
-self.width / 2.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array( |
|
[-self.height / 2.0, -self.height / 2.0, self.height / 2.0, self.height / 2.0, -self.height / 2.0, |
|
-self.height / 2.0, self.height / 2.0, self.height / 2.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([2, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class cone: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'cone' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, 0] |
|
z = [0, 0, -self.height] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.X.append(r[iN] * numpy.cos(theta[iT])) |
|
self.Y.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Z.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 0] = iN + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * iT |
|
self.P[iP, 3] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
class cylinder: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'cylinder' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, self.diameter / 2.0, 0] |
|
z = [0, 0, -self.height, -self.height] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.X.append(r[iN] * numpy.cos(theta[iT])) |
|
self.Y.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Z.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 0] = iN + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * iT |
|
self.P[iP, 3] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class hemicylinder: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'hemicylinder' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * numpy.pi / (Ntheta - 1) - numpy.pi / 2.0 for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, self.diameter / 2.0, 0] |
|
z = [self.height / 2.0, self.height / 2.0, -self.height / 2.0, -self.height / 2.0] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.Z.append(-r[iN] * numpy.cos(theta[iT])) |
|
self.X.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Y.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 3] = iN + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * iT |
|
self.P[iP, 0] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
class sphere: |
|
def __init__(self, diameter, cCor): |
|
self.diameter = diameter |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'sphere' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nthetad2 = int(Ntheta / 2) |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * numpy.pi / (Ntheta / 2 - 1) for xx in range(Nthetad2)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = self.diameter / 2.0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(Ntheta - 1) * (Nthetad2 - 1), 4], dtype=int) |
|
|
|
for iT in range(Nthetad2): |
|
for iTT in range(Ntheta): |
|
self.X.append(r * numpy.cos(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Y.append(r * numpy.sin(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Z.append(r * numpy.cos(phi[iT])) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, Ntheta): |
|
for iT in range(1, Nthetad2): |
|
self.P[iP, 3] = iN + Ntheta * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + Ntheta * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + Ntheta * iT |
|
self.P[iP, 0] = iN + Ntheta * iT |
|
self.nf += 1 |
|
iP += 1 |
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class hemisphere: |
|
def __init__(self, diameter, cCor): |
|
self.diameter = diameter |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'hemisphere' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * numpy.pi / 2.0 / (Ntheta / 2 - 1) for xx in range(Ntheta / 2)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = self.diameter / 2.0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(Ntheta - 1) * (Ntheta / 2 - 1), 4], dtype=int) |
|
|
|
for iT in range(Ntheta / 2): |
|
for iTT in range(Ntheta): |
|
self.X.append(r * numpy.cos(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Y.append(r * numpy.sin(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Z.append(-r * numpy.cos(phi[iT])) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, Ntheta): |
|
for iT in range(1, Ntheta / 2): |
|
self.P[iP, 0] = iN + Ntheta * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + Ntheta * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + Ntheta * iT |
|
self.P[iP, 3] = iN + Ntheta * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class pyramid: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'pyramid' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[0.0, 0.0, -self.length / 2.0, self.length / 2.0, 0.0, 0.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array( |
|
[0.0, 0.0, self.width / 2.0, self.width / 2.0, 0.0, 0.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array([-self.height, -self.height, 0.0, 0.0, -self.height, -self.height, 0.0, 0.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([5, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class wedge: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'wedge' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[0.0, 0.0, -self.length / 2.0, self.length / 2.0, 0.0, 0.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array([self.width / 2.0, self.width / 2.0, self.width / 2.0, self.width / 2.0, -self.width / 2.0, |
|
-self.width / 2.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array([-self.height, -self.height, 0.0, 0.0, -self.height, -self.height, 0.0, 0.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([2, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class torus: |
|
def __init__(self, diamOut, diamIn, cCor): |
|
self.diamOut = diamOut |
|
self.diamIn = diamIn |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'torus' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nphi = 18 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * 2 * numpy.pi / (Nphi - 1) for xx in range(Nphi)] |
|
self.nf = 0 |
|
self.np = 0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
R = self.diamOut / 2.0 |
|
r = self.diamIn / 2.0 |
|
|
|
for iT in range(Ntheta): |
|
for iP in range(Nphi): |
|
self.X.append((R + r * numpy.cos(theta[iT])) * numpy.cos(phi[iP])) |
|
self.Y.append((R + r * numpy.cos(theta[iT])) * numpy.sin(phi[iP])) |
|
self.Z.append(r * numpy.sin(theta[iT])) |
|
self.np += 1 |
|
|
|
self.nf = (Ntheta - 1) * (Nphi - 1) |
|
self.P = numpy.zeros([self.nf, 4], dtype=int) |
|
iPan = 0 |
|
for iT in range(Ntheta - 1): |
|
for iP in range(Nphi - 1): |
|
self.P[iPan, 0] = iP + iT * Nphi + 1 |
|
self.P[iPan, 1] = iP + 1 + iT * Nphi + 1 |
|
self.P[iPan, 2] = iP + 1 + Ntheta + iT * Nphi + 1 |
|
self.P[iPan, 3] = iP + Ntheta + iT * Nphi + 1 |
|
iPan += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
def make_voxels_without_figure(shape, length, height, width, diameter): |
|
pos = [0, 0, 0] |
|
if shape == "box": |
|
mesh = box(length, width, height, pos) |
|
elif shape == "cone": |
|
mesh = cone(diameter, height, pos) |
|
elif shape == "cylinder": |
|
mesh = cylinder(diameter, height, pos) |
|
elif shape == "sphere": |
|
mesh = sphere(diameter, pos) |
|
elif shape == "wedge": |
|
mesh = wedge(length, width, height, pos) |
|
|
|
hull_points = numpy.array([mesh.X.tolist(), mesh.Y.tolist(), mesh.Z.tolist()]).T |
|
|
|
|
|
G = 32 |
|
ex = 5 - 5 / G |
|
x, y, z = numpy.meshgrid(numpy.linspace(-ex, ex, G), |
|
numpy.linspace(-ex, ex, G), |
|
numpy.linspace(-(9.5 - 5 / G), 0.5 - 5 / G, G)) |
|
test_points = numpy.vstack((x.ravel(), y.ravel(), z.ravel())).T |
|
|
|
hull = scipy.spatial.Delaunay(hull_points) |
|
within = hull.find_simplex(test_points) >= 0 |
|
|
|
return within*1.0 |
|
|
|
|
|
def make_voxels(shape, length, height, width, diameter): |
|
return plotly_fig(make_voxels_without_figure(shape, length, height, width, diameter)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
curves, geometry, S, N, D, F, G, new_curves, new_geometry = load_data() |
|
|
|
class Network(object): |
|
|
|
def __init__(self, type): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.network = from_pretrained_keras("cmudrc/wave-energy-analysis") if type == "forward" else from_pretrained_keras("cmudrc/wave-energy-synthesis") |
|
|
|
def analysis(self, idx=None): |
|
print(idx) |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, S * N) |
|
else: |
|
idx = int(idx) |
|
|
|
|
|
data_input = new_geometry[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((G, G, G), order='F') |
|
|
|
|
|
print(data_input.shape) |
|
predicted_output = self.network.predict(data_input) |
|
true_output = new_curves[idx].reshape((3, F)) |
|
predicted_output = predicted_output.reshape((3, F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(predicted_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
df_true = pandas.DataFrame(true_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
|
|
|
|
return pandas.concat([fd, df_pred], axis=1), pandas.concat([fd, df_true], axis=1) |
|
|
|
|
|
def analysis_from_geometry(self, geometry): |
|
|
|
predicted_output = self.network.predict(numpy.array([geometry.flatten().tolist()])) |
|
predicted_output = predicted_output.reshape((3, F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(predicted_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
good_frame = pandas.concat([fd, df_pred], axis=1) |
|
|
|
return good_frame, good_frame |
|
|
|
def synthesis(self, idx=None): |
|
print(idx) |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, S * N) |
|
else: |
|
idx = int(idx) |
|
|
|
|
|
data_input = new_curves[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((3, F)) |
|
|
|
|
|
predicted_output = self.network.predict(data_input) |
|
true_output = new_geometry[idx].reshape((G, G, G), order='F') |
|
predicted_output = predicted_output.reshape((G, G, G), order='F') |
|
|
|
|
|
return predicted_output, true_output |
|
|
|
|
|
def synthesis_from_spectrum(self, other_data_input): |
|
|
|
data_input = other_data_input.reshape((1, 3*F)) |
|
|
|
|
|
predicted_output = self.network.predict(data_input) |
|
predicted_output = predicted_output.reshape((G, G, G), order='F') |
|
|
|
|
|
return predicted_output |
|
|
|
def get_geometry(self, idx=None): |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, S * N) |
|
else: |
|
idx = int(idx) |
|
|
|
idx = int(idx) |
|
|
|
|
|
data_input = new_geometry[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((G, G, G), order='F') |
|
|
|
|
|
return other_data_input |
|
|
|
|
|
def get_performance(self, idx=None): |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, S *N) |
|
else: |
|
idx = int(idx) |
|
|
|
idx = int(idx) |
|
|
|
|
|
data_input = new_curves[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((3, F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(other_data_input.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
table = pandas.concat([fd, df_pred], axis=1) |
|
|
|
return table |
|
|
|
|
|
def plotly_fig(values): |
|
X, Y, Z = numpy.mgrid[0:1:32j, 0:1:32j, 0:1:32j] |
|
fig = go.Figure(data=go.Volume( |
|
x=X.flatten(), |
|
y=Y.flatten(), |
|
z=Z.flatten(), |
|
value=values.flatten(), |
|
isomin=0.0, |
|
isomax=1.0, |
|
opacity=0.1, |
|
surface_count=21, |
|
colorscale='haline' |
|
)) |
|
return fig |
|
|
|
|
|
value_net = Network("forward") |
|
|
|
def performance(index): |
|
return value_net.get_performance(index) |
|
|
|
def geometry(index): |
|
values = value_net.get_geometry(index) |
|
return plotly_fig(values) |
|
|
|
def simple_analysis(index, choice, shape, length, width, height, diameter): |
|
forward_net = Network("forward") |
|
|
|
if choice == "Construct Shape from Parameters": |
|
return forward_net.analysis_from_geometry(make_voxels_without_figure(shape, length, height, width, diameter)) |
|
elif choice == "Pick Shape from Dataset": |
|
return forward_net.analysis(index) |
|
|
|
|
|
def simple_synthesis(index): |
|
inverse_net = Network("inverse") |
|
|
|
pred, true = inverse_net.synthesis(index) |
|
return plotly_fig(pred), plotly_fig(true) |
|
|
|
def synthesis_from_spectrum(df): |
|
inverse_net = Network("inverse") |
|
|
|
pred = inverse_net.synthesis_from_spectrum(df.to_numpy()[:, 1:]) |
|
return plotly_fig(pred) |
|
|
|
|
|
|
|
def change_textbox(choice, length, height, width, diameter): |
|
fig = make_voxels(choice, length, height, width, diameter) |
|
if choice == "cylinder": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
elif choice == "sphere": |
|
return [gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
elif choice == "box": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Plot.update(fig)] |
|
elif choice == "wedge": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Plot.update(fig)] |
|
elif choice == "cone": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
|
|
|
|
|
|
def randomize_analysis(choice): |
|
if choice == "Construct Shape from Parameters": |
|
length = random.uniform(3.0, 10.0) |
|
height = random.uniform(3.0, 10.0) |
|
width = random.uniform(3.0, 10.0) |
|
diameter = random.uniform(3.0, 10.0) |
|
choice2 = random.choice(["box", "cone", "sphere", "wedge", "cone"]) |
|
if choice2 == "box" or choice2 == "wedge": |
|
return [gradio.Radio.update(choice2), gradio.Slider.update(length), gradio.Slider.update(height), gradio.Slider.update(width), gradio.Slider.update(), gradio.Number.update(), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice2 == "cone" or choice2 == "cylinder": |
|
return [gradio.Radio.update(choice2), gradio.Slider.update(), gradio.Slider.update(height), gradio.Slider.update(), gradio.Slider.update(diameter), gradio.Number.update(), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice2 == "sphere": |
|
return [gradio.Radio.update(choice2), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(diameter), gradio.Number.update(), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice == "Pick Shape from Dataset": |
|
num = random.randint(1, 4999) |
|
return [gradio.Radio.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Number.update(num), gradio.Plot.update(geometry(num))] |
|
|
|
|
|
|
|
def geometry_change(choice, choice2, num, length, width, height, diameter): |
|
if choice == "Construct Shape from Parameters": |
|
[slider1, slider2, slider3, slider4, plot] = change_textbox(choice2, length, height, width, diameter) |
|
return [gradio.Radio.update(visible=True), slider1, slider2, slider3, slider4, gradio.Number.update(visible=False), gradio.Timeseries.update(visible=False), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice == "Pick Shape from Dataset": |
|
return [gradio.Radio.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Number.update(visible=True), gradio.Timeseries.update(visible=True), gradio.Plot.update(geometry(num))] |
|
|
|
with gradio.Blocks() as demo: |
|
with gradio.Accordion("✨ Read about the underlying ML model here! ✨", open=False): |
|
with gradio.Row(): |
|
with gradio.Column(): |
|
gradio.Markdown("# Toward the Rapid Design of Engineered Systems Through Deep Neural Networks") |
|
gradio.HTML("Christopher McComb, Carnegie Mellon University") |
|
gradio.Markdown("__Abstract__: The design of a system commits a significant portion of the final cost of that system. Many computational approaches have been developed to assist designers in the analysis (e.g., computational fluid dynamics) and synthesis (e.g., topology optimization) of engineered systems. However, many of these approaches are computationally intensive, taking significant time to complete an analysis and even longer to iteratively synthesize a solution. The current work proposes a methodology for rapidly evaluating and synthesizing engineered systems through the use of deep neural networks. The proposed methodology is applied to the analysis and synthesis of offshore structures such as oil platforms. These structures are constructed in a marine environment and are typically designed to achieve specific dynamics in response to a known spectrum of ocean waves. Results show that deep learning can be used to accurately and rapidly synthesize and analyze offshore structure.") |
|
with gradio.Column(): |
|
download = gradio.HTML("<a href=\"https://huggingface.co/spaces/cmudrc/wecnet/resolve/main/McComb2019_Chapter_TowardTheRapidDesignOfEngineer.pdf\" style=\"width: 60%; display: block; margin: auto;\"><img src=\"https://huggingface.co/spaces/cmudrc/wecnet/resolve/main/coverpage.png\"></a>") |
|
|
|
gradio.Markdown("When designing offshore structure, like [wave energy converters](https://www.nrel.gov/news/program/2021/how-wave-energy-could-go-big-by-getting-smaller.html), it's important to know what forces will be placed on the structure as waves come at different speeds. Likewise, if we have some idea of how we want the structure to respond to different waves, we can use that to guide the design of the shape of the structure. We call the first process _Analysis_, and the second process _Synthesis_. This demo has ML models that do both, very quickly.") |
|
|
|
with gradio.Tab("Analysis"): |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
whence_commeth_geometry = gradio.Radio( |
|
["Construct Shape from Parameters", "Pick Shape from Dataset"], label="How would you like to generate the shape of the offshore structure for analysis?", value="Construct Shape from Parameters" |
|
) |
|
radio = gradio.Radio( |
|
["box", "cone", "cylinder", "sphere", "wedge"], label="What kind of shape would you like to generate?", value="sphere" |
|
) |
|
height = gradio.Slider(label="Height", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
width = gradio.Slider(label="Width", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
diameter = gradio.Slider(label="Diameter", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=True) |
|
length = gradio.Slider(label="Length", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
|
|
|
|
num = gradio.Number(42, label="Type the index of the spectrum you would like to use or randomly select it.", visible=False) |
|
|
|
btn1 = gradio.Button("Randomize") |
|
with gradio.Column(): |
|
geo = gradio.Plot(make_voxels("sphere", 6.5, 6.5, 6.5, 6.5), label="Geometry") |
|
|
|
|
|
with gradio.Row(): |
|
btn2 = gradio.Button("Estimate Spectrum") |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
pred = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="Predicted") |
|
|
|
with gradio.Column(): |
|
true = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="True", visible=False) |
|
|
|
radio.change(fn=change_textbox, inputs=[radio, length, height, width, diameter], outputs=[height, width, diameter, length, geo]) |
|
height.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
width.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
diameter.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
length.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
whence_commeth_geometry.change(fn=geometry_change, inputs=[whence_commeth_geometry, radio, num, length, width, height, diameter], outputs=[radio, height, width, diameter, length, num, true, geo]) |
|
num.change(fn=geometry, inputs=[num], outputs=[geo]) |
|
|
|
btn1.click(fn=randomize_analysis, inputs=[whence_commeth_geometry], outputs=[radio, length, height, width, diameter, num, geo]) |
|
btn2.click(fn=simple_analysis, inputs=[num, whence_commeth_geometry, radio, length, width, height, diameter], outputs=[pred, true], api_name="analyze") |
|
with gradio.Tab("Synthesis"): |
|
with gradio.Row(): |
|
with gradio.Column(): |
|
whence_commeth_performance = gradio.Radio( |
|
["Pick Spectrum from Dataset"], label="How would you like to generate the desired response spectrum to synthesize from?", value="Construct Spectrum from Table" |
|
) |
|
num = gradio.Number(42, label="Type the index of the shape you would like to use or randomly select it.") |
|
btn1 = gradio.Button("Randomize") |
|
with gradio.Column(): |
|
perf = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="Performance") |
|
|
|
with gradio.Row(): |
|
btn2 = gradio.Button("Synthesize Geometry") |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
pred = gradio.Plot(label="Predicted") |
|
|
|
with gradio.Column(): |
|
true = gradio.Plot(label="True") |
|
|
|
|
|
btn1.click(fn=lambda: random.randint(1, 4999), inputs=[], outputs=num) |
|
num.change(fn=performance, inputs=[num], outputs=[perf]) |
|
btn2.click(fn=simple_synthesis, inputs=[num], outputs=[pred, true], api_name="synthesize") |
|
|
|
demo.launch() |