This code used to run in the notebook: no longer

Now I get nothing: no message, nothing. (I ran it in a notebook at https://jupyter.org/try-jupyter/.)

# Finite Element Modeling with Abaqus and Python for Thermal and
# Stress Analysis
# (C)  2017-2020, Petr Krysl
#
"""
Square domain with partial temperature boundary condition
and partial insulated boundary condition.  Finite element mesh
that consists of four-node quadrilaterals.
 """

import math
from numpy import array, zeros, ones, arange, linspace
from numpy import unique, dot, linalg
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

import time

tstart = time.time() 

# Input parameters
kappa = 0.2 # thermal conductivity
Q = 0.005 # uniform heat source
sidel = 48 # length of the side of the square domain
nes = 18 # number of elements per side
Dz = 1.0  # thickness of the slice

# Generate the nodes and the connectivities of the quadrilaterals
xs = linspace(0, sidel, nes+1) # grid in the X direction
ys = linspace(0, sidel, nes+1) # grid in the Y direction
nx = len(xs) - 1 # number of element edges in the X direction
ny = len(ys) - 1 # number of element edges in the Y direction
nnodes = (nx+1) * (ny+1) # Number of nodes
nfes = nx * ny # Number of elements

# Generate the nodes
x = zeros((nnodes, 2)) # Coordinates of nodes: initialized to all zeros
k = 0
for j  in arange(0, (ny+1)):
    for i  in arange(0, (nx+1)):
        x[k, :] = [xs[i], ys[j]]
        k = k + 1

# Generate the elements: note that the nodes are numbered from 1
conn = zeros((nfes, 4), dtype=int)
k = 0
for i  in arange(0, (nx)):
    for j  in arange(0, (ny)):
        f = int(j * (nx+1) + i) + 1
        conn[k, :] = [f, f+1, f+(nx+1)+1, f+(nx+1)]
        k = k + 1

# Define the degrees of freedom
# Fixed temperature at the nodes on the boundary, except for a few
# in the lower-left corner.  The  node numbers are one-based
Fixed = [int(i)+1 for i in arange(nx/2, nx+1)]
Fixed = Fixed + [int(j*(nx+1))+1 for j in arange(ny/2, ny+1)]
Fixed = Fixed + [int(i+ny*(nx+1))+1 for i in arange(0, nx+1)]
Fixed = Fixed + [int(j*(nx+1)+ny)+1 for j in arange(0, ny+1)]
Fixed = unique(Fixed)

dof = zeros((nnodes,1), dtype=int)
N_f = nnodes - len(Fixed) # number of free degrees of freedom
N_t = nnodes # total number of degrees of freedom

T = zeros((nnodes,1)) # vector of degrees of freedom

# Number the degrees of freedom: First we will number the prescribed 
# degrees of freedom starting from the number of free degrees of freedom
k = N_f # first we number the prescribed degrees of freedom
for index  in Fixed:
    dof[index-1] = k+1 # the DOF are 1-based
    k = k + 1
k = 0 # next we number the free degrees of freedom  
for index  in range(0, nnodes):
    if (dof[index] == 0): 
        dof[index] = k+1 # the DOF are 1-based
        k = k + 1

    
def gradNpar(xi, eta):
    """
    A one-liner to calculate the matrix of the basis function gradients
    in the parametric coordinates.
    """
    return array([
        [eta / 4 - 1. / 4, xi / 4 - 1. / 4],
        [1. / 4 - eta / 4, - xi / 4 - 1. / 4],
        [eta / 4 + 1. / 4, xi / 4 + 1. / 4],
        [- eta / 4 - 1. / 4, 1. / 4 - xi / 4]])
 
def N(xi, eta):
    """
    A one-liner to calculate the matrix of the basis function values.
    """
    return array([(xi - 1) * (eta - 1) / 4,
                  (xi + 1) * (eta - 1) / -4,
                  (xi + 1) * (eta + 1) / 4,
                  (xi - 1) * (eta + 1) / -4]).reshape(4, 1)
 
# These are the integration point data for four-point quadrature rule
xe = array([[-0.577350269189626, -0.577350269189626],
            [-0.577350269189626, +0.577350269189626],
            [+0.577350269189626, -0.577350269189626],
            [+0.577350269189626, +0.577350269189626]])
W = array([1, 1, 1, 1])

# These are the integration point data for one-point quadrature rule
#xe = array([[+0., +0]])
#W = array([4.0])

K = zeros((N_f, N_t))
L = zeros((N_f, 1))
 
nnpe = conn.shape[1] # number of nodes per element
zconn = conn - 1
for index  in arange(conn.shape[0]):
    # Element degree-of-freedom array,  converted to zero base
    zedof = dof[zconn[index, :]]-1
    # Initialize the elementwise conductivity matrix.
    Ke = zeros((nnpe, nnpe))
    # Initialize the elementwise heat load vector   
    LQe = zeros((nnpe, 1))
    # Loop over the quadrature points.
    for qp in range(xe.shape[0]):
        xi, eta = xe[qp, 0], xe[qp, 1]
        lx = x[zconn[index, :], :]
        # Compute the Jacobian matrix
        J = dot(lx.T, gradNpar(xi, eta))
        # The Jacobian
        detJ = linalg.det(J)
        # The  gradient  of the basis functions with respect to x,y
        gradN = dot(gradNpar(xi, eta), linalg.inv(J))
        # Add the contribution to the conductivity matrix
        Ke = Ke + kappa * Dz * dot(gradN, gradN.T) * detJ * W[qp]
        # At the contribution to the elementwise heat load vector
        LQe = LQe + Q * Dz * N(xi, eta) * ones((nnpe, 1)) * detJ * W[qp]
    # Assemble elementwise conductivity matrix
    for ro  in range(len(zedof)):
        for co  in range(len(zedof)):
            if (zedof[ro] < N_f):
                K[zedof[ro], zedof[co]] = K[zedof[ro], zedof[co]] + Ke[ro, co]
    # Assemble the elementwise heat load vector   
    for ro  in range(len(zedof)):
        if (zedof[ro] < N_f):
            L[zedof[ro]] = L[zedof[ro]] + LQe[ro]   

# Solve for the global temperatures at the free degrees of freedom
T[0:N_f] = linalg.solve(K[0:N_f, 0:N_f], L)

tend = time.time() 
print( 'Time =', tend-tstart)

if (len(T) < 10):
    print('Tg=', Tg)

# Plot contours
plt.figure()
plt.gca().set_aspect('equal')
# setup three 1-d arrays for the x-coordinate, the y-coordinate, and the
# z-coordinate
xs = x[:, 0].reshape(nnodes,)  # one value per node
ys = x[:, 1].reshape(nnodes,)  # one value per node
ix = dof[arange(nnodes)] - 1
zs = (T[ix]).reshape(nnodes,)  # one value per node
triangles = conn[:, (0, 1, 2)] - 1  # the triangles are defined by the connectivity arrays
plt.tricontour(xs, ys, triangles, zs, linewidths=3)
triangles = conn[:, (0, 2, 3)] - 1  # the triangles are defined by the connectivity arrays
plt.tricontour(xs, ys, triangles, zs, linewidths=3)
plt.colorbar()
plt.title('Contour plot of temperature')
plt.xlabel('x (m)')
plt.ylabel('y (m)')
plt.show()

Can anyone explain it? This code runs fine in Spyder on Win 11.

Works fine on my end (in my own lab and on jupyter.org’s jupyterlite you’ve linked).

2 Likes

Weird. Same browser (Edge) on a different computer runs it. Go figure.

Thanks for checking!

1 Like