def translate_nodes_ABAQUS_c0(m0, n0, c0, funcnum, model_name, part_name, H_model, semi_angle=0., scaling_factor=1., fem_meridian_bot2top=True, ignore_bot_h=None, ignore_top_h=None, T=None): r"""Translates the nodes in Abaqus based on a Fourier series The Fourier Series can be a half-sine, half-cosine or a complete Fourier Series as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`. Parameters ---------- m0 : int Number of terms along the `x` coordinate. n0 : int Number of terms along the `\theta` coordinate. c0 : numpy.ndarray The coefficients that will give the imperfection pattern. funcnum : int The function type, as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`. model_name : str Must be a valid key in the dictionary ``mdb.models``, in the interactive Python inside Abaqus. part_name : str Must be a valid key in the dictionary ``mdb.models[model_name].parts``, in the interactive Python inside Abaqus. H_model : float Total height of the model where the imperfections will be applied to, considering also eventual resin rings. semi_angle : float, optional The cone semi-vertex angle (a null value indicates that a cylinder is beeing analyzed). scaling_factor : float, optional The scaling factor that will multiply ``c0`` when applying the imperfections. fem_meridian_bot2top : bool, optional A boolean indicating if the finite element has the `x` axis starting at the bottom or at the top. ignore_bot_h : None or float, optional Used to ignore nodes from the bottom resin ring. ignore_top_h : None or float, optional Used to ignore nodes from the top resin ring. T : None or np.ndarray, optional A transformation matrix (cf. :func:`.transf_matrix`) required when the mesh is not in the :ref:`default coordinate system <figure_conecyl>`. Returns ------- nodal_translations : numpy.ndarray A 2-D array containing the translations ``x, y, z`` for each column. Notes ----- Despite the nodal traslations are returned all the nodes belonging to this model will be already translated. """ from abaqus import mdb, session from desicos.conecylDB import fit_data log('Calculating imperfection amplitudes for model {0} ...\n\t'.format( model_name) + '(using a scaling factor of {0})'.format(scaling_factor)) c0 = c0 * scaling_factor mod = mdb.models[model_name] part = mod.parts[part_name] part_nodes = np.array(part.nodes) coords = np.array([n.coordinates for n in part_nodes]) if T is not None: tmp = np.vstack((coords.T, np.ones((1, coords.shape[0])))) coords = np.dot(T, tmp).T del tmp if ignore_bot_h is not None: if ignore_bot_h <= 0: ignore_bot_h = None else: log('Applying ignore_bot_h: ignoring nodes with z <= {0}'.format( ignore_bot_h)) mask = coords[:, 2] > ignore_bot_h coords = coords[mask] part_nodes = part_nodes[mask] if ignore_top_h is not None: if ignore_top_h <= 0: ignore_top_h = None else: log('Applying ignore_top_h: ignoring nodes with z >= {0}'.format( H_model - ignore_top_h)) mask = coords[:, 2] < (H_model - ignore_top_h) coords = coords[mask] part_nodes = part_nodes[mask] if ignore_bot_h is None: ignore_bot_h = 0 if ignore_top_h is None: ignore_top_h = 0 H_eff = H_model - (ignore_bot_h + ignore_top_h) if fem_meridian_bot2top: xs_norm = (coords[:, 2] - ignore_bot_h) / H_eff else: xs_norm = (H_eff - (coords[:, 2] - ignore_bot_h)) / H_eff thetas = arctan2(coords[:, 1], coords[:, 0]) alpharad = deg2rad(semi_angle) w0 = fit_data.fw0(m0, n0, c0, xs_norm, thetas, funcnum) nodal_translations = np.zeros_like(coords) nodal_translations[:, 0] = w0 * cos(alpharad) * cos(thetas) nodal_translations[:, 1] = w0 * cos(alpharad) * sin(thetas) nodal_translations[:, 2] = w0 * sin(alpharad) log('Calculation of imperfection amplitudes finished!') # applying translations viewport = session.viewports[session.currentViewportName] log('Applying new nodal positions in ABAQUS CAE to model {0} ...'.format( model_name)) log(' (using a scaling factor of {0})'.format(scaling_factor)) new_coords = coords + nodal_translations if T is not None: Tinv = np.zeros_like(T) Tinv[:3, :3] = T[:3, :3].T Tinv[:, 3] = -T[:, 3] tmp = np.vstack((new_coords.T, np.ones((1, new_coords.shape[0])))) new_coords = np.dot(Tinv, tmp).T del tmp meshNodeArray = part.nodes.sequenceFromLabels( [n.label for n in part_nodes]) new_coords = np.ascontiguousarray(new_coords) part.editNode(nodes=meshNodeArray, coordinates=new_coords) log('Application of new nodal positions finished!') ra = mod.rootAssembly viewport.setValues(displayedObject=ra) ra.regenerate() return nodal_translations
from desicos.conecylDB.fit_data import fw0 ntheta = 420 nz = 180 funcnum = 2 path = 'degenhardt_2010_z25_msi_theta_z_imp.txt' theta = linspace(-pi, pi, ntheta) z = linspace(0., 1., nz) theta, z = meshgrid(theta, z, copy=False) for m0, n0 in [[20, 30], [30, 45], [40, 60], [50, 75]]: c, residues = calc_c0(path, m0=m0, n0=n0, sample_size=(10*2*m*n), funcnum=funcnum) w0 = fw0(m0, n0, z.ravel(), theta.ravel(), funcnum=funcnum) plt.figure(figsize=(3.5, 2)) levels = np.linspace(w0.min(), w0.max(), 400) plt.contourf(theta, z*H_measured, w0.reshape(theta.shape), levels=levels) ax = plt.gca() ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.xaxis.set_ticks([-pi, pi]) ax.xaxis.set_ticklabels([r'$-\pi$', r'$\pi$'])
def translate_nodes_ABAQUS_c0(m0, n0, c0, funcnum, model_name, part_name, H_model, semi_angle=0., scaling_factor=1., fem_meridian_bot2top=True, ignore_bot_h=None, ignore_top_h=None, T=None): r"""Translates the nodes in Abaqus based on a Fourier series The Fourier Series can be a half-sine, half-cosine or a complete Fourier Series as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`. Parameters ---------- m0 : int Number of terms along the `x` coordinate. n0 : int Number of terms along the `\theta` coordinate. c0 : numpy.ndarray The coefficients that will give the imperfection pattern. funcnum : int The function type, as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`. model_name : str Must be a valid key in the dictionary ``mdb.models``, in the interactive Python inside Abaqus. part_name : str Must be a valid key in the dictionary ``mdb.models[model_name].parts``, in the interactive Python inside Abaqus. H_model : float Total height of the model where the imperfections will be applied to, considering also eventual resin rings. semi_angle : float, optional The cone semi-vertex angle (a null value indicates that a cylinder is beeing analyzed). scaling_factor : float, optional The scaling factor that will multiply ``c0`` when applying the imperfections. fem_meridian_bot2top : bool, optional A boolean indicating if the finite element has the `x` axis starting at the bottom or at the top. ignore_bot_h : None or float, optional Used to ignore nodes from the bottom resin ring. ignore_top_h : None or float, optional Used to ignore nodes from the top resin ring. T : None or np.ndarray, optional A transformation matrix (cf. :func:`.transf_matrix`) required when the mesh is not in the :ref:`default coordinate system <figure_conecyl>`. Returns ------- nodal_translations : numpy.ndarray A 2-D array containing the translations ``x, y, z`` for each column. Notes ----- Despite the nodal traslations are returned all the nodes belonging to this model will be already translated. """ from abaqus import mdb, session from desicos.conecylDB import fit_data log('Calculating imperfection amplitudes for model {0} ...\n\t'. format(model_name) + '(using a scaling factor of {0})'.format(scaling_factor)) c0 = c0*scaling_factor mod = mdb.models[model_name] part = mod.parts[part_name] part_nodes = np.array(part.nodes) coords = np.array([n.coordinates for n in part_nodes]) if T is not None: tmp = np.vstack((coords.T, np.ones((1, coords.shape[0])))) coords = np.dot(T, tmp).T del tmp if ignore_bot_h is not None: if ignore_bot_h <= 0: ignore_bot_h = None else: log('Applying ignore_bot_h: ignoring nodes with z <= {0}'.format( ignore_bot_h)) mask = coords[:, 2] > ignore_bot_h coords = coords[mask] part_nodes = part_nodes[mask] if ignore_top_h is not None: if ignore_top_h <= 0: ignore_top_h = None else: log('Applying ignore_top_h: ignoring nodes with z >= {0}'.format( H_model - ignore_top_h)) mask = coords[:, 2] < (H_model - ignore_top_h) coords = coords[mask] part_nodes = part_nodes[mask] if ignore_bot_h is None: ignore_bot_h = 0 if ignore_top_h is None: ignore_top_h = 0 H_eff = H_model - (ignore_bot_h + ignore_top_h) if fem_meridian_bot2top: xs_norm = (coords[:, 2]-ignore_bot_h)/H_eff else: xs_norm = (H_eff-(coords[:, 2]-ignore_bot_h))/H_eff thetas = arctan2(coords[:, 1], coords[:, 0]) alpharad = deg2rad(semi_angle) w0 = fit_data.fw0(m0, n0, c0, xs_norm, thetas, funcnum) nodal_translations = np.zeros_like(coords) nodal_translations[:, 0] = w0*cos(alpharad)*cos(thetas) nodal_translations[:, 1] = w0*cos(alpharad)*sin(thetas) nodal_translations[:, 2] = w0*sin(alpharad) log('Calculation of imperfection amplitudes finished!') # applying translations viewport = session.viewports[session.currentViewportName] log('Applying new nodal positions in ABAQUS CAE to model {0} ...'. format(model_name)) log(' (using a scaling factor of {0})'.format(scaling_factor)) new_coords = coords + nodal_translations if T is not None: Tinv = np.zeros_like(T) Tinv[:3, :3] = T[:3, :3].T Tinv[:, 3] = -T[:, 3] tmp = np.vstack((new_coords.T, np.ones((1, new_coords.shape[0])))) new_coords = np.dot(Tinv, tmp).T del tmp meshNodeArray = part.nodes.sequenceFromLabels( [n.label for n in part_nodes]) new_coords = np.ascontiguousarray(new_coords) part.editNode(nodes=meshNodeArray, coordinates=new_coords) log('Application of new nodal positions finished!') ra = mod.rootAssembly viewport.setValues(displayedObject=ra) ra.regenerate() return nodal_translations
nz = 180 funcnum = 2 path = 'degenhardt_2010_z25_msi_theta_z_imp.txt' theta = linspace(-pi, pi, ntheta) z = linspace(0., 1., nz) theta, z = meshgrid(theta, z, copy=False) for m0, n0 in [[20, 30], [30, 45], [40, 60], [50, 75]]: c, residues = calc_c0(path, m0=m0, n0=n0, sample_size=(10 * 2 * m * n), funcnum=funcnum) w0 = fw0(m0, n0, z.ravel(), theta.ravel(), funcnum=funcnum) plt.figure(figsize=(3.5, 2)) levels = np.linspace(w0.min(), w0.max(), 400) plt.contourf(theta, z * H_measured, w0.reshape(theta.shape), levels=levels) ax = plt.gca() ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.xaxis.set_ticks([-pi, pi]) ax.xaxis.set_ticklabels([r'$-\pi$', r'$\pi$']) ax.set_xlabel('Circumferential Position, $rad$')