├── .gitignore ├── LICENSE ├── README.md ├── tf1 ├── tensorflow_DEM │ ├── CubeWithHole.py │ ├── Elasticity │ │ ├── CubeWithHole.py │ │ ├── HollowSphere.py │ │ ├── PlateWithHole.py │ │ ├── ThickCylinder.py │ │ ├── TimoshenkoBeam.py │ │ ├── cube_with_hole.mat │ │ ├── readme.md │ │ └── utils │ │ │ ├── Geom.py │ │ │ ├── PINN.py │ │ │ └── gridPlot.py │ ├── HollowSphere.py │ ├── Phase Field │ │ ├── TensilePlate.py │ │ └── utils │ │ │ ├── BezExtr.py │ │ │ ├── PINN_2ndPF.py │ │ │ └── gridPlot.py │ ├── PlateWithHole.py │ ├── ThickCylinder.py │ ├── TimoshenkoBeam.py │ ├── cube_with_hole.mat │ ├── gaussPtsBoundCubeWithHole.mat │ ├── gaussPtsBoundHollowSphere.mat │ ├── gaussPtsCubeWithHole.mat │ ├── gaussPtsHollowSphere.mat │ ├── readme.md │ └── utils │ │ ├── Geom.py │ │ └── PINN.py └── tensorflow_collocation │ ├── Adaptive (CMC_paper) │ ├── AcousticDuct_adaptive.py │ ├── AcousticDuct_inverse.py │ ├── CrackedDomainHarmonic_adaptive.py │ ├── Poisson_Annulus_adaptive.py │ ├── Poisson_SinCos_adaptive.py │ ├── README.md │ └── utils │ │ ├── Geometry.py │ │ └── PoissonEqAdapt.py │ ├── Elastodynamics │ ├── Wave1D.py │ └── utils │ │ ├── PINN_wave.py │ │ └── gridPlot.py │ ├── Helmholtz │ ├── AcousticDuct.py │ └── AcousticDuct_inverse.py │ ├── Poisson │ ├── Poisson1D_DD.py │ ├── Poisson1D_DD_tb_FP64.py │ ├── Poisson2D_Crack.py │ ├── Poisson2D_Dirichlet.py │ ├── Poisson2D_Neumann.py │ └── Poisson2D_Neumann_SinCos.py │ └── README.md └── tf2 ├── Helmholtz2D_Acoustic_Duct.py ├── Interpolate.py ├── PlateWithHole.py ├── PlateWithHole_DEM.py ├── Poisson.py ├── Poisson2D_Dirichlet.py ├── Poisson2D_Dirichlet_Circle.py ├── Poisson2D_Dirichlet_DEM.py ├── Poisson2D_Dirichlet_SinCos.py ├── Poisson_DEM.py ├── Poisson_DEM_adaptive.py ├── Poisson_Neumann.py ├── Poisson_Neumann_DEM.py ├── Poisson_mixed.py ├── README.md ├── ThickCylinder.py ├── ThickCylinder_DEM.py ├── TimonshenkoBeam.py ├── TimonshenkoBeam_DEM.py ├── Wave1D.py └── utils ├── Geom.py ├── Geom_examples.py ├── Plotting.py ├── Solvers.py ├── scipy_loss.py └── tfp_loss.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | .DS_Store 3 | *.vtk 4 | *.vtu 5 | *.asv 6 | *.m~ 7 | *.fig 8 | *.vts 9 | 10 | # Ignore file swap 11 | *.swp 12 | # Ignore folder idea of pycharm idea 13 | .idea/ 14 | # Ignore file python compiled code 15 | *.pyc 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Institute of Structural Mechanics 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepEnergyMethods 2 | Repository for Deep Learning Methods for solving Partial Differential Equations 3 | 4 | Companion paper: https://arxiv.org/abs/1908.10407 or https://doi.org/10.1016/j.cma.2019.112790 5 | 6 | Folder tf1 contains the original Tensorflow 1 codes (works with Tensorflow versions up to 1.15). 7 | 8 | Folder tf2 contains some examples which are converted to run on Tensorflow 2 (tested with version 2.11). 9 | 10 | -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Elasticity/HollowSphere.py: -------------------------------------------------------------------------------- 1 | # Implements the an hollow sphere under pressure problem 2 | 3 | import tensorflow as tf 4 | import numpy as np 5 | import matplotlib as mpl 6 | mpl.rcParams['figure.dpi'] = 200 7 | import time 8 | import os 9 | from utils.gridPlot import energyError 10 | from utils.gridPlot import scatterPlot 11 | from utils.gridPlot import createFolder 12 | from utils.gridPlot import energyPlot 13 | from utils.gridPlot import plotConvergence 14 | from utils.gridPlot import cart2sph 15 | from utils.gridPlot import sph2cart 16 | tf.reset_default_graph() # To clear the defined variables and operations of the previous cell 17 | np.random.seed(1234) 18 | tf.set_random_seed(1234) 19 | 20 | from utils.Geom import Geometry3D 21 | from utils.PINN import Elasticity3D 22 | 23 | class HollowSphere(Geometry3D): 24 | ''' 25 | Class for definining a quarter-annulus domain centered at the orgin 26 | (the domain is in the first quadrant) 27 | Input: rad_int, rad_ext - internal and external radii of the annulus 28 | ''' 29 | def __init__(self, a, b): 30 | 31 | geomData = dict() 32 | # Set degrees 33 | geomData['degree_u'] = 2 34 | geomData['degree_v'] = 2 35 | geomData['degree_w'] = 1 36 | 37 | # Set control points 38 | geomData['ctrlpts_size_u'] = 3 39 | geomData['ctrlpts_size_v'] = 3 40 | geomData['ctrlpts_size_w'] = 2 41 | 42 | wgt = 1/np.sqrt(2) 43 | 44 | geomData['ctrlpts'] = [[a, 0, 0],[wgt*a, 0, wgt*a],[0, 0, a], 45 | [wgt*a, wgt*a, 0],[0.5*a, 0.5*a, 0.5*a],[0, 0, wgt*a], 46 | [0, a, 0],[0, wgt*a, wgt*a],[0, 0, a],[b, 0, 0],[wgt*b, 0, wgt*b], 47 | [0, 0, b],[wgt*b, wgt*b, 0],[0.5*b, 0.5*b, 0.5*b],[0, 0, wgt*b], 48 | [0, b, 0],[0, wgt*b, wgt*b],[0, 0, b]] 49 | 50 | geomData['weights'] = [1.0,wgt,1,wgt,1/2,wgt,1,wgt,1,1,wgt,1,wgt,1/2,wgt,1,wgt,1] 51 | 52 | # Set knot vectors 53 | geomData['knotvector_u'] = [0., 0., 0., 1., 1., 1.] 54 | geomData['knotvector_v'] = [0., 0., 0., 1., 1., 1.] 55 | geomData['knotvector_w'] = [0., 0., 1., 1.] 56 | 57 | super().__init__(geomData) 58 | 59 | class PINN_HS(Elasticity3D): 60 | ''' 61 | Class including (symmetry) boundary conditions for the hollow sphere problem 62 | ''' 63 | def net_uvw(self, x, y, z): 64 | 65 | X = tf.concat([x, y, z], 1) 66 | 67 | uvw = self.neural_net(X, self.weights, self.biases) 68 | 69 | u = x*uvw[:, 0:1] 70 | v = y*uvw[:, 1:2] 71 | w = z*uvw[:, 2:3] 72 | 73 | return u, v, w 74 | 75 | def getExactDisplacements(x, y, z, model): 76 | P = model['P'] 77 | b = model['b'] 78 | a = model['a'] 79 | E = model['E'] 80 | nu = model['nu'] 81 | 82 | azimuth, elevation, r = cart2sph(x, y, z) 83 | 84 | u_r = P*a**3*r/(E*(b**3-a**3))*((1-2*nu)+(1+nu)*b**3/(2*r**3)) 85 | u_exact, v_exact, w_exact = sph2cart(azimuth, elevation, u_r) 86 | 87 | return u_exact, v_exact, w_exact 88 | 89 | def getExactStresses(x, y, z, model): 90 | numPts = len(x) 91 | P = model['P'] 92 | b = model['b'] 93 | a = model['a'] 94 | 95 | sigma_xx = np.zeros_like(x) 96 | sigma_yy = np.zeros_like(x) 97 | sigma_zz = np.zeros_like(x) 98 | sigma_xy = np.zeros_like(x) 99 | sigma_yz = np.zeros_like(x) 100 | sigma_zx = np.zeros_like(x) 101 | 102 | for i in range(numPts): 103 | 104 | azimuth, elevation, r = cart2sph(x[i], y[i], z[i]) 105 | 106 | phi = azimuth 107 | theta = np.pi/2-elevation 108 | 109 | sigma_r = P*a**3*(b**3-r**3)/(r**3*(a**3-b**3)) 110 | sigma_th = P*a**3*(b**3+2*r**3)/(2*r**3*(b**3-a**3)) 111 | 112 | rot_mat = np.array( \ 113 | [[np.sin(theta)*np.cos(phi), np.cos(theta)*np.cos(phi), -np.sin(phi)], 114 | [np.sin(theta)*np.sin(phi), np.cos(theta)*np.sin(phi), np.cos(phi)], 115 | [np.cos(theta), -np.sin(theta), 0.]]) 116 | A = np.array( [[sigma_r, 0., 0.], [0., sigma_th, 0.], [0., 0., sigma_th]] ) 117 | stress_cart = rot_mat@A@rot_mat.T 118 | 119 | sigma_xx[i] = stress_cart[0,0] 120 | sigma_yy[i] = stress_cart[1,1] 121 | sigma_zz[i] = stress_cart[2,2] 122 | sigma_xy[i] = stress_cart[0,1] 123 | sigma_zx[i] = stress_cart[0,2] 124 | sigma_yz[i] = stress_cart[1,2] 125 | 126 | return sigma_xx, sigma_yy, sigma_zz, sigma_xy, sigma_yz, sigma_zx 127 | 128 | 129 | 130 | #Main program 131 | originalDir = os.getcwd() 132 | foldername = 'HollowSphere_results' 133 | createFolder('./'+ foldername + '/') 134 | os.chdir(os.path.join(originalDir, './'+ foldername + '/')) 135 | 136 | 137 | figHeight = 6 138 | figWidth = 6 139 | 140 | # Material parameters 141 | model_data = dict() 142 | model_data['E'] = 1e3 143 | model_data['nu'] = 0.3 144 | 145 | model = dict() 146 | model['E'] = model_data['E'] 147 | model['nu'] = model_data['nu'] 148 | model['a'] = 1.0 # Internal diameter 149 | model['b'] = 4.0 # External diameter 150 | model['P'] = 1.0 # Internal oressure 151 | 152 | # Domain bounds 153 | model['lb'] = np.array([0., 0., 0.]) #lower bound of the plate 154 | model['ub'] = np.array([model['b'], model['b'], model['b']]) # Upper bound of the plate 155 | 156 | NN_param = dict() 157 | NN_param['layers'] = [3, 50, 50, 50, 3] 158 | NN_param['data_type'] = tf.float32 159 | 160 | # Generating points inside the domain using GeometryIGA 161 | myDomain = HollowSphere(model['a'], model['b']) 162 | 163 | numElemU = 15 164 | numElemV = 15 165 | numElemW = 15 166 | numGauss = 2 167 | 168 | vertex = myDomain.genElemList(numElemU, numElemV, numElemW) 169 | xPhys, yPhys, zPhys, wgtsPhys = myDomain.getElemIntPts(vertex, numGauss) 170 | X_f = np.concatenate((xPhys,yPhys,zPhys,wgtsPhys),axis=1) 171 | 172 | numElemFace = [40, 40] 173 | numGaussFace = 2 174 | orientFace = 5 175 | xFace, yFace, zFace, xNorm, yNorm, zNorm, wgtsFace = myDomain.getQuadFacePts(numElemFace, 176 | numGaussFace, orientFace) 177 | X_bnd = np.concatenate((xFace, yFace, zFace, wgtsFace, xNorm, yNorm, zNorm), axis=1) 178 | 179 | model_pts = dict() 180 | model_pts['X_int'] = X_f 181 | model_pts['X_bnd'] = X_bnd 182 | 183 | modelNN = PINN_HS(model_data, model_pts, NN_param) 184 | filename = 'Training_scatter' 185 | scatterPlot(X_f,X_bnd,figHeight,figWidth,filename) 186 | 187 | start_time = time.time() 188 | num_train_its = 2000 189 | modelNN.train(num_train_its) 190 | elapsed = time.time() - start_time 191 | print('Training time: %.4f' % (elapsed)) 192 | 193 | nPred = 50 194 | withSides = [1, 1, 1, 1, 1, 1] 195 | xGrid, yGrid, zGrid = myDomain.getUnifIntPts(nPred, nPred, nPred, withSides) 196 | Grid = np.concatenate((xGrid, yGrid, zGrid), axis=1) 197 | u_pred, v_pred, w_pred, energy_pred, sigma_x_pred, sigma_y_pred, sigma_z_pred, \ 198 | sigma_xy_pred, sigma_yz_pred, sigma_zx_pred = modelNN.predict(Grid) 199 | 200 | # Computing exact displacements 201 | u_exact, v_exact, w_exact = getExactDisplacements(xGrid, yGrid, zGrid, model) 202 | 203 | errU = u_exact - u_pred 204 | errV = v_exact - v_pred 205 | errW = w_exact - w_pred 206 | err = errU**2 + errV**2 + errW**2 207 | err_norm = err.sum() 208 | ex = u_exact**2 + v_exact**2 + w_exact**2 209 | ex_norm = ex.sum() 210 | error_u = np.sqrt(err_norm/ex_norm) 211 | print("Relative L2 error: ", error_u) 212 | filename = 'HollowSphere' 213 | energyPlot(xGrid,yGrid,zGrid,nPred,u_pred,v_pred,w_pred,energy_pred,errU,errV,errW,filename) 214 | 215 | print('Loss convergence') 216 | adam_buff = modelNN.loss_adam_buff 217 | lbfgs_buff = modelNN.lbfgs_buffer 218 | plotConvergence(num_train_its,adam_buff,lbfgs_buff,figHeight,figWidth) 219 | 220 | # Compute the L2 and energy norm errors using integration 221 | u_pred, v_pred, w_pred, energy_pred, sigma_x_pred, sigma_y_pred, sigma_z_pred, \ 222 | tau_xy_pred, tau_yz_pred, tau_zx_pred = modelNN.predict(X_f) 223 | u_exact, v_exact, w_exact = getExactDisplacements(X_f[:,0], X_f[:,1], X_f[:,2], model) 224 | err_l2 = np.sum(((u_exact-u_pred[:,0])**2 + (v_exact-v_pred[:,0])**2 + \ 225 | (w_exact-w_pred[:,0])**2)*X_f[:,3]) 226 | norm_l2 = np.sum((u_exact**2 + v_exact**2 + w_exact**2)*X_f[:,3]) 227 | error_u_l2 = np.sqrt(err_l2/norm_l2) 228 | print("Relative L2 error (integration): ", error_u_l2) 229 | 230 | energy_err, energy_norm = energyError(X_f,sigma_x_pred,sigma_y_pred,model,\ 231 | sigma_z_pred,tau_xy_pred,tau_yz_pred,tau_zx_pred,getExactStresses) 232 | print("Relative energy error (integration): ", np.sqrt(energy_err/energy_norm)) 233 | os.chdir(originalDir) 234 | 235 | -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Elasticity/cube_with_hole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/Elasticity/cube_with_hole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Elasticity/readme.md: -------------------------------------------------------------------------------- 1 | Files that use the Geomdl library for geometry modeling. 2 | 3 | Install with: 4 | 5 | `pip install geomdl` 6 | -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Elasticity/utils/gridPlot.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from mpl_toolkits.mplot3d import Axes3D 5 | from pyevtk.hl import gridToVTK 6 | 7 | def createFolder(folder_name): 8 | try: 9 | if not os.path.exists(folder_name): 10 | os.makedirs(folder_name) 11 | except OSError: 12 | print ('Error: Creating folder. ' + folder_name) 13 | 14 | def cart2sph(x, y, z): 15 | # From https://stackoverflow.com/questions/30084174/efficient-matlab-cart2sph-and-sph2cart-functions-in-python 16 | azimuth = np.arctan2(y,x) 17 | elevation = np.arctan2(z,np.sqrt(x**2 + y**2)) 18 | r = np.sqrt(x**2 + y**2 + z**2) 19 | return azimuth, elevation, r 20 | 21 | def sph2cart(azimuth, elevation, r): 22 | # From https://stackoverflow.com/questions/30084174/efficient-matlab-cart2sph-and-sph2cart-functions-in-python 23 | x = r * np.cos(elevation) * np.cos(azimuth) 24 | y = r * np.cos(elevation) * np.sin(azimuth) 25 | z = r * np.sin(elevation) 26 | return x, y, z 27 | 28 | def scatterPlot(X_f,X_bnd,figHeight,figWidth,filename): 29 | fig = plt.figure(figsize=(figWidth,figHeight)) 30 | ax = fig.gca(projection='3d') 31 | ax.scatter(X_f[:,0], X_f[:,1], X_f[:,2], s = 0.75) 32 | ax.scatter(X_bnd[:,0], X_bnd[:,1], X_bnd[:,2], s = 0.75, c='red') 33 | ax.set_xlabel('$x$',fontweight='bold',fontsize = 12) 34 | ax.set_ylabel('$y$',fontweight='bold',fontsize = 12) 35 | ax.set_zlabel('$z$',fontweight='bold',fontsize = 12) 36 | ax.tick_params(axis='both', which='major', labelsize = 6) 37 | ax.tick_params(axis='both', which='minor', labelsize = 6) 38 | plt.savefig(filename+'.png', dpi=300, facecolor='w', edgecolor='w', 39 | transparent = 'true', bbox_inches = 'tight') 40 | plt.show() 41 | plt.close() 42 | 43 | def energyPlot(xGrid,yGrid,zGrid,nPred,u_pred,v_pred,w_pred,energy_pred,errU,errV,errW,filename): 44 | # Plot results 45 | oShapeX = np.resize(xGrid, [nPred, nPred, nPred]) 46 | oShapeY = np.resize(yGrid, [nPred, nPred, nPred]) 47 | oShapeZ = np.resize(zGrid, [nPred, nPred, nPred]) 48 | 49 | u = np.resize(u_pred, [nPred, nPred, nPred]) 50 | v = np.resize(v_pred, [nPred, nPred, nPred]) 51 | w = np.resize(w_pred, [nPred, nPred, nPred]) 52 | displacement = (u, v, w) 53 | 54 | elas_energy = np.resize(energy_pred, [nPred, nPred, nPred]) 55 | 56 | gridToVTK(filename, oShapeX, oShapeY, oShapeZ, pointData = 57 | {"Displacement": displacement, "Elastic Energy": elas_energy}) 58 | 59 | err_u = np.resize(errU, [nPred, nPred, nPred]) 60 | err_v = np.resize(errV, [nPred, nPred, nPred]) 61 | err_w = np.resize(errW, [nPred, nPred, nPred]) 62 | 63 | disp_err = (err_u, err_v, err_w) 64 | gridToVTK(filename+'Err', oShapeX, oShapeY, oShapeZ, pointData = 65 | {"Displacement": disp_err, "Elastic Energy": elas_energy}) 66 | 67 | def plotConvergence(iter,adam_buff,lbfgs_buff,figHeight,figWidth): 68 | filename = "convergence" 69 | plt.figure(figsize=(figWidth, figHeight)) 70 | range_adam = np.arange(1,iter+1) 71 | range_lbfgs = np.arange(iter+2, iter+2+len(lbfgs_buff)) 72 | ax0, = plt.semilogy(range_adam, adam_buff, c='b', label='Adam',linewidth=2.0) 73 | ax1, = plt.semilogy(range_lbfgs, lbfgs_buff, c='r', label='L-BFGS',linewidth=2.0) 74 | plt.legend(handles=[ax0,ax1],fontsize=14) 75 | plt.xticks(fontsize=12) 76 | plt.yticks(fontsize=12) 77 | plt.xlabel('Iteration',fontweight='bold',fontsize=14) 78 | plt.ylabel('Loss value',fontweight='bold',fontsize=14) 79 | plt.tight_layout() 80 | plt.savefig(filename+".pdf", dpi=700, facecolor='w', edgecolor='w', 81 | transparent = 'true', bbox_inches = 'tight') 82 | plt.show() 83 | plt.close() 84 | 85 | def energyError(X_f,sigma_x_pred,sigma_y_pred,model,sigma_z_pred,tau_xy_pred,tau_yz_pred,tau_zx_pred,getExactStresses): 86 | sigma_xx_exact, sigma_yy_exact, sigma_zz_exact, sigma_xy_exact, sigma_yz_exact, \ 87 | sigma_zx_exact = getExactStresses(X_f[:,0], X_f[:,1], X_f[:,2], model) 88 | sigma_xx_err = sigma_xx_exact - sigma_x_pred[:,0] 89 | sigma_yy_err = sigma_yy_exact - sigma_y_pred[:,0] 90 | sigma_zz_err = sigma_zz_exact - sigma_z_pred[:,0] 91 | sigma_xy_err = sigma_xy_exact - tau_xy_pred[:,0] 92 | sigma_yz_err = sigma_yz_exact - tau_yz_pred[:,0] 93 | sigma_zx_err = sigma_zx_exact - tau_zx_pred[:,0] 94 | 95 | energy_err = 0 96 | energy_norm = 0 97 | numPts = X_f.shape[0] 98 | 99 | C_mat = np.zeros((6,6)) 100 | C_mat[0,0] = model['E']*(1-model['nu'])/((1+model['nu'])*(1-2*model['nu'])) 101 | C_mat[1,1] = model['E']*(1-model['nu'])/((1+model['nu'])*(1-2*model['nu'])) 102 | C_mat[2,2] = model['E']*(1-model['nu'])/((1+model['nu'])*(1-2*model['nu'])) 103 | C_mat[0,1] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 104 | C_mat[0,2] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 105 | C_mat[1,0] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 106 | C_mat[1,2] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 107 | C_mat[2,0] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 108 | C_mat[2,0] = model['E']*model['nu']/((1+model['nu'])*(1-2*model['nu'])) 109 | C_mat[3,3] = model['E']/(2*(1+model['nu'])) 110 | C_mat[4,4] = model['E']/(2*(1+model['nu'])) 111 | C_mat[5,5] = model['E']/(2*(1+model['nu'])) 112 | 113 | C_inv = np.linalg.inv(C_mat) 114 | for i in range(numPts): 115 | err_pt = np.array([sigma_xx_err[i], sigma_yy_err[i], sigma_zz_err[i], 116 | sigma_xy_err[i], sigma_yz_err[i], sigma_zx_err[i]]) 117 | norm_pt = np.array([sigma_xx_exact[i], sigma_yy_exact[i], sigma_zz_exact[i], \ 118 | sigma_xy_exact[i], sigma_yz_exact[i], sigma_zx_exact[i]]) 119 | energy_err = energy_err + err_pt@C_inv@err_pt.T*X_f[i,3] 120 | energy_norm = energy_norm + norm_pt@C_inv@norm_pt.T*X_f[i,3] 121 | 122 | return energy_err, energy_norm -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Phase Field/TensilePlate.py: -------------------------------------------------------------------------------- 1 | # Implements the second-order phase field to study the growth of fracture in a two dimensional plate 2 | # The plate has initial crack and is under tensile loading 3 | 4 | import tensorflow as tf 5 | import numpy as np 6 | import matplotlib as mpl 7 | mpl.rcParams['figure.dpi'] = 200 8 | import time 9 | import os 10 | tf.reset_default_graph() # To clear the defined variables and operations of the previous cell 11 | tf.logging.set_verbosity(tf.logging.ERROR) 12 | from utils.gridPlot import scatterPlot 13 | from utils.gridPlot import genGrid 14 | from utils.gridPlot import plotDispStrainEnerg 15 | from utils.gridPlot import plotPhiStrainEnerg 16 | from utils.gridPlot import plotConvergence 17 | from utils.gridPlot import createFolder 18 | from utils.gridPlot import plot1dPhi 19 | from utils.BezExtr import Geometry2D 20 | from utils.gridPlot import plotForceDisp 21 | from utils.BezExtr import refineElemRegionY2D 22 | from utils.PINN_2ndPF import CalculateUPhi 23 | 24 | np.random.seed(1234) 25 | tf.set_random_seed(1234) 26 | 27 | class Quadrilateral(Geometry2D): 28 | ''' 29 | Class for definining a quadrilateral domain 30 | Input: quadDom: array of the form [[x1, y1], [x2, y2], [x3, y3], [x4, y4]] 31 | containing the domain corners (control-points) 32 | ''' 33 | def __init__(self, quadDom): 34 | 35 | # Domain bounds 36 | self.quadDom = quadDom 37 | 38 | self.x1, self.y1 = self.quadDom[0,:] 39 | self.x2, self.y2 = self.quadDom[1,:] 40 | self.x3, self.y3 = self.quadDom[2,:] 41 | self.x4, self.y4 = self.quadDom[3,:] 42 | 43 | geomData = dict() 44 | 45 | # Set degrees 46 | geomData['degree_u'] = 1 47 | geomData['degree_v'] = 1 48 | 49 | # Set control points 50 | geomData['ctrlpts_size_u'] = 2 51 | geomData['ctrlpts_size_v'] = 2 52 | 53 | geomData['ctrlpts'] = np.array([[self.x1, self.y1, 0], [self.x2, self.y2, 0], 54 | [self.x3, self.y3, 0], [self.x4, self.y4, 0]]) 55 | 56 | geomData['weights'] = np.array([[1.0], [1.0], [1.0], [1.0]]) 57 | 58 | # Set knot vectors 59 | geomData['knotvector_u'] = [0.0, 0.0, 1.0, 1.0] 60 | geomData['knotvector_v'] = [0.0, 0.0, 1.0, 1.0] 61 | 62 | super().__init__(geomData) 63 | 64 | class PINN_PF(CalculateUPhi): 65 | ''' 66 | Class including (symmetry) boundary conditions for the tension plate 67 | ''' 68 | def __init__(self, model, NN_param): 69 | #PhysicsInformedNN.__init__(self, model_data, model_pts, NN_param) 70 | super().__init__(model, NN_param) 71 | 72 | def net_uv(self,x,y,vdelta): 73 | 74 | X = tf.concat([x,y],1) 75 | 76 | uvphi = self.neural_net(X,self.weights,self.biases) 77 | uNN = uvphi[:,0:1] 78 | vNN = uvphi[:,1:2] 79 | 80 | u = (1-x)*x*uNN 81 | v = y*(y-1)*vNN + y*vdelta 82 | 83 | return u, v 84 | if __name__ == "__main__": 85 | 86 | originalDir = os.getcwd() 87 | foldername = 'TensionPlate_results' 88 | createFolder('./'+ foldername + '/') 89 | os.chdir(os.path.join(originalDir, './'+ foldername + '/')) 90 | 91 | figHeight = 5 92 | figWidth = 5 93 | nSteps = 8 # Total number of steps to observe the growth of crack 94 | deltaV = 1e-3 #displacement increment per step 95 | 96 | model = dict() 97 | model['E'] = 210.0*1e3 # Modulus of elasticity 98 | model['nu'] = 0.3 # Poission's ratio 99 | model['L'] = 1.0 # Length of the plate 100 | model['W'] = 1.0 # Breadth of the plate 101 | model['l'] = 0.0125 # length scale parameter 102 | # Domain bounds 103 | model['lb'] = np.array([0.0,0.0]) #lower bound of the plate 104 | model['ub'] = np.array([model['L'],model['W']]) # Upper bound of the plate 105 | 106 | NN_param = dict() # neural network parameters 107 | NN_param['layers'] = [2, 20, 20, 20, 3] # Layers and neurons for the neural network 108 | NN_param['data_type'] = tf.float32 # Data type of the variables for the analysis 109 | 110 | # Generating points inside the domain using Geometry class 111 | domainCorners = np.array([[0,0],[model['W'], 0.],[0, model['L']],[ model['W'],model['L']]]) 112 | myQuad = Quadrilateral(domainCorners) 113 | numElemU = 40 114 | numElemV = 40 115 | numGauss = 1 116 | vertex = myQuad.genElemList(numElemU,numElemV) 117 | 118 | # Refine betwenn 0.3 < y < 0.7 119 | refYmax = 0.7 120 | refYmin = 0.3 121 | vertex = refineElemRegionY2D(vertex,refYmin,refYmax) 122 | 123 | # Refine betwenn 0.4 < y < 0.6 124 | refYmax = 0.6 125 | refYmin = 0.4 126 | vertex = refineElemRegionY2D(vertex,refYmin,refYmax) 127 | 128 | # Refine betwenn 0.45 < y < 0.55 129 | refYmax = 0.55 130 | refYmin = 0.45 131 | vertex = refineElemRegionY2D(vertex,refYmin,refYmax) 132 | 133 | # Refine betwenn 0.475 < y < 0.525 134 | refYmax = 0.525 135 | refYmin = 0.475 136 | vertex = refineElemRegionY2D(vertex,refYmin,refYmax) 137 | 138 | 139 | xPhys, yPhys, wgtsPhys = myQuad.getElemIntPts(vertex, numGauss) 140 | X_f = np.concatenate((xPhys,yPhys, wgtsPhys),axis=1) 141 | hist_f = np.transpose(np.array([np.zeros((X_f.shape[0]),dtype = np.float32)])) 142 | filename = 'Training_scatter' 143 | scatterPlot(X_f,figHeight,figWidth,filename) 144 | 145 | # Boundary data 146 | N_b = 800 # Number of boundary points for the fracture analysis (Left, Right, Top, Bottom) 147 | x_bottomEdge = np.array([np.linspace(0.0,model['L'],int(N_b/4), dtype = np.float32)]) 148 | y_bottomEdge = np.zeros((int(N_b/4),1),dtype = np.float32) 149 | xBottomEdge = np.concatenate((x_bottomEdge.T,y_bottomEdge), axis=1) 150 | 151 | # Generating the prediction mesh 152 | nPred = np.array([[135,45],[135,45],[135,45]]) 153 | offset = 2*model['l'] 154 | secBound = np.array([[0.0, 0.5*model['L']-offset],[0.5*model['L']-offset, 155 | 0.5*model['L']+offset],[0.5*model['L']+offset, model['L']]], dtype = np.float32) 156 | Grid, xGrid, yGrid, hist_grid = genGrid(nPred,model['L'],secBound) 157 | filename = 'Prediction_scatter' 158 | scatterPlot(Grid,figHeight,figWidth,filename) 159 | 160 | fdGraph = np.zeros((nSteps,2),dtype = np.float32) 161 | phi_pred_old = hist_grid # Initializing phi_pred_old to zero 162 | 163 | modelNN = PINN_PF(model, NN_param) 164 | num_train_its = 10000 165 | 166 | for iStep in range(0,nSteps): 167 | 168 | v_delta = deltaV*iStep 169 | 170 | start_time = time.time() 171 | if iStep==0: 172 | num_lbfgs_its = 10000 173 | else: 174 | num_lbfgs_its = 2000 175 | 176 | modelNN.train(X_f, v_delta, hist_f, num_train_its, num_lbfgs_its) 177 | elapsed = time.time() - start_time 178 | print('Training time: %.4f' % (elapsed)) 179 | 180 | _, _, _, _, _, hist_f = modelNN.predict(X_f[:,0:2], hist_f, v_delta) # Computing the history function for the next step 181 | u_pred, v_pred, phi_pred, elas_energy_pred, frac_energy_pred, hist_grid = modelNN.predict(Grid,hist_grid,v_delta) 182 | 183 | traction_pred = modelNN.predict_traction(xBottomEdge,v_delta) 184 | fdGraph[iStep,0] = v_delta 185 | fdGraph[iStep,1] = 4*np.sum(traction_pred,axis=0)/N_b 186 | 187 | phi_pred = np.maximum(phi_pred, phi_pred_old) 188 | phi_pred_old = phi_pred 189 | 190 | plotPhiStrainEnerg(nPred,xGrid,yGrid,phi_pred,frac_energy_pred,iStep,figHeight,figWidth) 191 | plotDispStrainEnerg(nPred,xGrid,yGrid,u_pred,v_pred,elas_energy_pred,iStep,figHeight,figWidth) 192 | 193 | adam_buff = modelNN.loss_adam_buff 194 | lbfgs_buff = modelNN.lbfgs_buffer 195 | plotConvergence(num_train_its,adam_buff,lbfgs_buff,iStep,figHeight,figWidth) 196 | 197 | # 1D plot of phase field 198 | xVal = 0.25 199 | nPredY = 2000 200 | xPred = xVal*np.ones((nPredY,1)) 201 | yPred = np.linspace(0,model['W'],nPredY)[np.newaxis] 202 | xyPred = np.concatenate((xPred,yPred.T),axis=1) 203 | phi_pred_1d = modelNN.predict_phi(xyPred) 204 | phi_exact = np.exp(-np.absolute(yPred-0.5)/model['l']) 205 | plot1dPhi(yPred,phi_pred_1d,phi_exact,iStep,figHeight,figWidth) 206 | 207 | error_phi = (np.linalg.norm(phi_exact-phi_pred_1d.T,2)/np.linalg.norm(phi_exact,2)) 208 | print('Relative error phi: %e' % (error_phi)) 209 | 210 | print('Completed '+ str(iStep+1) +' of '+str(nSteps)+'.') 211 | 212 | plotForceDisp(fdGraph,figHeight,figWidth) 213 | os.chdir(originalDir) 214 | -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/cube_with_hole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/cube_with_hole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsBoundCubeWithHole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/gaussPtsBoundCubeWithHole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsBoundHollowSphere.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/gaussPtsBoundHollowSphere.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsCubeWithHole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/gaussPtsCubeWithHole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsHollowSphere.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/431ad94aa34b6f2ab9b4c251b7c93a020e20583b/tf1/tensorflow_DEM/gaussPtsHollowSphere.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/readme.md: -------------------------------------------------------------------------------- 1 | Files that use the Geomdl library for geometry modeling. 2 | 3 | Install with: 4 | 5 | `pip install geomdl` 6 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Adaptive (CMC_paper)/AcousticDuct_adaptive.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implement a Helmholtz 2D problem for the acoustic duct: 3 | \Delta u(x,y) +k^2u(x,y) = 0 for (x,y) \in \Omega:= (0,2)x(0,1) 4 | \partial u / \partial n = cos(m*pi*x), for x = 0; 5 | \partial u / \partial n = -iku, for x = 2; 6 | \partial u / \partial n = 0, for y=0 and y=1 7 | 8 | 9 | Exact solution: u(x,y) = cos(m*pi*y)*(A_1*exp(-i*k_x*x) + A_2*exp(i*k_x*x))corresponding to 10 | where A_1 and A_2 are obtained by solving the 2x2 linear system: 11 | [i*k_x -i*k_x ] [A_1] = [1] 12 | [(k-k_x)*exp(-2*i*k_x) (k+k_x)*exp(2*i*k_x)] [A_2] [0] 13 | 14 | Writes output for TensorBoard 15 | Adaptivity 16 | 17 | ''' 18 | 19 | import tensorflow as tf 20 | import numpy as np 21 | #import sys 22 | #print(sys.path) 23 | from utils.PoissonEqAdapt import PoissonEquationColl 24 | from utils.Geometry import QuadrilateralGeom 25 | import matplotlib.pyplot as plt 26 | import time 27 | 28 | import matplotlib as mpl 29 | mpl.rcParams['figure.dpi'] = 300 30 | 31 | print("Initializing domain...") 32 | tf.reset_default_graph() # To clear the defined variables and operations of the previous cell 33 | np.random.seed(1234) 34 | tf.set_random_seed(1234) 35 | 36 | #problem parameters 37 | m = 2; #mode number 38 | k = 12; #wave number 39 | alpha = -k**2 40 | 41 | 42 | #model paramaters 43 | layers = [2, 30, 30, 30, 1] #number of neurons in each layer 44 | num_train_its = 10000 #number of training iterations 45 | data_type = tf.float32 46 | numIter = 3 47 | pen_dir = 0 48 | pen_neu = 100 49 | numBndPts = 101 50 | numIntPtsX = 101 51 | numIntPtsY = 51 52 | 53 | #solve for the constants A1 and A2 in the exact solution 54 | kx = np.sqrt(k**2 - (m*np.pi)**2); 55 | LHS = np.array([[1j*kx, -1j*kx], [(k-kx)*np.exp(-2*1j*kx), (k+kx)*np.exp(2*1j*kx)]]) 56 | RHS = np.array([[1],[0]]) 57 | A = np.linalg.solve(LHS, RHS) 58 | 59 | #generate points 60 | domainCorners = np.array([[0,0],[2,0],[2,1],[0,1]]) 61 | domainGeom = QuadrilateralGeom(domainCorners) 62 | neumann_left_x, neumann_left_y, normal_left_x, normal_left_y = domainGeom.getLeftPts(numBndPts) 63 | neumann_bottom_x, neumann_bottom_y, normal_bottom_x, normal_bottom_y = domainGeom.getBottomPts(numBndPts) 64 | neumann_top_x, neumann_top_y, normal_top_x, normal_top_y = domainGeom.getTopPts(numBndPts) 65 | neumann_right_x, neumann_right_y, normal_right_x, normal_right_y = domainGeom.getRightPts(numBndPts) 66 | interior_x, interior_y = domainGeom.getUnifIntPts(numIntPtsX, numIntPtsY, [0,0,0,0]) 67 | interior_x_flat = np.ndarray.flatten(interior_x)[np.newaxis] 68 | interior_y_flat = np.ndarray.flatten(interior_y)[np.newaxis] 69 | 70 | #generate boundary values 71 | neumann_left_flux = np.cos(m*np.pi*neumann_left_y) 72 | neumann_bottom_flux = np.zeros((numBndPts,1)) 73 | neumann_top_flux = np.zeros((numBndPts,1)) 74 | neumann_right_flux = np.real(np.cos(m*np.pi*neumann_right_y)*(A[0]*(-1j)*kx*np.exp(-1j*kx*neumann_right_x)\ 75 | +A[1]*1j*kx*np.exp(1j*kx*neumann_right_x))) 76 | 77 | #generate interior values (f(x,y)) 78 | f_val = np.zeros_like(interior_x_flat) 79 | 80 | #combine points 81 | neumann_left_bnd = np.concatenate((neumann_left_x, neumann_left_y, 82 | normal_left_x, normal_left_y, neumann_left_flux), axis=1) 83 | neumann_bottom_bnd = np.concatenate((neumann_bottom_x, neumann_bottom_y, 84 | normal_bottom_x, normal_bottom_y, neumann_bottom_flux), axis=1) 85 | neumann_top_bnd = np.concatenate((neumann_top_x, neumann_top_y, 86 | normal_top_x, normal_top_y, neumann_top_flux), axis=1) 87 | neumann_right_bnd = np.concatenate((neumann_right_x, neumann_right_y, 88 | normal_right_x, normal_right_y, neumann_right_flux), axis=1) 89 | neumann_bnd = np.concatenate((neumann_left_bnd, neumann_bottom_bnd, neumann_top_bnd, neumann_right_bnd), axis=0) 90 | dirichlet_bnd = np.zeros((1,3)) 91 | X_int = np.concatenate((interior_x_flat.T, interior_y_flat.T, f_val.T), axis=1) 92 | top_pred_X = np.zeros([0,3]) 93 | 94 | 95 | #adaptivity loop 96 | 97 | rel_err = np.zeros(numIter) 98 | rel_est_err = np.zeros(numIter) 99 | numPts = np.zeros(numIter) 100 | 101 | print('Defining model...') 102 | model = PoissonEquationColl(dirichlet_bnd, neumann_bnd, alpha, layers, data_type, pen_dir, pen_neu) 103 | 104 | for i in range(numIter): 105 | 106 | #training part 107 | X_int = np.concatenate((X_int, top_pred_X)) 108 | print('Domain geometry') 109 | plt.scatter(neumann_bnd[:,0], neumann_bnd[:,1],s=0.5,c='g') 110 | plt.scatter(dirichlet_bnd[:,0], dirichlet_bnd[:,1],s=0.5,c='r') 111 | plt.scatter(X_int[:,0], X_int[:,1], s=0.5, c='b') 112 | plt.show() 113 | 114 | 115 | start_time = time.time() 116 | print('Starting training...') 117 | model.train(X_int, num_train_its) 118 | elapsed = time.time() - start_time 119 | print('Training time: %.4f' % (elapsed)) 120 | 121 | #generate points for evaluating the model 122 | print('Evaluating model...') 123 | numPredPtsX = 2*numIntPtsX 124 | numPredPtsY = 2*numIntPtsY 125 | pred_interior_x, pred_interior_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [1,1,1,1]) 126 | pred_interior_x_flat = np.ndarray.flatten(pred_interior_x)[np.newaxis] 127 | pred_interior_y_flat = np.ndarray.flatten(pred_interior_y)[np.newaxis] 128 | pred_X = np.concatenate((pred_interior_x_flat.T, pred_interior_y_flat.T), axis=1) 129 | u_pred, _ = model.predict(pred_X) 130 | 131 | #define exact solution 132 | u_exact = np.real(np.cos(m*np.pi*pred_interior_y_flat.T)*(A[0]*np.exp(-1j*kx*pred_interior_x_flat.T)\ 133 | +A[1]*np.exp(1j*kx*pred_interior_x_flat.T))) 134 | 135 | u_pred_err = u_exact-u_pred 136 | error_u = (np.linalg.norm(u_exact-u_pred,2)/np.linalg.norm(u_exact,2)) 137 | print('Relative error u: %e' % (error_u)) 138 | 139 | # #plot the solution u_comp 140 | print('$u_{comp}$') 141 | u_pred = np.resize(u_pred, [numPredPtsY, numPredPtsX]) 142 | CS = plt.contourf(pred_interior_x, pred_interior_y, u_pred, 255, cmap=plt.cm.jet) 143 | plt.colorbar() # draw colorbar 144 | #plt.title('$u_{comp}$') 145 | plt.show() 146 | 147 | #plot the error u_ex 148 | print('$u_{ex}$') 149 | u_exact = np.resize(u_exact, [numPredPtsY, numPredPtsX]) 150 | plt.contourf(pred_interior_x, pred_interior_y, u_exact, 255, cmap=plt.cm.jet) 151 | plt.colorbar() # draw colorbar 152 | #plt.title('$u_{ex}$') 153 | plt.show() 154 | 155 | #plot the error u_ex - u_comp 156 | print('u_ex - u_comp') 157 | u_pred_err = np.resize(u_pred_err, [numPredPtsY, numPredPtsX]) 158 | plt.contourf(pred_interior_x, pred_interior_y, u_pred_err, 255, cmap=plt.cm.jet) 159 | plt.colorbar() # draw colorbar 160 | #plt.title('$u_{ex}-u_{comp}$') 161 | plt.show() 162 | # 163 | # 164 | print('Loss convergence') 165 | range_adam = np.arange(1,num_train_its+1) 166 | range_lbfgs = np.arange(num_train_its+2, num_train_its+2+len(model.lbfgs_buffer)) 167 | ax0, = plt.semilogy(range_adam, model.loss_adam_buff, label='Adam') 168 | ax1, = plt.semilogy(range_lbfgs, model.lbfgs_buffer, label='L-BFGS') 169 | plt.legend(handles=[ax0,ax1]) 170 | plt.xlabel('Iteration') 171 | plt.ylabel('Loss value') 172 | plt.show() 173 | 174 | #generate interior points for evaluating the model 175 | numPredPtsX = 2*numIntPtsX-1 176 | numPredPtsY = 2*numIntPtsY-1 177 | pred_int_x, pred_int_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [0,0,0,0]) 178 | pred_int_x_flat = np.ndarray.flatten(pred_int_x)[np.newaxis] 179 | pred_int_y_flat = np.ndarray.flatten(pred_int_y)[np.newaxis] 180 | pred_X = np.concatenate((pred_int_x_flat.T, pred_int_y_flat.T), axis=1) 181 | u_pred, f_pred = model.predict(pred_X) 182 | 183 | f_val = np.zeros_like(pred_int_x_flat.T) 184 | 185 | f_err = f_val - f_pred 186 | f_err_rel = (np.linalg.norm(f_err,2)/np.linalg.norm(f_val,2)) 187 | 188 | rel_err[i] = error_u 189 | rel_est_err[i] = f_err_rel 190 | numPts[i] = len(X_int) 191 | 192 | print('Estimated relative error f_int-f_pred: %e' % (f_err_rel)) 193 | print('f_int - f_pred') 194 | f_err_plt = np.resize(f_err, [numPredPtsY-2, numPredPtsX-2]) 195 | plt.contourf(pred_int_x, pred_int_y, f_err_plt, 255, cmap=plt.cm.jet) 196 | plt.colorbar() # draw colorbar 197 | plt.show() 198 | 199 | #pick the top N percent interior points with highest error 200 | N = 30 201 | ntop = np.int(np.round(len(f_err)*N/100)) 202 | index_f_err = np.argsort(-np.abs(f_err),axis=0) 203 | top_pred_xy = np.squeeze(pred_X[index_f_err[0:ntop-1,:]]) 204 | 205 | #generate interior values (f(x,y)) 206 | top_pred_val = np.squeeze(f_val[index_f_err[0:ntop-1,:]], axis=2) 207 | top_pred_X = np.concatenate((top_pred_xy, top_pred_val), axis=1) 208 | 209 | 210 | print(rel_err) 211 | print(rel_est_err) 212 | print(numPts) 213 | 214 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Adaptive (CMC_paper)/Poisson_Annulus_adaptive.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implement a Poisson-type 2D problem with pure Dirichlet boundary conditions on an 3 | Annulus domain: 4 | - \Delta u(x,y) + u(x,y) = f(x,y) for (x,y) \in \Omega quarter-annulus with inner 5 | radius 1, and outer radius 4 6 | u(x,y) = 0, for (x,y) \in \partial \Omega 7 | Exact solution: u(x,y) = (x^2+y^2-1)*(x^2+y^2-16)*sin(x)*sin(y) corresponding to 8 | f(x,y) = (3*x^4 - 67*x^2 - 67*y^2 + 3*y^4 + 6*x^2*y^2 + 116)*sin(x)*sin(y)+ 9 | +(68*x - 8*x^3 - 8*x*y^2)* cos(x)*sin(y) + 10 | +(68*y - 8*y^3 - 8*y*x^2)* cos(x)*sin(y) 11 | (defined in net_f_u function) 12 | See Example 4.4 in https://doi.org/10.1142/S0218202510004878 13 | ''' 14 | import tensorflow as tf 15 | import numpy as np 16 | #import sys 17 | #print(sys.path) 18 | from utils.PoissonEqAdapt import PoissonEquationColl 19 | from utils.Geometry import AnnulusGeom 20 | import matplotlib.pyplot as plt 21 | import time 22 | 23 | import matplotlib as mpl 24 | mpl.rcParams['figure.dpi'] = 200 25 | 26 | print("Initializing domain...") 27 | tf.reset_default_graph() # To clear the defined variables and operations of the previous cell 28 | np.random.seed(1234) 29 | tf.set_random_seed(1234) 30 | 31 | #problem parameters 32 | alpha = 1 33 | 34 | #model paramaters 35 | layers = [2, 10, 10, 1] #number of neurons in each layer 36 | num_train_its = 10000 #number of training iterations 37 | data_type = tf.float32 38 | pen_dir = 100 39 | pen_neu = 0 40 | numIter = 3 41 | 42 | numPts = 21 43 | numBndPts = 2*numPts 44 | numIntPtsX = numPts 45 | numIntPtsY = numPts 46 | 47 | #generate points 48 | rad_int = 1 49 | rad_ext = 4 50 | domainGeom = AnnulusGeom(rad_int, rad_ext) 51 | dirichlet_inner_x, dirichlet_inner_y, _, _ = domainGeom.getInnerPts(numBndPts) 52 | dirichlet_outer_x, dirichlet_outer_y, _, _ = domainGeom.getOuterPts(numBndPts) 53 | dirichlet_xax_x, dirichlet_xax_y, _, _ = domainGeom.getXAxPts(numBndPts) 54 | dirichlet_yax_x, dirichlet_yax_y, _, _ = domainGeom.getYAxPts(numBndPts) 55 | 56 | interior_x, interior_y = domainGeom.getUnifIntPts(numIntPtsX, numIntPtsY, [0,0,0,0]) 57 | int_x = np.ndarray.flatten(interior_x)[np.newaxis] 58 | int_y = np.ndarray.flatten(interior_y)[np.newaxis] 59 | 60 | #generate boundary values 61 | dirichlet_inner_u = np.zeros((numBndPts,1)) 62 | dirichlet_outer_u = np.zeros((numBndPts,1)) 63 | dirichlet_xax_u = np.zeros((numBndPts,1)) 64 | dirichlet_yax_u = np.zeros((numBndPts,1)) 65 | #generate interior values (f(x,y)) 66 | f_val = (3*int_x**4 - 67*int_x**2 - 67*int_y**2 + 3*int_y**4 + 6*int_x**2*int_y**2 + 116)*np.sin(int_x)*np.sin(int_y) \ 67 | +(68*int_x - 8*int_x**3 - 8*int_x*int_y**2) * np.cos(int_x)*np.sin(int_y) \ 68 | +(68*int_y - 8*int_y**3 - 8*int_y*int_x**2) * np.cos(int_y)*np.sin(int_x) 69 | 70 | 71 | #combine points 72 | dirichlet_inner_bnd = np.concatenate((dirichlet_inner_x, dirichlet_inner_y, dirichlet_inner_u), axis=1) 73 | dirichlet_outer_bnd = np.concatenate((dirichlet_outer_x, dirichlet_outer_y, dirichlet_outer_u), axis=1) 74 | dirichlet_xax_bnd = np.concatenate((dirichlet_xax_x, dirichlet_xax_y, dirichlet_xax_u), axis=1) 75 | dirichlet_yax_bnd = np.concatenate((dirichlet_yax_x, dirichlet_yax_y, dirichlet_yax_u), axis=1) 76 | dirichlet_bnd = np.concatenate((dirichlet_inner_bnd, dirichlet_outer_bnd, 77 | dirichlet_xax_bnd, dirichlet_yax_bnd), axis=0) 78 | #neumann_bnd = np.array([[],[],[],[],[]]) 79 | neumann_bnd = np.zeros((1,5)) 80 | top_pred_X = np.zeros([0,3]) 81 | 82 | X_int = np.concatenate((int_x.T, int_y.T, f_val.T), axis=1) 83 | 84 | print('Defining model...') 85 | model = PoissonEquationColl(dirichlet_bnd, neumann_bnd, alpha, layers, data_type, pen_dir, pen_neu) 86 | 87 | 88 | #adaptivity loop 89 | 90 | rel_err = np.zeros(numIter) 91 | rel_est_err = np.zeros(numIter) 92 | numPts = np.zeros(numIter) 93 | 94 | for i in range(numIter): 95 | 96 | X_int = np.concatenate((X_int, top_pred_X)) 97 | 98 | 99 | print('Domain geometry') 100 | plt.scatter(dirichlet_bnd[:,0], dirichlet_bnd[:,1],s=0.5,c='r') 101 | plt.scatter(X_int[:,0], X_int[:,1], s=0.5, c='b') 102 | plt.show() 103 | 104 | start_time = time.time() 105 | print('Starting training...') 106 | model.train(X_int, num_train_its) 107 | elapsed = time.time() - start_time 108 | print('Training time: %.4f' % (elapsed)) 109 | 110 | 111 | #generate points for evaluating the model 112 | print('Evaluating model...') 113 | numPredPtsX = 2*numIntPtsX 114 | numPredPtsY = 2*numIntPtsY 115 | pred_interior_x, pred_interior_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [1,1,1,1]) 116 | pred_x = np.ndarray.flatten(pred_interior_x)[np.newaxis] 117 | pred_y = np.ndarray.flatten(pred_interior_y)[np.newaxis] 118 | pred_X = np.concatenate((pred_x.T, pred_y.T), axis=1) 119 | u_pred, _ = model.predict(pred_X) 120 | 121 | 122 | u_exact = (pred_x.T**2+pred_y.T**2-1)*(pred_x.T**2+pred_y.T**2-16)*np.sin(pred_x.T)*np.sin(pred_y.T) 123 | u_pred_err = u_exact-u_pred 124 | 125 | 126 | error_u = (np.linalg.norm(u_exact-u_pred,2)/np.linalg.norm(u_exact,2)) 127 | print('Relative error u: %e' % (error_u)) 128 | 129 | # #plot the solution u_comp 130 | print('$u_{comp}$') 131 | u_pred = np.resize(u_pred, [numPredPtsX, numPredPtsY]) 132 | CS = plt.contourf(pred_interior_x, pred_interior_y, u_pred, 255, cmap=plt.cm.jet) 133 | plt.colorbar() # draw colorbar 134 | #plt.title('$u_{comp}$') 135 | plt.show() 136 | 137 | #plot the error u_ex 138 | print('$u_{ex}$') 139 | u_exact = np.resize(u_exact, [numPredPtsX, numPredPtsY]) 140 | plt.contourf(pred_interior_x, pred_interior_y, u_exact, 255, cmap=plt.cm.jet) 141 | plt.colorbar() # draw colorbar 142 | #plt.title('$u_{ex}$') 143 | plt.show() 144 | 145 | #plot the error u_ex - u_comp 146 | print('u_ex - u_comp') 147 | u_pred_err = np.resize(u_pred_err, [numPredPtsX, numPredPtsY]) 148 | plt.contourf(pred_interior_x, pred_interior_y, u_pred_err, 255, cmap=plt.cm.jet) 149 | plt.colorbar() # draw colorbar 150 | #plt.title('$u_{ex}-u_{comp}$') 151 | plt.show() 152 | # 153 | # 154 | print('Loss convergence') 155 | range_adam = np.arange(1,num_train_its+1) 156 | range_lbfgs = np.arange(num_train_its+2, num_train_its+2+len(model.lbfgs_buffer)) 157 | ax0, = plt.semilogy(range_adam, model.loss_adam_buff, label='Adam') 158 | ax1, = plt.semilogy(range_lbfgs, model.lbfgs_buffer, label='L-BFGS') 159 | plt.legend(handles=[ax0,ax1]) 160 | plt.xlabel('Iteration') 161 | plt.ylabel('Loss value') 162 | plt.show() 163 | 164 | #generate interior points for evaluating the model 165 | numPredPtsX = 2*numIntPtsX-1 166 | numPredPtsY = 2*numIntPtsY-1 167 | pred_int_x, pred_int_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [0,0,0,0]) 168 | int_x = np.ndarray.flatten(pred_int_x)[np.newaxis] 169 | int_y = np.ndarray.flatten(pred_int_y)[np.newaxis] 170 | pred_X = np.concatenate((int_x.T, int_y.T), axis=1) 171 | u_pred, f_pred = model.predict(pred_X) 172 | 173 | f_val = (3*int_x.T**4 - 67*int_x.T**2 - 67*int_y.T**2 + 3*int_y.T**4 + 6*int_x.T**2*int_y.T**2 + 116)*np.sin(int_x.T)*np.sin(int_y.T) \ 174 | +(68*int_x.T - 8*int_x.T**3 - 8*int_x.T*int_y.T**2) * np.cos(int_x.T)*np.sin(int_y.T) \ 175 | +(68*int_y.T - 8*int_y.T**3 - 8*int_y.T*int_x.T**2) * np.cos(int_y.T)*np.sin(int_x.T) 176 | 177 | 178 | f_err = f_val - f_pred 179 | f_err_rel = (np.linalg.norm(f_err,2)/np.linalg.norm(f_val,2)) 180 | 181 | rel_err[i] = error_u 182 | rel_est_err[i] = f_err_rel 183 | numPts[i] = len(X_int) 184 | 185 | print('Estimated relative error f_int-f_pred: %e' % (f_err_rel)) 186 | print('f_int - f_pred') 187 | f_err_plt = np.resize(f_err, [numPredPtsY-2, numPredPtsX-2]) 188 | plt.contourf(pred_int_x, pred_int_y, f_err_plt, 255, cmap=plt.cm.jet) 189 | plt.colorbar() # draw colorbar 190 | plt.show() 191 | 192 | #pick the top N percent interior points with highest error 193 | N = 30 194 | ntop = np.int(np.round(len(f_err)*N/100)) 195 | index_f_err = np.argsort(-np.abs(f_err),axis=0) 196 | top_pred_xy = np.squeeze(pred_X[index_f_err[0:ntop-1,:]]) 197 | 198 | #generate interior values (f(x,y)) 199 | top_pred_val = np.squeeze(f_val[index_f_err[0:ntop-1,:]], axis=2) 200 | top_pred_X = np.concatenate((top_pred_xy, top_pred_val), axis=1) 201 | 202 | print(rel_err) 203 | print(rel_est_err) 204 | print(numPts) 205 | 206 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Adaptive (CMC_paper)/Poisson_SinCos_adaptive.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implement a Poisson 2D problem with Dirichlet and Neumann boundary conditions: 3 | - \Delta u(x,y) = f(x,y) for (x,y) \in \Omega:= (0,1)x(0,1) 4 | u(x,y) = 0, for x = 0 5 | du/dy = 0 for y = 0, y = 1 6 | du/dx = k*pi*cos(k*pi*x)*cos(k*pi*y) for x = 1 7 | 8 | Exact solution: u(x,y) = sin(k*pi*x)*cos(k*pi*y) corresponding to 9 | f(x,y) = 2*k^2*pi^2*sin(k*pi*x)*cos(k*pi*y) 10 | ''' 11 | 12 | import tensorflow as tf 13 | import numpy as np 14 | #import sys 15 | #print(sys.path) 16 | from utils.PoissonEqAdapt import PoissonEquationColl 17 | from utils.Geometry import QuadrilateralGeom 18 | import matplotlib.pyplot as plt 19 | import time 20 | 21 | import matplotlib as mpl 22 | mpl.rcParams['figure.dpi'] = 200 23 | 24 | print("Initializing domain...") 25 | tf.reset_default_graph() # To clear the defined variables and operations of the previous cell 26 | np.random.seed(1234) 27 | tf.set_random_seed(1234) 28 | 29 | #problem parameters 30 | alpha = 0 31 | k = 2 32 | 33 | #model paramaters 34 | layers = [2, 10, 1] #number of neurons in each layer 35 | num_train_its = 10000 #number of training iterations 36 | data_type = tf.float64 37 | pen_dir = 1 38 | pen_neu = 1 39 | 40 | numIter = 3 41 | 42 | numPts = 21 43 | numBndPts = 2*numPts 44 | numIntPtsX = numPts 45 | numIntPtsY = numPts 46 | 47 | #generate points 48 | domainCorners = np.array([[0,0],[1,0],[1,1],[0,1]]) 49 | domainGeom = QuadrilateralGeom(domainCorners) 50 | dirichlet_left_x, dirichlet_left_y, _, _ = domainGeom.getLeftPts(numBndPts) 51 | neumann_bottom_x, neumann_bottom_y, normal_bottom_x, normal_bottom_y = domainGeom.getBottomPts(numBndPts) 52 | neumann_top_x, neumann_top_y, normal_top_x, normal_top_y = domainGeom.getTopPts(numBndPts) 53 | neumann_right_x, neumann_right_y, normal_right_x, normal_right_y = domainGeom.getRightPts(numBndPts) 54 | interior_x, interior_y = domainGeom.getUnifIntPts(numIntPtsX, numIntPtsY, [0,0,0,0]) 55 | interior_x_flat = np.ndarray.flatten(interior_x)[np.newaxis] 56 | interior_y_flat = np.ndarray.flatten(interior_y)[np.newaxis] 57 | 58 | #generate boundary values 59 | dirichlet_left_u = np.zeros((numBndPts,1)) 60 | neumann_bottom_flux = np.zeros((numBndPts,1)) 61 | neumann_top_flux = np.zeros((numBndPts,1)) 62 | neumann_right_flux = k*np.pi*np.cos(k*np.pi*neumann_right_x)*np.cos(k*np.pi*neumann_right_y) 63 | 64 | #generate interior values (f(x,y)) 65 | f_val = 2*k**2*np.pi**2*np.sin(k*np.pi*interior_x_flat)*np.cos(k*np.pi*interior_y_flat) 66 | 67 | #combine points 68 | dirichlet_bnd = np.concatenate((dirichlet_left_x, dirichlet_left_y, dirichlet_left_u), axis=1) 69 | neumann_bottom_bnd = np.concatenate((neumann_bottom_x, neumann_bottom_y, 70 | normal_bottom_x, normal_bottom_y, neumann_bottom_flux), axis=1) 71 | neumann_top_bnd = np.concatenate((neumann_top_x, neumann_top_y, 72 | normal_top_x, normal_top_y, neumann_top_flux), axis=1) 73 | neumann_right_bnd = np.concatenate((neumann_right_x, neumann_right_y, 74 | normal_right_x, normal_right_y, neumann_right_flux), axis=1) 75 | neumann_bnd = np.concatenate((neumann_bottom_bnd, neumann_top_bnd, neumann_right_bnd), axis=0) 76 | X_int = np.concatenate((interior_x_flat.T, interior_y_flat.T, f_val.T), axis=1) 77 | top_pred_X = np.zeros([0,3]) 78 | 79 | #adaptivity loop 80 | 81 | rel_err = np.zeros(numIter) 82 | rel_est_err = np.zeros(numIter) 83 | numPts = np.zeros(numIter) 84 | 85 | print('Defining model...') 86 | model = PoissonEquationColl(dirichlet_bnd, neumann_bnd, alpha, layers, data_type, pen_dir, pen_neu) 87 | 88 | for i in range(numIter): 89 | 90 | #training part 91 | X_int = np.concatenate((X_int, top_pred_X)) 92 | 93 | print('Domain geometry') 94 | plt.scatter(neumann_bnd[:,0], neumann_bnd[:,1],s=0.5,c='g') 95 | plt.scatter(dirichlet_bnd[:,0], dirichlet_bnd[:,1],s=0.5,c='r') 96 | plt.scatter(X_int[:,0], X_int[:,1], s=0.5, c='b') 97 | plt.show() 98 | 99 | start_time = time.time() 100 | print('Starting training...') 101 | model.train(X_int, num_train_its) 102 | elapsed = time.time() - start_time 103 | print('Training time: %.4f' % (elapsed)) 104 | 105 | #generate points for plotting the results 106 | print('Evaluating model...') 107 | numPredPtsX = 2*numIntPtsX 108 | numPredPtsY = 2*numIntPtsY 109 | pred_x, pred_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [1,1,1,1]) 110 | pred_x_flat = np.ndarray.flatten(pred_x)[np.newaxis] 111 | pred_y_flat = np.ndarray.flatten(pred_y)[np.newaxis] 112 | pred_X = np.concatenate((pred_x_flat.T, pred_y_flat.T), axis=1) 113 | u_pred, f_pred = model.predict(pred_X) 114 | 115 | #define exact solution 116 | u_exact = np.sin(k*np.pi*pred_x_flat.T)*np.cos(k*np.pi*pred_y_flat.T) 117 | 118 | u_pred_err = u_exact-u_pred 119 | error_u = (np.linalg.norm(u_pred_err,2)/np.linalg.norm(u_exact,2)) 120 | print('Relative error u: %e' % (error_u)) 121 | 122 | # #plot the solution u_comp 123 | print('$u_{comp}$') 124 | u_pred = np.resize(u_pred, [numPredPtsY, numPredPtsX]) 125 | CS = plt.contourf(pred_x, pred_y, u_pred, 255, cmap=plt.cm.jet) 126 | plt.colorbar() # draw colorbar 127 | #plt.title('$u_{comp}$') 128 | plt.show() 129 | 130 | #plot the error u_ex 131 | print('$u_{ex}$') 132 | u_exact = np.resize(u_exact, [numPredPtsY, numPredPtsX]) 133 | plt.contourf(pred_x, pred_y, u_exact, 255, cmap=plt.cm.jet) 134 | plt.colorbar() # draw colorbar 135 | #plt.title('$u_{ex}$') 136 | plt.show() 137 | 138 | #plot the error u_ex - u_comp 139 | print('u_ex - u_comp') 140 | u_pred_err = np.resize(u_pred_err, [numPredPtsY, numPredPtsX]) 141 | plt.contourf(pred_x, pred_y, u_pred_err, 255, cmap=plt.cm.jet) 142 | plt.colorbar() # draw colorbar 143 | #plt.title('$u_{ex}-u_{comp}$') 144 | plt.show() 145 | 146 | # 147 | print('Loss convergence') 148 | range_adam = np.arange(1,num_train_its+1) 149 | range_lbfgs = np.arange(num_train_its+2, num_train_its+2+len(model.lbfgs_buffer)) 150 | ax0, = plt.semilogy(range_adam, model.loss_adam_buff, label='Adam') 151 | ax1, = plt.semilogy(range_lbfgs, model.lbfgs_buffer, label='L-BFGS') 152 | plt.legend(handles=[ax0,ax1]) 153 | plt.xlabel('Iteration') 154 | plt.ylabel('Loss value') 155 | plt.show() 156 | 157 | #generate interior points for evaluating the model 158 | numPredPtsX = 2*numIntPtsX-1 159 | numPredPtsY = 2*numIntPtsY-1 160 | pred_int_x, pred_int_y = domainGeom.getUnifIntPts(numPredPtsX, numPredPtsY, [0,0,0,0]) 161 | pred_int_x_flat = np.ndarray.flatten(pred_int_x)[np.newaxis] 162 | pred_int_y_flat = np.ndarray.flatten(pred_int_y)[np.newaxis] 163 | pred_X = np.concatenate((pred_int_x_flat.T, pred_int_y_flat.T), axis=1) 164 | u_pred, f_pred = model.predict(pred_X) 165 | 166 | f_val = 2*k**2*np.pi**2*np.sin(k*np.pi*pred_int_x_flat.T)*np.cos(k*np.pi*pred_int_y_flat.T) 167 | f_err = f_val - f_pred 168 | f_err_rel = (np.linalg.norm(f_err,2)/np.linalg.norm(f_val,2)) 169 | 170 | rel_err[i] = error_u 171 | rel_est_err[i] = f_err_rel 172 | numPts[i] = len(X_int) 173 | 174 | print('Estimated relative error f_int-f_pred: %e' % (f_err_rel)) 175 | print('f_int - f_pred') 176 | f_err_plt = np.resize(f_err, [numPredPtsY-2, numPredPtsX-2]) 177 | plt.contourf(pred_int_x, pred_int_y, f_err_plt, 255, cmap=plt.cm.jet) 178 | plt.colorbar() # draw colorbar 179 | plt.show() 180 | 181 | #pick the top N percent interior points with highest error 182 | N = 30 183 | ntop = np.int(np.round(len(f_err)*N/100)) 184 | index_f_err = np.argsort(-np.abs(f_err),axis=0) 185 | top_pred_xy = np.squeeze(pred_X[index_f_err[0:ntop-1,:]]) 186 | 187 | #generate interior values (f(x,y)) 188 | top_pred_val = np.squeeze(f_val[index_f_err[0:ntop-1,:]], axis=2) 189 | top_pred_X = np.concatenate((top_pred_xy, top_pred_val), axis=1) 190 | print('Num new points:', len(top_pred_X)) 191 | 192 | 193 | 194 | 195 | print(rel_err) 196 | print(rel_est_err) 197 | print(numPts) 198 | print('Num parameters: ', np.sum([np.prod(v.get_shape().as_list()) for v in tf.trainable_variables()])) 199 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Adaptive (CMC_paper)/README.md: -------------------------------------------------------------------------------- 1 | Adaptive collocation code based for the examples in https://doi.org/10.32604/cmc.2019.06641 2 | 3 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Elastodynamics/Wave1D.py: -------------------------------------------------------------------------------- 1 | """ 2 | script for wave equation in 1D with Neumann boundary conditions at left end 3 | Governing equation: u_tt(x,t) = u_xx(x,t) for x \in (0,1), u(0)=u(1)=0 4 | Exact solution u(x,t) = 2\alpha/pi for x<\alpha*(t-1) 5 | = \alpha/pi*[1-cos(pi*(t-x/alpha))], for \alpha(t-1)<=x<=alpha*t 6 | = 0 for \alpha*t < x 7 | which satisfies the inital and Neumann boundary conditions: 8 | u(x,0) = 0 9 | u_t(x,0) = 0 10 | u_x(0,t) = -sin(pi*t) for 0<=t<=1 11 | = 0 for 1