22 changed files with 0 additions and 1896 deletions
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.0 KiB |
@ -1,45 +0,0 @@ |
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
class ANN_Model(nn.Module): |
|||
def __init__(self,input_features=8,out_features=72): |
|||
super().__init__() |
|||
self.fc1=nn.Linear(input_features,12) |
|||
self.fc2=nn.Linear(12,16) |
|||
self.fc3=nn.Linear(16,20) |
|||
self.fc4=nn.Linear(20,25) |
|||
|
|||
self.fc5=nn.Linear(50,60) |
|||
self.fc6=nn.Linear(60,70) |
|||
self.fc7=nn.Linear(70,80) |
|||
self.fc8=nn.Linear(80,90) |
|||
self.fc9=nn.Linear(90,100) |
|||
self.fc10=nn.Linear(100,90) |
|||
self.fc11=nn.Linear(90,80) |
|||
|
|||
|
|||
self.out=nn.Linear(80,out_features) |
|||
|
|||
|
|||
def forward(self,x): |
|||
density=x[:,:25].reshape(x.shape[0],25) |
|||
displace = x[:,25:] |
|||
x = F.relu(self.fc1(displace)) |
|||
x = F.relu(self.fc2(x)) |
|||
x = F.relu(self.fc3(x)) |
|||
x = F.relu(self.fc4(x)) |
|||
x = torch.hstack((density,x)) |
|||
|
|||
x = F.relu(self.fc5(x)) |
|||
x = F.relu(self.fc6(x)) |
|||
x = F.relu(self.fc7(x)) |
|||
x = F.relu(self.fc8(x)) |
|||
x = F.relu(self.fc9(x)) |
|||
x = F.relu(self.fc10(x)) |
|||
x = F.relu(self.fc11(x)) |
|||
|
|||
|
|||
x = self.out(x) |
|||
|
|||
return x |
@ -1,76 +0,0 @@ |
|||
#### ENCODER_Model |
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
class AutoEncoder_Model(nn.Module): |
|||
def __init__(self,input_features=33,out_features=72): |
|||
super().__init__() |
|||
self.upsample25x=nn.Upsample(scale_factor=2.5, mode='bilinear') |
|||
|
|||
self.fc1=nn.Linear(75,100) |
|||
self.fc2=nn.Linear(100,150) |
|||
self.fc3=nn.Linear(150,200) |
|||
self.fc4=nn.Linear(200,300) |
|||
self.fc5=nn.Linear(300,400) |
|||
self.fc6=nn.Linear(400,500) |
|||
self.fc7=nn.Linear(500,576) |
|||
|
|||
self.fc8=nn.Linear(576,500) |
|||
self.fc9=nn.Linear(500,400) |
|||
self.fc10=nn.Linear(400,300) |
|||
self.fc11=nn.Linear(300,200) |
|||
self.fc12=nn.Linear(200,150) |
|||
self.fc13=nn.Linear(150,100) |
|||
self.fc14=nn.Linear(100,72) |
|||
|
|||
|
|||
def forward(self,x): |
|||
B=x.shape[0] |
|||
density=x[:,:25] |
|||
density=density.reshape(B,1,5,5) # B 1(C) 5 5 |
|||
|
|||
u = x[:,25:29].reshape(B,1,2,2) # B 1(C) 2 2 |
|||
v = x[:,29:].reshape(B,1,2,2) # B 1(C) 2 2 |
|||
|
|||
displace = torch.cat((u,v),1) # B 2(C) 2 2 |
|||
|
|||
displace = self.upsample25x(displace) #升维度 -> B 2 5 5 |
|||
|
|||
# 1.矩阵相乘做耦合 |
|||
# u = torch.mul(displace[:,0,:,:],density[:,0,:,:]) |
|||
# v = torch.mul(displace[:,1,:,:],density[:,0,:,:]) |
|||
# x = torch.stack((u,v),1) # B 2 5 5 |
|||
# x = x.reshape(B,50) |
|||
|
|||
# 2.卷积做耦合 |
|||
# self.conv55=nn.Conv2d(3,2,3,padding=1) # B 3 5 5 -> B 2 5 5 |
|||
# |
|||
|
|||
# 3.直接 cat 接上 |
|||
x = torch.cat((displace,density),1) |
|||
x = x.reshape(B,75) |
|||
|
|||
x = torch.autograd.Variable(x,requires_grad=True) |
|||
|
|||
|
|||
# Encode |
|||
x = F.relu(self.fc1(x)) |
|||
x = F.relu(self.fc2(x)) |
|||
x = F.relu(self.fc3(x)) |
|||
x = F.relu(self.fc4(x)) |
|||
x = F.relu(self.fc5(x)) |
|||
x = F.relu(self.fc6(x)) |
|||
x = F.relu(self.fc7(x)) |
|||
shape_func=x.clone() |
|||
|
|||
# Decode |
|||
x = F.relu(self.fc8(x)) |
|||
x = F.relu(self.fc9(x)) |
|||
x = F.relu(self.fc10(x)) |
|||
x = F.relu(self.fc11(x)) |
|||
x = F.relu(self.fc12(x)) |
|||
x = F.relu(self.fc13(x)) |
|||
x = F.relu(self.fc14(x)) |
|||
|
|||
return x, shape_func |
@ -1,63 +0,0 @@ |
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
class CNN_Model(nn.Module): |
|||
def __init__(self,input_features=8,out_features=72): |
|||
super().__init__() |
|||
|
|||
self.upsample25x=nn.Upsample(scale_factor=2.5, mode='bilinear') |
|||
# self.conv55=nn.Conv2d(3,3,3,padding=1) # keep B 3 5 5 |
|||
# self.conv56=nn.Conv2d(3,3,4,padding=2) # B 3 5 5 -> B 3 5 6 |
|||
|
|||
# self.conv66_1=nn.Conv2d(3,5,3,padding=1) # B 3 6 6 -> B 64 6 6 |
|||
# self.conv66_2=nn.Conv2d(5,8,3,padding=1) # B 64 6 6 -> B 32 6 6 |
|||
# self.conv66_3=nn.Conv2d(8,5,3,padding=1) # B 32 6 6 -> B 8 6 6 |
|||
# self.conv66_4=nn.Conv2d(5,2,3,padding=1) # B 8 6 6 -> B 2 6 6 |
|||
|
|||
self.conv55=nn.Conv2d(3,2,3,padding=1) # B 3 5 5 -> B 2 5 5 |
|||
self.fc1=nn.Linear(50,70) |
|||
self.fc2=nn.Linear(70,90) |
|||
self.fc3=nn.Linear(90,110) |
|||
self.fc4=nn.Linear(110,130) |
|||
self.fc5=nn.Linear(130,100) |
|||
self.fc6=nn.Linear(100,80) |
|||
self.fc7=nn.Linear(80,72) |
|||
|
|||
def forward(self,x): |
|||
B=x.shape[0] |
|||
density=x[:,:25] |
|||
density=density.reshape(B,1,5,5) # B 1 5 5 |
|||
|
|||
|
|||
displace = x[:,25:] |
|||
displace = displace.reshape(B,2,2,2) # B 2 2 2(C) |
|||
displace = displace.permute(0,3,1,2) #更换张量维度顺序为->B C W H |
|||
displace = self.upsample25x(displace) #升维度 -> B 2 5 5 |
|||
|
|||
# x = torch.cat((displace,density),1) |
|||
|
|||
|
|||
# x = F.relu(self.conv56(x)) |
|||
# x = F.relu(self.conv66_1(x)) |
|||
# x = F.relu(self.conv66_2(x)) |
|||
# x = F.relu(self.conv66_3(x)) |
|||
# x = F.relu(self.conv66_4(x)) |
|||
|
|||
# x = x.permute(0,2,3,1) |
|||
# x = x.reshape(B,72) |
|||
|
|||
u = torch.mul(displace[:,0,:,:],density[:,0,:,:]).reshape(B,25) |
|||
v = torch.mul(displace[:,1,:,:],density[:,0,:,:]).reshape(B,25) |
|||
x = torch.cat((u,v),1) |
|||
|
|||
|
|||
x = F.relu(self.fc1(x)) |
|||
x = F.relu(self.fc2(x)) |
|||
x = F.relu(self.fc3(x)) |
|||
x = F.relu(self.fc4(x)) |
|||
x = F.relu(self.fc5(x)) |
|||
x = F.relu(self.fc6(x)) |
|||
x = F.relu(self.fc7(x)) |
|||
|
|||
return x |
@ -1,110 +0,0 @@ |
|||
import argparse |
|||
import os |
|||
from utils import utils |
|||
import torch |
|||
|
|||
|
|||
class BaseOptions(): |
|||
"""This class defines options used during both training and test time. |
|||
|
|||
It also implements several helper functions such as parsing, printing, and saving the options. |
|||
It also gathers additional options defined in <modify_commandline_options> functions in both dataset class and model class. |
|||
""" |
|||
|
|||
def __init__(self): |
|||
"""Reset the class; indicates the class hasn't been initailized""" |
|||
self.initialized = False |
|||
|
|||
def initialize(self, parser): |
|||
"""Define the common options that are used in both training and test.""" |
|||
# basic parameters |
|||
parser.add_argument('--dataroot', type=str, default='./datasets', help='root path to datasets') |
|||
parser.add_argument('--name', type=str, default='experiment_name', help='name of the experiment. It decides where to store samples and models') |
|||
parser.add_argument('--gpu_id', type=str, default='0', help='gpu ids: e.g. 0, 1, ... . use -1 for CPU') |
|||
parser.add_argument('--device', type=str, default='cuda:0', help='generate device with gpu_id and usable user device') |
|||
parser.add_argument('--checkpoints_dir', type=str, default='./checkpoints', help='models are saved here') |
|||
parser.add_argument('--ms_ratio', type=int, default=5, help='multiscale ratio') |
|||
|
|||
# model parameters |
|||
parser.add_argument('--model', type=str, default='ANN', help='chooses which model to use. [ANN | CNN | AutoEncoder]') |
|||
# dataset parameters |
|||
# parser.add_argument('--resolution', type=str, default='180_60', help='data resolution. nelx_nely here') |
|||
parser.add_argument('--nelx', type=int, default=180, help='num of elements on x-axis') |
|||
parser.add_argument('--nely', type=int, default=60, help='num of elements on y-axis') |
|||
parser.add_argument('--nelz', type=int, default=1, help='num of elements on z-axis') |
|||
parser.add_argument('--dimension', type=int, default=2, help='dimension of dataset models') |
|||
parser.add_argument('--is_standard', type=bool, default=False, help='whether need standardization or not') |
|||
|
|||
# additional parameters |
|||
parser.add_argument('--epoch', type=str, default='latest', help='which epoch to load? set to latest to use latest cached model') |
|||
parser.add_argument('--load_iter', type=int, default=0, help='which iteration to load? if load_iter > 0, the code will load models by iter_[load_iter]; otherwise, the code will load models by [epoch]') |
|||
parser.add_argument('--verbose', action='store_true', help='if specified, print more debugging information') |
|||
parser.add_argument('--suffix', type=str, default='', help='customized suffix: opt.name = opt.name + suffix: e.g., {model}_{netG}_size{load_size}') |
|||
|
|||
# identify initializiation timing |
|||
self.initialized = True |
|||
return parser |
|||
|
|||
def gather_options(self): |
|||
"""Initialize our parser with basic options(only once). |
|||
Add additional model-specific and dataset-specific options. |
|||
These options are defined in the <modify_commandline_options> function |
|||
in model and dataset classes. |
|||
""" |
|||
if not self.initialized: # check if it has been initialized |
|||
parser = argparse.ArgumentParser() # customize help formatting with <formatter_class> |
|||
parser = self.initialize(parser) |
|||
|
|||
# get the basic options |
|||
opt, _ = parser.parse_known_args() |
|||
|
|||
# save and return the parser |
|||
self.parser = parser |
|||
return parser.parse_args() |
|||
|
|||
def print_options(self, opt): |
|||
"""Print and save options |
|||
|
|||
It will print both current options and default values(if different). |
|||
It will save options into a text file / [checkpoints_dir] / opt.txt |
|||
""" |
|||
message = '' |
|||
message += '----------------- Options ---------------\n' |
|||
for k, v in sorted(vars(opt).items()): |
|||
comment = '' |
|||
default = self.parser.get_default(k) |
|||
if v != default: |
|||
comment = '\t[default: %s]' % str(default) |
|||
message += '{:>25}: {:<30}{}\n'.format(str(k), str(v), comment) |
|||
message += '----------------- End -------------------' |
|||
print(message) |
|||
|
|||
# save to the disk |
|||
expr_dir = os.path.join(opt.checkpoints_dir, opt.model+'_'+opt.mod) |
|||
utils.mkdir(expr_dir) |
|||
file_name = os.path.join(expr_dir, '{}_opt.txt'.format(opt.phase)) |
|||
with open(file_name, 'wt') as opt_file: |
|||
opt_file.write(message) |
|||
opt_file.write('\n') |
|||
|
|||
def parse(self): |
|||
"""Parse our options, create checkpoints directory suffix, and set up gpu device.""" |
|||
opt = self.gather_options() |
|||
opt.isTrain = self.isTrain # train or test |
|||
|
|||
# process opt.suffix |
|||
if opt.suffix: |
|||
suffix = ('_' + opt.suffix.format(**vars(opt))) if opt.suffix != '' else '' |
|||
opt.name = opt.name + suffix |
|||
|
|||
self.print_options(opt) |
|||
|
|||
# set device with gpu id |
|||
if opt.gpu_id == -1: |
|||
opt.device = 'cpu' |
|||
else: |
|||
opt.device = f'cuda:{opt.gpu_id}' if torch.cuda.is_available() else 'cpu' |
|||
|
|||
self.opt = opt |
|||
return self.opt |
|||
|
@ -1,19 +0,0 @@ |
|||
from .base_options import BaseOptions |
|||
|
|||
|
|||
class TestOptions(BaseOptions): |
|||
"""This class includes test options. |
|||
|
|||
It also includes shared options defined in BaseOptions. |
|||
""" |
|||
|
|||
def initialize(self, parser): |
|||
parser = BaseOptions.initialize(self, parser) # define shared options |
|||
parser.add_argument('--results_dir', type=str, default='./results', help='saves results here.') |
|||
parser.add_argument('--phase', type=str, default='test', help='train, val, test, etc') |
|||
parser.add_argument('--mod', type=str, default='mod3', help='chooses which dataset model for test. mod1....') |
|||
parser.add_argument('--pretrained_model_path', type=str, default='./checkpoints/ANN_mod1/ANN_mod1_opt.pt', help='pretrained model file load path') |
|||
|
|||
|
|||
self.isTrain = False |
|||
return parser |
@ -1,23 +0,0 @@ |
|||
from .base_options import BaseOptions |
|||
|
|||
|
|||
class TrainOptions(BaseOptions): |
|||
"""This class includes training options. |
|||
|
|||
It also includes shared options defined in BaseOptions. |
|||
""" |
|||
|
|||
def initialize(self, parser): |
|||
parser = BaseOptions.initialize(self, parser) |
|||
# visdom and HTML visualization parameters |
|||
|
|||
# network saving and loading parameters |
|||
parser.add_argument('--phase', type=str, default='train', help='train, val, test, etc') |
|||
|
|||
# training parameters |
|||
parser.add_argument('--epochs', type=int, default=10000, help='number of epochs') |
|||
parser.add_argument('--lr', type=float, default=0.001, help='initial learning rate for adam') |
|||
parser.add_argument('--mod', type=str, default='mod2', help='chooses which dataset model for train. mod1....') |
|||
|
|||
self.isTrain = True |
|||
return parser |
@ -1,4 +0,0 @@ |
|||
matplotlib==3.8.0 |
|||
numpy==1.26.2 |
|||
scikit_learn==1.3.0 |
|||
torch==2.1.0 |
@ -1,60 +0,0 @@ |
|||
import os |
|||
import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
|
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
from utils.data_standardizer import standardization |
|||
from utils.data_loader import data_loader |
|||
from options.test_options import TestOptions |
|||
|
|||
|
|||
def test(X, opt): |
|||
# OLD: model_load_path, X, standard = False, device = 0 |
|||
if opt.is_standard: |
|||
X = standardization(X) |
|||
|
|||
X_test=torch.from_numpy(X).type(torch.float32).to(opt.device) |
|||
|
|||
model = torch.load(opt.pretrained_model_path) |
|||
return model(X_test) |
|||
|
|||
|
|||
if __name__=='__main__': |
|||
# Load parmetaers |
|||
opt = TestOptions().parse() |
|||
|
|||
# Load datasets, mod2 as default |
|||
global_density, global_displace, coarse_density, coarse_displace, fine_displace = data_loader(opt) |
|||
X = np.hstack((coarse_density[:,:] , coarse_displace[:,:,0] , coarse_displace[:,:,1])) |
|||
Y = fine_displace[:,:] |
|||
|
|||
# Predict |
|||
pred = test(X, opt) |
|||
|
|||
# Set loss function |
|||
loss_function = nn.MSELoss() |
|||
# Calculate loss |
|||
pred_loss=[] |
|||
Y_test = torch.from_numpy(Y).type(torch.float32).to(opt.device) |
|||
for i in range(pred.shape[0]): |
|||
pred_loss.append(loss_function(pred[i,:],Y_test[i,:]).item()) |
|||
|
|||
print('Total loss: '+ str(loss_function(pred,Y_test).item())) |
|||
|
|||
# Plot |
|||
plt.plot(range(pred.shape[0]),pred_loss) |
|||
plt.ylabel('Loss') |
|||
plt.xlabel('Coarse mesh id') |
|||
plt.title("Linear graph") |
|||
plt.savefig(os.path.join(opt.results_dir, 'test_loss.png')) |
|||
plt.show() |
|||
|
|||
loss_metrix = np.asarray(pred_loss) |
|||
loss_metrix = loss_metrix.reshape(int(opt.nely/opt.ms_ratio), int(opt.nelx/opt.ms_ratio)) |
|||
plt.matshow(loss_metrix) |
|||
plt.title("Show loss value in grid") |
|||
plt.savefig(os.path.join(opt.results_dir, 'test_loss_in_grid.png')) |
|||
plt.show() |
@ -1,261 +0,0 @@ |
|||
from __future__ import division |
|||
import numpy as np |
|||
from scipy.sparse import coo_matrix |
|||
from scipy.sparse.linalg import spsolve |
|||
from matplotlib import colors |
|||
import matplotlib.pyplot as plt |
|||
|
|||
|
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
from utils.data_standardizer import standardization |
|||
from utils.data_loader import data_loader |
|||
|
|||
|
|||
def top_EMsFEA(nelx,nely,volfrac,penal,rmin,ft,mod_idx,m): |
|||
print("Minimum compliance problem with OC") |
|||
print("ndes: " + str(nelx) + " x " + str(nely)) |
|||
print("volfrac: " + str(volfrac) + ", rmin: " + str(rmin) + ", penal: " + str(penal)) |
|||
print("Filter method: " + ["Sensitivity based","Density based"][ft]) |
|||
# Max and min stiffness |
|||
Emin=1e-9 |
|||
Emax=1.0 |
|||
c_nelx=int(nelx/m) |
|||
c_nely=int(nely/m) |
|||
# dofs: |
|||
ndof = 2*(nelx+1)*(nely+1) |
|||
coarse_ndof = 2*(c_nelx+1)*(c_nely+1) |
|||
# Allocate design variables (as array), initialize and allocate sens. |
|||
x=volfrac * np.ones(nely*nelx,dtype=float) |
|||
xold=x.copy() |
|||
xPhys=x.copy() |
|||
g=0 # must be initialized to use the NGuyen/Paulino OC approach |
|||
dc=np.zeros((nely,nelx), dtype=float) |
|||
# FE: Build the index vectors for the for coo matrix format. |
|||
KE=lk() |
|||
edofMat=np.zeros((nelx*nely,8),dtype=int) |
|||
for elx in range(nelx): |
|||
for ely in range(nely): |
|||
el = ely+elx*nely |
|||
n1=(nely+1)*elx+ely |
|||
n2=(nely+1)*(elx+1)+ely |
|||
edofMat[el,:]=np.array([2*n1+2, 2*n1+3, 2*n2+2, 2*n2+3,2*n2, 2*n2+1, 2*n1, 2*n1+1]) |
|||
# Construct the index pointers for the coo format |
|||
iK = np.kron(edofMat,np.ones((8,1))).flatten() |
|||
jK = np.kron(edofMat,np.ones((1,8))).flatten() |
|||
|
|||
|
|||
coarse_edofMat=np.zeros((c_nelx*c_nely,8),dtype=int) |
|||
for elx in range(c_nelx): |
|||
for ely in range(c_nely): |
|||
el = ely+elx*c_nely |
|||
n1=(c_nely+1)*elx+ely |
|||
n2=(c_nely+1)*(elx+1)+ely |
|||
coarse_edofMat[el,:]=np.array([2*n1+2, 2*n1+3, 2*n2+2, 2*n2+3,2*n2, 2*n2+1, 2*n1, 2*n1+1]) |
|||
# Construct the index pointers for the coo format |
|||
coarse_iK = np.kron(coarse_edofMat,np.ones((8,1))).flatten() |
|||
coarse_jK = np.kron(coarse_edofMat,np.ones((1,8))).flatten() |
|||
|
|||
|
|||
|
|||
# Filter: Build (and assemble) the index+data vectors for the coo matrix format |
|||
nfilter=int(nelx*nely*((2*(np.ceil(rmin)-1)+1)**2)) |
|||
iH = np.zeros(nfilter) |
|||
jH = np.zeros(nfilter) |
|||
sH = np.zeros(nfilter) |
|||
cc=0 |
|||
for i in range(nelx): |
|||
for j in range(nely): |
|||
row=i*nely+j |
|||
kk1=int(np.maximum(i-(np.ceil(rmin)-1),0)) |
|||
kk2=int(np.minimum(i+np.ceil(rmin),nelx)) |
|||
ll1=int(np.maximum(j-(np.ceil(rmin)-1),0)) |
|||
ll2=int(np.minimum(j+np.ceil(rmin),nely)) |
|||
for k in range(kk1,kk2): |
|||
for l in range(ll1,ll2): |
|||
col=k*nely+l |
|||
fac=rmin-np.sqrt(((i-k)*(i-k)+(j-l)*(j-l))) |
|||
iH[cc]=row |
|||
jH[cc]=col |
|||
sH[cc]=np.maximum(0.0,fac) |
|||
cc=cc+1 |
|||
# Finalize assembly and convert to csc format |
|||
H=coo_matrix((sH,(iH,jH)),shape=(nelx*nely,nelx*nely)).tocsc() |
|||
Hs=H.sum(1) |
|||
# BC's and support |
|||
# dofs=np.arange(2*(nelx+1)*(nely+1)) |
|||
# fixed=np.union1d(dofs[0:2*(nely+1):2],np.array([2*(nelx+1)*(nely+1)-1])) |
|||
# free=np.setdiff1d(dofs,fixed) |
|||
|
|||
coarse_dofs=np.arange(2*(c_nelx+1)*(c_nely+1)) |
|||
coarse_fixed=np.union1d(coarse_dofs[0:2*(c_nely+1):2],np.array([2*(c_nelx+1)*(c_nely+1)-1])) |
|||
coarse_free=np.setdiff1d(coarse_dofs,coarse_fixed) |
|||
|
|||
# Solution and RHS vectors |
|||
# f=np.zeros((ndof,1)) |
|||
# u=np.zeros((ndof,1)) |
|||
|
|||
c_f=np.zeros((coarse_ndof,1)) |
|||
c_u=np.zeros((coarse_ndof,1)) |
|||
# Set load |
|||
# f[1,0]=-1 |
|||
|
|||
c_f[1,0]=-1 |
|||
# Initialize plot and plot the initial design |
|||
plt.ion() # Ensure that redrawing is possible |
|||
fig,ax = plt.subplots() |
|||
im = ax.imshow(-xPhys.reshape((nelx,nely)).T, cmap='gray',\ |
|||
interpolation='none',norm=colors.Normalize(vmin=-1,vmax=0)) |
|||
fig.show() |
|||
# Set loop counter and gradient vectors |
|||
loop=0 |
|||
change=1 |
|||
dv = np.ones(nely*nelx) |
|||
dc = np.ones(nely*nelx) |
|||
ce = np.ones(nely*nelx) |
|||
while change>0.01 and loop<2000: |
|||
loop=loop+1 |
|||
# Setup and solve FE problem |
|||
coarse_xPhys=xPhys[12::25] |
|||
sK=((KE.flatten()[np.newaxis]).T*(Emin+(coarse_xPhys)**penal*(Emax-Emin))).flatten(order='F') |
|||
K = coo_matrix((sK,(coarse_iK,coarse_jK)),shape=(coarse_ndof,coarse_ndof)).tocsc() |
|||
# Remove constrained dofs from matrix |
|||
K = K[coarse_free,:][:,coarse_free] |
|||
# Solve coarse situation |
|||
c_u[coarse_free,0]=spsolve(K,c_f[coarse_free,0]) |
|||
# Predict fine situation |
|||
u=pred_net(c_u,xPhys,c_nelx,c_nely,m,'checkpoints/ANN_mod1/ANN_mod1_opt.pt') |
|||
|
|||
# print(f.shape, f) |
|||
# print(K.shape, K) |
|||
# print(f[free,0]) |
|||
# print(u.shape, u) |
|||
|
|||
# Objective and sensitivity |
|||
ce[:] = (np.dot(u[edofMat].reshape(nelx*nely,8),KE) * u[edofMat].reshape(nelx*nely,8) ).sum(1) |
|||
obj=( (Emin+xPhys**penal*(Emax-Emin))*ce ).sum() |
|||
dc[:]=(-penal*xPhys**(penal-1)*(Emax-Emin))*ce |
|||
dv[:] = np.ones(nely*nelx) |
|||
# Sensitivity filtering: |
|||
if ft==0: |
|||
dc[:] = np.asarray((H*(x*dc))[np.newaxis].T/Hs)[:,0] / np.maximum(0.001,x) |
|||
elif ft==1: |
|||
dc[:] = np.asarray(H*(dc[np.newaxis].T/Hs))[:,0] |
|||
dv[:] = np.asarray(H*(dv[np.newaxis].T/Hs))[:,0] |
|||
# Optimality criteria |
|||
xold[:]=x |
|||
(x[:],g)=oc(nelx,nely,x,volfrac,dc,dv,g) |
|||
# Filter design variables |
|||
if ft==0: xPhys[:]=x |
|||
elif ft==1: xPhys[:]=np.asarray(H*x[np.newaxis].T/Hs)[:,0] |
|||
# Compute the change by the inf. norm |
|||
change=np.linalg.norm(x.reshape(nelx*nely,1)-xold.reshape(nelx*nely,1),np.inf) |
|||
# Plot to screen |
|||
im.set_array(-xPhys.reshape((nelx,nely)).T) |
|||
fig.canvas.draw() |
|||
# Write iteration history to screen (req. Python 2.6 or newer) |
|||
print("it.: {0} , obj.: {1:.3f} Vol.: {2:.3f}, ch.: {3:.3f}".format(\ |
|||
loop,obj,(g+volfrac*nelx*nely)/(nelx*nely),change)) |
|||
|
|||
|
|||
np.save('results/top88_' + mod_idx + '_xPhys_' + str(nelx) + '_' + str(nely) + '.npy', xPhys.reshape((nelx,nely)).T) |
|||
np.save('results/top88_' + mod_idx + '_u_' + str(nelx) + '_' + str(nely) + '.npy', u) |
|||
plt.savefig('results/top88_' + mod_idx + '_img_' + str(nelx) + '_' + str(nely) + '.jpg') |
|||
|
|||
# plt.show() |
|||
|
|||
print(u.reshape(nelx+1,nely+1,2)) |
|||
|
|||
# Make sure the plot stays and that the shell remains |
|||
np.save('results/top88_' + mod_idx + '_xPhys_' + str(nelx) + '_' + str(nely) + '.npy', xPhys.reshape((nelx,nely)).T) |
|||
np.save('results/top88_' + mod_idx + '_u_' + str(nelx) + '_' + str(nely) + '.npy', u) |
|||
plt.savefig('results/top88_' + mod_idx + '_img_' + str(nelx) + '_' + str(nely) + '.jpg') |
|||
plt.show() |
|||
print("Press any key...") |
|||
#element stiffness matrix |
|||
def lk(): |
|||
E=1 |
|||
nu=0.3 |
|||
k=np.array([1/2-nu/6,1/8+nu/8,-1/4-nu/12,-1/8+3*nu/8,-1/4+nu/12,-1/8-nu/8,nu/6,1/8-3*nu/8]) |
|||
KE = E/(1-nu**2)*np.array([ [k[0], k[1], k[2], k[3], k[4], k[5], k[6], k[7]], |
|||
[k[1], k[0], k[7], k[6], k[5], k[4], k[3], k[2]], |
|||
[k[2], k[7], k[0], k[5], k[6], k[3], k[4], k[1]], |
|||
[k[3], k[6], k[5], k[0], k[7], k[2], k[1], k[4]], |
|||
[k[4], k[5], k[6], k[7], k[0], k[1], k[2], k[3]], |
|||
[k[5], k[4], k[3], k[2], k[1], k[0], k[7], k[6]], |
|||
[k[6], k[3], k[4], k[1], k[2], k[7], k[0], k[5]], |
|||
[k[7], k[2], k[1], k[4], k[3], k[6], k[5], k[0]] ]); |
|||
return (KE) |
|||
# Optimality criterion |
|||
def oc(nelx,nely,x,volfrac,dc,dv,g): |
|||
l1=0 |
|||
l2=1e9 |
|||
move=0.2 |
|||
# reshape to perform vector operations |
|||
xnew=np.zeros(nelx*nely) |
|||
while (l2-l1)/(l1+l2)>1e-3: |
|||
lmid=0.5*(l2+l1) |
|||
xnew[:]= np.maximum(0.0,np.maximum(x-move,np.minimum(1.0,np.minimum(x+move,x*np.sqrt(-dc/dv/lmid))))) |
|||
gt=g+np.sum((dv*(xnew-x))) |
|||
if gt>0 : |
|||
l1=lmid |
|||
else: |
|||
l2=lmid |
|||
return (xnew,gt) |
|||
|
|||
|
|||
def pred_net(coarse_u,fine_x,coarse_nelx,coarse_nely,m, model_load_path, standard = False, device = 0): |
|||
coarse_density=np.zeros(shape=(coarse_nely*coarse_nelx,m*m)) |
|||
fine_x=fine_x.reshape(coarse_nely*m,coarse_nelx*m) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
coarse_density[elx + ely * m] = fine_x[ely * m : (ely + 1) * m, elx * m : (elx + 1) * m].flatten() |
|||
print(coarse_density.shape) |
|||
|
|||
|
|||
global_displace = coarse_u.reshape(coarse_nelx+1,coarse_nely+1,2) |
|||
global_displace = np.dstack((global_displace[:,:,0].T, global_displace[:,:,1].T)) |
|||
coarse_displace=np.zeros(shape=(coarse_nely*coarse_nelx,4,2)) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
coarse_displace[elx + ely][0] = global_displace[ely, elx, :] |
|||
coarse_displace[elx + ely][1] = global_displace[ely, (elx+1), :] |
|||
coarse_displace[elx + ely][2] = global_displace[(ely+1), elx, :] |
|||
coarse_displace[elx + ely][3] = global_displace[(ely+1), (elx+1), :] |
|||
print(coarse_displace.shape) |
|||
|
|||
X = np.hstack((coarse_density[:,:] , coarse_displace[:,:,0] , coarse_displace[:,:,1])) |
|||
model = torch.load(model_load_path) |
|||
if standard: |
|||
X = standardization(X) |
|||
device = f'cuda:{device}' if torch.cuda.is_available() else 'cpu' |
|||
X = torch.from_numpy(X).type(torch.float32).to(device) |
|||
pred=model(X).cpu().detach().numpy() |
|||
|
|||
# print(pred) |
|||
u_reconstructed = np.zeros(shape=(coarse_nely*m+1, coarse_nelx*m+1, 2)) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
u_reconstructed[ely*m : (ely+1)*m+1, elx*m : (elx+1)*m+1, :] = pred[elx + ely * m].reshape((m+1, m+1, 2)) |
|||
# u_reconstructed = u_reconstructed.reshape(coarse_nely*m+1, coarse_nelx*m+1,2) |
|||
u_reconstructed = np.dstack((u_reconstructed[:,:,0].T, u_reconstructed[:,:,1].T)) |
|||
u_reconstructed=u_reconstructed.flatten() |
|||
|
|||
return u_reconstructed |
|||
|
|||
|
|||
|
|||
|
|||
# The real main driver |
|||
if __name__ == "__main__": |
|||
mod_idx='test1' |
|||
m=5 |
|||
nelx=180 |
|||
nely=60 |
|||
volfrac=0.4 |
|||
rmin=5.4 |
|||
penal=3.0 |
|||
ft=1 # ft==0 -> sens, ft==1 -> dens |
|||
top_EMsFEA(nelx,nely,volfrac,penal,rmin,ft,mod_idx,m) |
@ -1,76 +0,0 @@ |
|||
import time |
|||
import os |
|||
import numpy as np |
|||
import matplotlib.pyplot as plt |
|||
|
|||
import torch |
|||
import torch.nn as nn |
|||
import torch.nn.functional as F |
|||
|
|||
from utils.data_standardizer import standardization |
|||
from utils.data_loader import data_loader |
|||
from options.train_options import TrainOptions |
|||
|
|||
from models.ANN import ANN_Model |
|||
|
|||
def train(X, Y, opt): |
|||
if opt.is_standard: |
|||
X = standardization(X) |
|||
Y = standardization(Y) |
|||
|
|||
X_train=torch.from_numpy(X).type(torch.float32).to(opt.device) |
|||
Y_train=torch.from_numpy(Y).type(torch.float32).to(opt.device) |
|||
|
|||
# Load net model |
|||
torch.manual_seed(20) |
|||
model_name=opt.model+'_Model' |
|||
model = eval(model_name)() # ANN_Model() as default |
|||
model.parameters |
|||
model=model.to(opt.device) |
|||
print(model) |
|||
|
|||
# Set loss function |
|||
loss_function = nn.MSELoss() |
|||
|
|||
# Set adam optimizer |
|||
optimizer=torch.optim.Adam(model.parameters(),lr=opt.lr) # ANN 学习率最好0.001 左右(无归一化) |
|||
|
|||
# Train |
|||
start_time=time.time() |
|||
losses=[] |
|||
for i in range(opt.epochs): |
|||
pred = model.forward(X_train) |
|||
loss=loss_function(pred,Y_train) |
|||
# loss.requires_grad_(True) |
|||
losses.append(loss.cpu().detach().numpy()) |
|||
if i%(opt.epochs/10)==1: |
|||
print("Epoch number: {} and the loss : {}".format(i,loss.item())) |
|||
optimizer.zero_grad() |
|||
loss.backward() |
|||
optimizer.step() |
|||
print(time.time()-start_time) |
|||
|
|||
# save trained model, mkdir opt has done in options/base_options.py |
|||
save_path=os.path.join(opt.checkpoints_dir, opt.model+'_'+opt.mod, opt.model+'_'+opt.mod+'_opt.pt') |
|||
torch.save(model, save_path) |
|||
|
|||
return losses |
|||
|
|||
|
|||
if __name__=='__main__': |
|||
# Load parmetaers |
|||
opt = TrainOptions().parse() |
|||
|
|||
# Load datasets, mod1 as default |
|||
global_density, global_displace, coarse_density, coarse_displace, fine_displace = data_loader(opt) |
|||
X = np.hstack((coarse_density[:,:] , coarse_displace[:,:,0] , coarse_displace[:,:,1])) |
|||
Y = fine_displace[:,:] |
|||
|
|||
# Train |
|||
losses = train(X, Y, opt) |
|||
|
|||
# plot loss |
|||
plt.plot(range(opt.epochs),losses) |
|||
plt.ylabel('Loss') |
|||
plt.xlabel('Epoch') |
|||
plt.show() |
@ -1,54 +0,0 @@ |
|||
import numpy as np |
|||
import os |
|||
|
|||
def data_loader(opt): |
|||
# Load datasets |
|||
|
|||
# './datasets/train/180_60/u_OR_xPhys/mod1.npy' as default |
|||
density_load_path = os.path.join(opt.dataroot, opt.phase, str(opt.nelx)+'_'+str(opt.nely), 'xPhys', opt.mod+'.npy') |
|||
displace_load_path = os.path.join(opt.dataroot, opt.phase, str(opt.nelx)+'_'+str(opt.nely), 'u', opt.mod+'.npy') |
|||
|
|||
global_density = np.load(density_load_path) # (nely , nelx) |
|||
global_displace = np.load(displace_load_path) # ( (nely+1)*(nelx+1)*2 , 1 ) |
|||
|
|||
global_displace = global_displace.reshape(opt.nelx+1, opt.nely+1, 2) |
|||
global_displace = np.dstack((global_displace[:,:,0].T, global_displace[:,:,1].T)) # -> ( (nelx+1), (nelx+1), 2 ) |
|||
|
|||
m=opt.ms_ratio |
|||
N=(m+1)**2 |
|||
global_nely=global_density.shape[0] |
|||
global_nelx=global_density.shape[1] |
|||
coarse_nely = int(global_nely/m) |
|||
coarse_nelx = int(global_nelx/m) |
|||
|
|||
# Generate coarse mesh density |
|||
coarse_density=np.zeros(shape=(coarse_nely*coarse_nelx,m*m)) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
coarse_density[elx + ely * m] = global_density[ely * m : (ely + 1) * m, elx * m : (elx + 1) * m].flatten() |
|||
print(coarse_density.shape) |
|||
|
|||
# Generate coarse mesh displacement |
|||
coarse_displace=np.zeros(shape=(coarse_nely*coarse_nelx,4,2)) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
coarse_displace[elx + ely * m][0] = global_displace[ely * m, elx * m, :] |
|||
coarse_displace[elx + ely * m][1] = global_displace[ely * m, (elx+1) * m, :] |
|||
coarse_displace[elx + ely * m][2] = global_displace[(ely+1) * m, elx * m, :] |
|||
coarse_displace[elx + ely * m][3] = global_displace[(ely+1) * m, (elx+1) * m, :] |
|||
print(coarse_displace.shape) |
|||
|
|||
# Generate fine mesh displacement |
|||
fine_displace=np.zeros(shape=(coarse_nely*coarse_nelx, ((m+1)**2) * 2)) |
|||
for ely in range(coarse_nely): |
|||
for elx in range(coarse_nelx): |
|||
fine_displace[elx + ely * m] = global_displace[ely*m : (ely+1)*m+1, elx*m : (elx+1)*m+1, :].flatten() |
|||
print(fine_displace.shape) |
|||
|
|||
|
|||
return global_density, global_displace, coarse_density, coarse_displace, fine_displace |
|||
|
|||
if __name__=='__main__': |
|||
from options.train_options import TrainOptions |
|||
opt = TrainOptions().parse() |
|||
data_loader(opt) |
@ -1,7 +0,0 @@ |
|||
import numpy as np |
|||
|
|||
def standardization(data): |
|||
mu = np.mean(data, axis=0) |
|||
sigma = np.std(data, axis=0) |
|||
return (data - mu) / sigma |
|||
|
@ -1,185 +0,0 @@ |
|||
# A 165 LINE TOPOLOGY OPTIMIZATION CODE BY NIELS AAGE AND VILLADS EGEDE JOHANSEN, JANUARY 2013 |
|||
from __future__ import division |
|||
import numpy as np |
|||
from scipy.sparse import coo_matrix |
|||
from scipy.sparse.linalg import spsolve |
|||
from matplotlib import colors |
|||
import matplotlib.pyplot as plt |
|||
# MAIN DRIVER |
|||
def top88(nelx,nely,volfrac,penal,rmin,ft,mod_idx): |
|||
print("Minimum compliance problem with OC") |
|||
print("ndes: " + str(nelx) + " x " + str(nely)) |
|||
print("volfrac: " + str(volfrac) + ", rmin: " + str(rmin) + ", penal: " + str(penal)) |
|||
print("Filter method: " + ["Sensitivity based","Density based"][ft]) |
|||
# Max and min stiffness |
|||
Emin=1e-9 |
|||
Emax=1.0 |
|||
# dofs: |
|||
ndof = 2*(nelx+1)*(nely+1) |
|||
# Allocate design variables (as array), initialize and allocate sens. |
|||
x=volfrac * np.ones(nely*nelx,dtype=float) |
|||
xold=x.copy() |
|||
xPhys=x.copy() |
|||
g=0 # must be initialized to use the NGuyen/Paulino OC approach |
|||
dc=np.zeros((nely,nelx), dtype=float) |
|||
# FE: Build the index vectors for the for coo matrix format. |
|||
KE=lk() |
|||
edofMat=np.zeros((nelx*nely,8),dtype=int) |
|||
for elx in range(nelx): |
|||
for ely in range(nely): |
|||
el = ely+elx*nely |
|||
n1=(nely+1)*elx+ely |
|||
n2=(nely+1)*(elx+1)+ely |
|||
edofMat[el,:]=np.array([2*n1+2, 2*n1+3, 2*n2+2, 2*n2+3,2*n2, 2*n2+1, 2*n1, 2*n1+1]) |
|||
# Construct the index pointers for the coo format |
|||
iK = np.kron(edofMat,np.ones((8,1))).flatten() |
|||
jK = np.kron(edofMat,np.ones((1,8))).flatten() |
|||
# Filter: Build (and assemble) the index+data vectors for the coo matrix format |
|||
nfilter=int(nelx*nely*((2*(np.ceil(rmin)-1)+1)**2)) |
|||
iH = np.zeros(nfilter) |
|||
jH = np.zeros(nfilter) |
|||
sH = np.zeros(nfilter) |
|||
cc=0 |
|||
for i in range(nelx): |
|||
for j in range(nely): |
|||
row=i*nely+j |
|||
kk1=int(np.maximum(i-(np.ceil(rmin)-1),0)) |
|||
kk2=int(np.minimum(i+np.ceil(rmin),nelx)) |
|||
ll1=int(np.maximum(j-(np.ceil(rmin)-1),0)) |
|||
ll2=int(np.minimum(j+np.ceil(rmin),nely)) |
|||
for k in range(kk1,kk2): |
|||
for l in range(ll1,ll2): |
|||
col=k*nely+l |
|||
fac=rmin-np.sqrt(((i-k)*(i-k)+(j-l)*(j-l))) |
|||
iH[cc]=row |
|||
jH[cc]=col |
|||
sH[cc]=np.maximum(0.0,fac) |
|||
cc=cc+1 |
|||
# Finalize assembly and convert to csc format |
|||
H=coo_matrix((sH,(iH,jH)),shape=(nelx*nely,nelx*nely)).tocsc() |
|||
Hs=H.sum(1) |
|||
# BC's and support |
|||
dofs=np.arange(2*(nelx+1)*(nely+1)) |
|||
fixed=np.union1d(dofs[0:2*(nely+1):2],np.array([2*(nelx+1)*(nely+1)-1])) |
|||
free=np.setdiff1d(dofs,fixed) |
|||
# Solution and RHS vectors |
|||
f=np.zeros((ndof,1)) |
|||
u=np.zeros((ndof,1)) |
|||
# Set load |
|||
f[1,0]=-1 |
|||
# Initialize plot and plot the initial design |
|||
plt.ion() # Ensure that redrawing is possible |
|||
fig,ax = plt.subplots() |
|||
im = ax.imshow(-xPhys.reshape((nelx,nely)).T, cmap='gray',\ |
|||
interpolation='none',norm=colors.Normalize(vmin=-1,vmax=0)) |
|||
fig.show() |
|||
# Set loop counter and gradient vectors |
|||
loop=0 |
|||
change=1 |
|||
dv = np.ones(nely*nelx) |
|||
dc = np.ones(nely*nelx) |
|||
ce = np.ones(nely*nelx) |
|||
while change>0.01 and loop<2000: |
|||
loop=loop+1 |
|||
# Setup and solve FE problem |
|||
sK=((KE.flatten()[np.newaxis]).T*(Emin+(xPhys)**penal*(Emax-Emin))).flatten(order='F') |
|||
K = coo_matrix((sK,(iK,jK)),shape=(ndof,ndof)).tocsc() |
|||
# Remove constrained dofs from matrix |
|||
K = K[free,:][:,free] |
|||
# Solve system |
|||
u[free,0]=spsolve(K,f[free,0]) |
|||
|
|||
# print(f.shape, f) |
|||
# print(K.shape, K) |
|||
# print(f[free,0]) |
|||
# print(u.shape, u) |
|||
|
|||
# Objective and sensitivity |
|||
ce[:] = (np.dot(u[edofMat].reshape(nelx*nely,8),KE) * u[edofMat].reshape(nelx*nely,8) ).sum(1) |
|||
obj=( (Emin+xPhys**penal*(Emax-Emin))*ce ).sum() |
|||
dc[:]=(-penal*xPhys**(penal-1)*(Emax-Emin))*ce |
|||
dv[:] = np.ones(nely*nelx) |
|||
# Sensitivity filtering: |
|||
if ft==0: |
|||
dc[:] = np.asarray((H*(x*dc))[np.newaxis].T/Hs)[:,0] / np.maximum(0.001,x) |
|||
elif ft==1: |
|||
dc[:] = np.asarray(H*(dc[np.newaxis].T/Hs))[:,0] |
|||
dv[:] = np.asarray(H*(dv[np.newaxis].T/Hs))[:,0] |
|||
# Optimality criteria |
|||
xold[:]=x |
|||
(x[:],g)=oc(nelx,nely,x,volfrac,dc,dv,g) |
|||
# Filter design variables |
|||
if ft==0: xPhys[:]=x |
|||
elif ft==1: xPhys[:]=np.asarray(H*x[np.newaxis].T/Hs)[:,0] |
|||
# Compute the change by the inf. norm |
|||
change=np.linalg.norm(x.reshape(nelx*nely,1)-xold.reshape(nelx*nely,1),np.inf) |
|||
# Plot to screen |
|||
im.set_array(-xPhys.reshape((nelx,nely)).T) |
|||
fig.canvas.draw() |
|||
# Write iteration history to screen (req. Python 2.6 or newer) |
|||
print("it.: {0} , obj.: {1:.3f} Vol.: {2:.3f}, ch.: {3:.3f}".format(\ |
|||
loop,obj,(g+volfrac*nelx*nely)/(nelx*nely),change)) |
|||
|
|||
|
|||
np.save('results/top88_' + mod_idx + '_xPhys_' + str(nelx) + '_' + str(nely) + '.npy', xPhys.reshape((nelx,nely)).T) |
|||
np.save('results/top88_' + mod_idx + '_u_' + str(nelx) + '_' + str(nely) + '.npy', u) |
|||
plt.savefig('results/top88_' + mod_idx + '_img_' + str(nelx) + '_' + str(nely) + '.jpg') |
|||
|
|||
# plt.show() |
|||
|
|||
print(u.reshape(nelx+1,nely+1,2)) |
|||
|
|||
# Make sure the plot stays and that the shell remains |
|||
np.save('results/top88_' + mod_idx + '_xPhys_' + str(nelx) + '_' + str(nely) + '.npy', xPhys.reshape((nelx,nely)).T) |
|||
np.save('results/top88_' + mod_idx + '_u_' + str(nelx) + '_' + str(nely) + '.npy', u) |
|||
plt.savefig('results/top88_' + mod_idx + '_img_' + str(nelx) + '_' + str(nely) + '.jpg') |
|||
plt.show() |
|||
print("Press any key...") |
|||
#element stiffness matrix |
|||
def lk(): |
|||
E=1 |
|||
nu=0.3 |
|||
k=np.array([1/2-nu/6,1/8+nu/8,-1/4-nu/12,-1/8+3*nu/8,-1/4+nu/12,-1/8-nu/8,nu/6,1/8-3*nu/8]) |
|||
KE = E/(1-nu**2)*np.array([ [k[0], k[1], k[2], k[3], k[4], k[5], k[6], k[7]], |
|||
[k[1], k[0], k[7], k[6], k[5], k[4], k[3], k[2]], |
|||
[k[2], k[7], k[0], k[5], k[6], k[3], k[4], k[1]], |
|||
[k[3], k[6], k[5], k[0], k[7], k[2], k[1], k[4]], |
|||
[k[4], k[5], k[6], k[7], k[0], k[1], k[2], k[3]], |
|||
[k[5], k[4], k[3], k[2], k[1], k[0], k[7], k[6]], |
|||
[k[6], k[3], k[4], k[1], k[2], k[7], k[0], k[5]], |
|||
[k[7], k[2], k[1], k[4], k[3], k[6], k[5], k[0]] ]); |
|||
return (KE) |
|||
# Optimality criterion |
|||
def oc(nelx,nely,x,volfrac,dc,dv,g): |
|||
l1=0 |
|||
l2=1e9 |
|||
move=0.2 |
|||
# reshape to perform vector operations |
|||
xnew=np.zeros(nelx*nely) |
|||
while (l2-l1)/(l1+l2)>1e-3: |
|||
lmid=0.5*(l2+l1) |
|||
xnew[:]= np.maximum(0.0,np.maximum(x-move,np.minimum(1.0,np.minimum(x+move,x*np.sqrt(-dc/dv/lmid))))) |
|||
gt=g+np.sum((dv*(xnew-x))) |
|||
if gt>0 : |
|||
l1=lmid |
|||
else: |
|||
l2=lmid |
|||
return (xnew,gt) |
|||
# The real main driver |
|||
if __name__ == "__main__": |
|||
# Default input parameters |
|||
mod_idx='mod4' |
|||
nelx=30 |
|||
nely=10 |
|||
volfrac=0.4 |
|||
rmin=5.4 |
|||
penal=3.0 |
|||
ft=1 # ft==0 -> sens, ft==1 -> dens |
|||
import sys |
|||
if len(sys.argv)>1: nelx =int(sys.argv[1]) |
|||
if len(sys.argv)>2: nely =int(sys.argv[2]) |
|||
if len(sys.argv)>3: volfrac=float(sys.argv[3]) |
|||
if len(sys.argv)>4: rmin =float(sys.argv[4]) |
|||
if len(sys.argv)>5: penal =float(sys.argv[5]) |
|||
if len(sys.argv)>6: ft =int(sys.argv[6]) |
|||
top88(nelx,nely,volfrac,penal,rmin,ft,mod_idx) |
@ -1,23 +0,0 @@ |
|||
import os |
|||
|
|||
def mkdirs(paths): |
|||
"""create empty directories if they don't exist |
|||
|
|||
Parameters: |
|||
paths (str list) -- a list of directory paths |
|||
""" |
|||
if isinstance(paths, list) and not isinstance(paths, str): |
|||
for path in paths: |
|||
mkdir(path) |
|||
else: |
|||
mkdir(paths) |
|||
|
|||
|
|||
def mkdir(path): |
|||
"""create a single empty directory if it didn't exist |
|||
|
|||
Parameters: |
|||
path (str) -- a single directory path |
|||
""" |
|||
if not os.path.exists(path): |
|||
os.makedirs(path) |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue