├── tf1 ├── tensorflow_DEM │ ├── cube_with_hole.mat │ ├── readme.md │ ├── gaussPtsCubeWithHole.mat │ ├── gaussPtsHollowSphere.mat │ ├── Elasticity │ │ ├── cube_with_hole.mat │ │ ├── readme.md │ │ ├── utils │ │ │ └── gridPlot.py │ │ └── HollowSphere.py │ ├── gaussPtsBoundCubeWithHole.mat │ ├── gaussPtsBoundHollowSphere.mat │ └── Phase Field │ │ └── TensilePlate.py └── tensorflow_collocation │ ├── Adaptive (CMC_paper) │ ├── README.md │ ├── Poisson_SinCos_adaptive.py │ ├── Poisson_Annulus_adaptive.py │ └── AcousticDuct_adaptive.py │ ├── README.md │ ├── Elastodynamics │ ├── utils │ │ ├── gridPlot.py │ │ └── PINN_wave.py │ └── Wave1D.py │ └── Poisson │ ├── Poisson1D_DD.py │ └── Poisson1D_DD_tb_FP64.py ├── tf2 ├── README.md ├── utils │ ├── scipy_loss.py │ ├── tfp_loss.py │ ├── Plotting.py │ └── Geom_examples.py ├── Interpolate.py ├── Poisson2D_Dirichlet_SinCos.py ├── Poisson2D_Dirichlet_Circle.py ├── Poisson2D_Dirichlet.py ├── Poisson2D_Dirichlet_DEM.py ├── Poisson.py ├── Poisson_Neumann.py ├── Poisson_mixed.py ├── Wave1D.py ├── Helmholtz2D_Acoustic_Duct.py ├── Poisson_DEM.py ├── Poisson_DEM_adaptive.py ├── Poisson_Neumann_DEM.py ├── TimonshenkoBeam_DEM.py └── ThickCylinder_DEM.py ├── .gitignore ├── README.md └── LICENSE /tf1/tensorflow_DEM/cube_with_hole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/tf1/tensorflow_DEM/cube_with_hole.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_DEM/gaussPtsCubeWithHole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/tf1/tensorflow_DEM/gaussPtsCubeWithHole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsHollowSphere.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/tf1/tensorflow_DEM/gaussPtsHollowSphere.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/Elasticity/cube_with_hole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/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/gaussPtsBoundCubeWithHole.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/tf1/tensorflow_DEM/gaussPtsBoundCubeWithHole.mat -------------------------------------------------------------------------------- /tf1/tensorflow_DEM/gaussPtsBoundHollowSphere.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ISM-Weimar/DeepEnergyMethods/HEAD/tf1/tensorflow_DEM/gaussPtsBoundHollowSphere.mat -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tf2/README.md: -------------------------------------------------------------------------------- 1 | This directory contains solvers which are compatible with Tensorflow 2. 2 | 3 | Dependencies: Tensorflow 2, tensorflow-probability, geomdl, matplotlib 4 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/README.md: -------------------------------------------------------------------------------- 1 | Collocation code based on an extension of Physics Informed Neural Networks ( https://github.com/maziarraissi/PINNs ). 2 | 3 | Requires Tensorflow and pyDOE 4 | 5 | ### Recommended steps for running the collocation code using tensorflow with CPU support: 6 | 7 | 1. Install Anaconda Python 3 branch by downloading it from https://www.anaconda.com/download/ 8 | If you already have an older version of Anaconda installed, it might be a good idea to update it by typing `conda update --all` at the “Anaconda prompt” or uninstall and reinstall it. You can leave the default options which do not require administrator access. 9 | 10 | 2. Open the Anaconda Prompt from the Start Menu on Windows or by typing `conda activate base` on Linux. 11 | 12 | 3. (Optional) Create a tensorflow environment named tf. The command to create the environment and install tensorflow and its dependencies is: 13 | `conda create --name tf tensorflow` 14 | 15 | For Tensorflow 1.15, use the command 16 | `conda create --name tf tensorflow=1.15` 17 | 18 | 19 | 4. (Optional) Activate the tensorflow environment with the command: 20 | `conda activate tf` 21 | 22 | 5. Install the spyder IDE and some additional packages: 23 | ``` 24 | conda install spyder 25 | conda install matplotlib 26 | conda install -c conda-forge pydoe 27 | ``` 28 | Note: Although spyder and matplotlib are installed already in the base environment, they should be installed and run from the "tf" environment to ensure that they work correctly with programs which use tensorflow. 29 | 30 | 6. Start spyder from the Anaconda prompt: 31 | `spyder` 32 | 33 | 7. Open the file you would like to run e.g. `(…)DeepEnergyMethods/tensorflow_collocation/Poisson/Poisson2D_Dirichlet.py` and run it in the current console with the Green arrow button in the toolbar or by pressing F5 34 | 35 | For subsequent runs, you can of course skip the steps 1, 3, and 5. 36 | -------------------------------------------------------------------------------- /tf2/utils/scipy_loss.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Fri Sep 11 15:50:38 2020 5 | 6 | @author: cosmin 7 | """ 8 | import tensorflow as tf 9 | import numpy as np 10 | 11 | def scipy_function_factory(model, *args): 12 | """A factory to create a function required by scipy.opimizer. 13 | Based on the example from https://stackoverflow.com/questions/59029854/use-scipy-optimizer-with-tensorflow-2-0-for-neural-network-training 14 | Args: 15 | model [in]: an instance of `tf.keras.Model` or its subclasses. 16 | *args: arguments to be passed to model.get_grads method 17 | 18 | Returns: 19 | A function that has a signature of: 20 | loss_value, gradients = f(model_parameters). 21 | """ 22 | 23 | # obtain the shapes of all trainable parameters in the model 24 | shapes = tf.shape_n(model.trainable_variables) 25 | n_tensors = len(shapes) 26 | 27 | # we'll use tf.dynamic_stitch and tf.dynamic_partition later, so we need to 28 | # prepare required information first 29 | count = 0 30 | idx = [] # stitch indices 31 | part = [] # partition indices 32 | 33 | for i, shape in enumerate(shapes): 34 | n = np.product(shape) 35 | idx.append(tf.reshape(tf.range(count, count+n, dtype=tf.int32), shape)) 36 | part.extend([i]*n) 37 | count += n 38 | 39 | part = tf.constant(part) 40 | 41 | def assign_new_model_parameters(params_1d): 42 | """A function updating the model's parameters with a 1D tf.Tensor. 43 | 44 | Args: 45 | params_1d [in]: a 1D tf.Tensor representing the model's trainable parameters. 46 | """ 47 | 48 | params = tf.dynamic_partition(params_1d, part, n_tensors) 49 | for i, (shape, param) in enumerate(zip(shapes, params)): 50 | model.trainable_variables[i].assign(tf.reshape(param, shape)) 51 | 52 | # now create a function that will be returned by this factory 53 | def f(params_1d): 54 | """A function that can be used by tfp.optimizer.lbfgs_minimize. 55 | 56 | This function is created by function_factory. 57 | 58 | Args: 59 | params_1d [in]: a 1D tf.Tensor. 60 | 61 | Returns: 62 | A scalar loss and the gradients w.r.t. the `params_1d`. 63 | """ 64 | assign_new_model_parameters(params_1d) 65 | loss_value, grads = model.get_grad(*args) 66 | grads = tf.dynamic_stitch(idx, grads) 67 | 68 | # print out iteration & loss 69 | f.iter.assign_add(1) 70 | if f.iter%model.print_epoch == 0: 71 | tf.print("Iter:", f.iter, "loss:", loss_value) 72 | 73 | return loss_value.numpy(), grads.numpy() 74 | 75 | # store these information as members so we can use them outside the scope 76 | f.iter = tf.Variable(0) 77 | f.idx = idx 78 | f.part = part 79 | f.shapes = shapes 80 | f.assign_new_model_parameters = assign_new_model_parameters 81 | 82 | return f -------------------------------------------------------------------------------- /tf2/utils/tfp_loss.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Fri Sep 11 15:50:38 2020 5 | 6 | @author: cosmin 7 | """ 8 | import tensorflow as tf 9 | import numpy as np 10 | 11 | def tfp_function_factory(model, *args): 12 | """A factory to create a function required by tfp.optimizer.lbfgs_minimize. 13 | Based on the example from https://pychao.com/2019/11/02/optimize-tensorflow-keras-models-with-l-bfgs-from-tensorflow-probability/ 14 | Args: 15 | model [in]: an instance of `tf.keras.Model` or its subclasses. 16 | *args: arguments to be passed to model.get_grads method 17 | 18 | Returns: 19 | A function that has a signature of: 20 | loss_value, gradients = f(model_parameters). 21 | """ 22 | 23 | # obtain the shapes of all trainable parameters in the model 24 | shapes = tf.shape_n(model.trainable_variables) 25 | n_tensors = len(shapes) 26 | 27 | # we'll use tf.dynamic_stitch and tf.dynamic_partition later, so we need to 28 | # prepare required information first 29 | count = 0 30 | idx = [] # stitch indices 31 | part = [] # partition indices 32 | 33 | for i, shape in enumerate(shapes): 34 | n = np.prod(shape) 35 | idx.append(tf.reshape(tf.range(count, count+n, dtype=tf.int32), shape)) 36 | part.extend([i]*n) 37 | count += n 38 | 39 | part = tf.constant(part) 40 | @tf.function 41 | def assign_new_model_parameters(params_1d): 42 | """A function updating the model's parameters with a 1D tf.Tensor. 43 | 44 | Args: 45 | params_1d [in]: a 1D tf.Tensor representing the model's trainable parameters. 46 | """ 47 | 48 | params = tf.dynamic_partition(params_1d, part, n_tensors) 49 | for i, (shape, param) in enumerate(zip(shapes, params)): 50 | model.trainable_variables[i].assign(tf.reshape(param, shape)) 51 | 52 | # now create a function that will be returned by this factory 53 | @tf.function 54 | def f(params_1d): 55 | """A function that can be used by tfp.optimizer.lbfgs_minimize. 56 | 57 | This function is created by function_factory. 58 | 59 | Args: 60 | params_1d [in]: a 1D tf.Tensor. 61 | 62 | Returns: 63 | A scalar loss and the gradients w.r.t. the `params_1d`. 64 | """ 65 | assign_new_model_parameters(params_1d) 66 | loss_value, grads = model.get_grad(*args) 67 | grads = tf.dynamic_stitch(idx, grads) 68 | 69 | # print out iteration & loss 70 | f.iter.assign_add(1) 71 | if f.iter%model.print_epoch == 0: 72 | tf.print("Iter:", f.iter, "loss:", loss_value) 73 | # store loss value so we can retrieve later 74 | tf.py_function(f.history.append, inp=[loss_value], Tout=[]) 75 | return loss_value, grads 76 | 77 | # store these information as members so we can use them outside the scope 78 | f.iter = tf.Variable(0) 79 | f.idx = idx 80 | f.part = part 81 | f.shapes = shapes 82 | f.assign_new_model_parameters = assign_new_model_parameters 83 | f.history = [] 84 | 85 | return f -------------------------------------------------------------------------------- /tf1/tensorflow_collocation/Elastodynamics/utils/gridPlot.py: -------------------------------------------------------------------------------- 1 | import os 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | 6 | def createFolder(folder_name): 7 | try: 8 | if not os.path.exists(folder_name): 9 | os.makedirs(folder_name) 10 | except OSError: 11 | print ('Error: Creating folder. ' + folder_name) 12 | 13 | def plot1d(u_pred_err,X_star,u_pred,u_exact,v_pred,v_exact,v_pred_err,figHeight,figWidth): 14 | 15 | filename = 'disp_err' 16 | plt.figure(figsize=(figWidth, figHeight)) 17 | plt.plot(X_star, 100*u_pred_err, c='b', linewidth=2.0) 18 | #plt.title('$\phi_{comp}$ and $\phi_{exact}$') 19 | plt.xticks(fontsize=12) 20 | plt.yticks(fontsize=12) 21 | plt.xlabel('x',fontweight='bold',fontsize=14) 22 | plt.ylabel('Relative $\%$ error in displacement',fontweight='bold',fontsize=14) 23 | plt.tight_layout() 24 | plt.savefig(filename +".pdf", dpi=700, facecolor='w', edgecolor='w', 25 | transparent = 'true', bbox_inches = 'tight') 26 | plt.show() 27 | plt.close() 28 | 29 | filename = 'disp' 30 | plt.figure(figsize=(figWidth, figHeight)) 31 | ax0, = plt.plot(X_star,u_pred, label='$u_{comp}$', c='b', linewidth=2.0) 32 | ax1, = plt.plot(X_star,u_exact, label='$u_{exact}$', c='r',linewidth=2.0) 33 | plt.legend(handles=[ax0,ax1],fontsize=14) 34 | #plt.title('$\phi_{comp}$ and $\phi_{exact}$') 35 | plt.xticks(fontsize=12) 36 | plt.yticks(fontsize=12) 37 | plt.xlabel('x',fontweight='bold',fontsize=14) 38 | plt.ylabel('Displacement',fontweight='bold',fontsize=14) 39 | plt.tight_layout() 40 | plt.savefig(filename +".pdf", dpi=700, facecolor='w', edgecolor='w', 41 | transparent = 'true', bbox_inches = 'tight') 42 | plt.show() 43 | plt.close() 44 | 45 | filename = 'velocity' 46 | plt.figure(figsize=(figWidth, figHeight)) 47 | ax0, = plt.plot(X_star,v_pred, label='$v_{comp}$', c='b', linewidth=2.0) 48 | ax1, = plt.plot(X_star,v_exact, label='$v_{exact}$', c='r',linewidth=2.0) 49 | plt.legend(handles=[ax0,ax1],fontsize=14) 50 | #plt.title('$\phi_{comp}$ and $\phi_{exact}$') 51 | plt.xticks(fontsize=12) 52 | plt.yticks(fontsize=12) 53 | plt.xlabel('x',fontweight='bold',fontsize=14) 54 | plt.ylabel('Velocity',fontweight='bold',fontsize=14) 55 | plt.tight_layout() 56 | plt.savefig(filename +".pdf", dpi=700, facecolor='w', edgecolor='w', 57 | transparent = 'true', bbox_inches = 'tight') 58 | plt.show() 59 | plt.close() 60 | 61 | filename = 'vel_err' 62 | plt.figure(figsize=(figWidth, figHeight)) 63 | plt.plot(X_star, 100*v_pred_err, c='b', linewidth=2.0) 64 | #plt.title('$\phi_{comp}$ and $\phi_{exact}$') 65 | plt.xticks(fontsize=12) 66 | plt.yticks(fontsize=12) 67 | plt.xlabel('x',fontweight='bold',fontsize=14) 68 | plt.ylabel('Relative $\%$ error in velocity',fontweight='bold',fontsize=14) 69 | plt.tight_layout() 70 | plt.savefig(filename +".pdf", dpi=700, facecolor='w', edgecolor='w', 71 | transparent = 'true', bbox_inches = 'tight') 72 | plt.show() 73 | plt.close() 74 | 75 | def plotConvergence(iter,adam_buff,lbfgs_buff,figHeight,figWidth): 76 | 77 | filename = "convergence" 78 | plt.figure(figsize=(figWidth, figHeight)) 79 | range_adam = np.arange(1,iter+1) 80 | range_lbfgs = np.arange(iter+2, iter+2+len(lbfgs_buff)) 81 | ax0, = plt.semilogy(range_adam, adam_buff, c='b', label='Adam',linewidth=2.0) 82 | ax1, = plt.semilogy(range_lbfgs, lbfgs_buff, c='r', label='L-BFGS',linewidth=2.0) 83 | plt.legend(handles=[ax0,ax1],fontsize=14) 84 | plt.xticks(fontsize=12) 85 | plt.yticks(fontsize=12) 86 | plt.xlabel('Iteration',fontweight='bold',fontsize=14) 87 | plt.ylabel('Loss value',fontweight='bold',fontsize=14) 88 | plt.tight_layout() 89 | plt.savefig(filename +".pdf", dpi=700, facecolor='w', edgecolor='w', 90 | transparent = 'true', bbox_inches = 'tight') 91 | plt.show() 92 | plt.close() 93 | 94 | -------------------------------------------------------------------------------- /tf2/Interpolate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Interpolation example 5 | Inpterpolates the function given by exact_sol(x) at a discrete set of points 6 | Created on Fri Sep 11 15:57:07 2020 7 | 8 | @author: cosmin 9 | """ 10 | import tensorflow as tf 11 | import numpy as np 12 | import tensorflow_probability as tfp 13 | import matplotlib.pyplot as plt 14 | 15 | from utils.tfp_loss import tfp_function_factory 16 | from utils.Plotting import plot_convergence_semilog 17 | 18 | tf.random.set_seed(42) 19 | 20 | class model(tf.keras.Model): 21 | def __init__(self, layers, train_op, num_epoch, print_epoch): 22 | super(model, self).__init__() 23 | self.model_layers = layers 24 | self.train_op = train_op 25 | self.num_epoch = num_epoch 26 | self.print_epoch = print_epoch 27 | self.adam_loss_hist = [] 28 | 29 | def call(self, X): 30 | return self.u(X) 31 | 32 | # Running the model 33 | def u(self,X): 34 | for l in self.model_layers: 35 | X = l(X) 36 | return X 37 | 38 | # Return the first derivative 39 | def du(self, X): 40 | with tf.GradientTape() as tape: 41 | tape.watch(X) 42 | u_val = self.u(X) 43 | du_val = tape.gradient(u_val, X) 44 | return du_val 45 | 46 | #Custom loss function 47 | def get_loss(self,Xint, Yint): 48 | u_val_int=self.u(Xint) 49 | int_loss = tf.reduce_mean(tf.math.square(u_val_int - Yint)) 50 | return int_loss 51 | 52 | # get gradients 53 | def get_grad(self, Xint, Yint): 54 | with tf.GradientTape() as tape: 55 | tape.watch(self.trainable_variables) 56 | L = self.get_loss(Xint, Yint) 57 | g = tape.gradient(L, self.trainable_variables) 58 | return L, g 59 | 60 | # perform gradient descent 61 | def network_learn(self,Xint,Yint): 62 | for i in range(self.num_epoch): 63 | L, g = self.get_grad(Xint, Yint) 64 | self.train_op.apply_gradients(zip(g, self.trainable_variables)) 65 | self.adam_loss_hist.append(L) 66 | if i%self.print_epoch==0: 67 | print("Epoch {} loss: {}".format(i, L)) 68 | 69 | 70 | 71 | #define the function ot be interpolated 72 | k = 4 73 | def exact_sol(input): 74 | output = np.sin(k*np.pi*input) 75 | return output 76 | 77 | #define the input and output data set 78 | xmin = -1 79 | xmax = 1 80 | numPts = 201 81 | data_type = "float64" 82 | 83 | Xint = np.linspace(xmin, xmax, numPts).astype(data_type) 84 | Xint = np.array(Xint)[np.newaxis].T 85 | Yint = exact_sol(Xint) 86 | 87 | #define the model 88 | tf.keras.backend.set_floatx(data_type) 89 | l1 = tf.keras.layers.Dense(64, "tanh") 90 | l2 = tf.keras.layers.Dense(64, "tanh") 91 | l3 = tf.keras.layers.Dense(1, None) 92 | train_op = tf.keras.optimizers.Adam() 93 | num_epoch = 10000 94 | print_epoch = 100 95 | pred_model = model([l1, l2, l3], train_op, num_epoch, print_epoch) 96 | 97 | #convert the training data to tensors 98 | Xint_tf = tf.convert_to_tensor(Xint) 99 | Yint_tf = tf.convert_to_tensor(Yint) 100 | 101 | #training 102 | print("Training (ADAM)...") 103 | pred_model.network_learn(Xint_tf, Yint_tf) 104 | print("Training (LBFGS)...") 105 | loss_func = tfp_function_factory(pred_model, Xint_tf, Yint_tf) 106 | # convert initial model parameters to a 1D tf.Tensor 107 | init_params = tf.dynamic_stitch(loss_func.idx, pred_model.trainable_variables) 108 | # train the model with L-BFGS solver 109 | results = tfp.optimizer.lbfgs_minimize( 110 | value_and_gradients_function=loss_func, initial_position=init_params, 111 | max_iterations=4000, num_correction_pairs=50, tolerance=1e-14) 112 | # after training, the final optimized parameters are still in results.position 113 | # so we have to manually put them back to the model 114 | loss_func.assign_new_model_parameters(results.position) 115 | 116 | print("Testing...") 117 | numPtsTest = 2*numPts 118 | x_test = np.linspace(xmin, xmax, numPtsTest) 119 | x_test = np.array(x_test)[np.newaxis].T 120 | x_tf = tf.convert_to_tensor(x_test) 121 | 122 | y_test = pred_model.u(x_tf) 123 | y_exact = exact_sol(x_test) 124 | 125 | plt.plot(x_test, y_test, x_test, y_exact) 126 | plt.show() 127 | plt.plot(x_test, y_exact-y_test) 128 | plt.title("Error") 129 | plt.show() 130 | err = y_exact - y_test 131 | print("L2-error norm: {}".format(np.linalg.norm(err)/np.linalg.norm(y_exact))) 132 | 133 | # plot the loss convergence 134 | plot_convergence_semilog(pred_model.adam_loss_hist, loss_func.history) 135 | -------------------------------------------------------------------------------- /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