PyFlex  1.0
Riser cross section analysis
coefficients.py
Go to the documentation of this file.
1 """Copyright (C) 2016 Joakim A. Taby
2 
3  This program is free software: you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation, either version 3 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program. If not, see <http://www.gnu.org/licenses/>."""
14 import numpy as np
15 
16 
17 def analytical_contact_pressures(sigma,alpha,n,A,R,t,p_int,p_ext):
18  """ Finding contact pressure from pressure differencial between layers. Using B1.23 from handbook, assuming
19  sliding occurs along midpoint between layers.
20  """
21 
22  out_in=True
23 
24  if len(sigma.shape) ==1:
25  h_length=1
26  else:
27  h_length=len(sigma[:,0])
28 
29  R_inner=np.zeros(len(A))
30  R_outer=np.zeros(len(A))
31  for i in range(len(A)):
32  if i ==0:
33  R_inner[i]=R[i]-t[i]/2.0
34  R_outer[i]=(R[i+1]-t[i+1]/2.0+R[i]+t[i]/2.0)/2.0
35  elif i== len(A)-1:
36  R_inner[i]=(R[i]-t[i]/2.0+R[i-1]+t[i-1]/2.0)/2.0
37  R_outer[i]=R[i]+t[i]/2.0
38  else:
39  R_inner[i]=(R[i]-t[i]/2.0+R[i-1]+t[i-1]/2.0)/2.0
40  R_outer[i]=(R[i+1]-t[i+1]/2.0+R[i]+t[i]/2.0)/2.0
41 
42  pressure_diff_out_in = n*sigma*A*np.sin(alpha)**2/(2.0*np.pi*np.cos(alpha)*R*R_inner)
43 
44  if out_in:
45 
46  pressure_contact_out_in=np.zeros((len(A),h_length))
47 
48 
49 
50  for i in range(len(A)-1,-1,-1):
51  if i == len(A)-1:
52  pressure_contact_out_in[i]=p_ext*(R[i]+t[i]/2.0)/R_inner[i]+pressure_diff_out_in.T[i]
53  else:
54  pressure_contact_out_in[i]=pressure_diff_out_in.T[i]+pressure_contact_out_in[i+1]*R_outer[i]/R_inner[i]
55 
56  return pressure_contact_out_in.T
57 
58  else:
59 
60  pressure_diff_in_out=n*sigma*A*np.sin(alpha)**2/(2.0*np.pi*np.cos(alpha)*R*R_outer)
61  pressure_contact_in_out=np.zeros((len(A),h_length))
62  for i in range(len(A)):
63  if i == 0:
64  pressure_contact_in_out[i]=p_int
65  else:
66  pressure_contact_in_out[i]=(pressure_contact_in_out[i-1]*R_inner[i-1]/R_outer[i-1]
67  -pressure_diff_in_out.T[i-1])
68 
69  return pressure_contact_in_out.T
70 
71 
72 def critical_curvature(slenderobject, contact_pressure, frictionfactors=np.array([5, 5, 5])):
73  """ Finding the critical curvature. Need to find where this is taken from.
74  :param frictionfactors: friction factors between layer and the layer inside
75  :param contact_pressure: contact line load. A matrix [2,nlayers] for outside and inside of layer
76  respectively
77  :param slenderobject: Object of slender type from the sledner class of slenders
78  """
79  # checking data input
80  if isinstance(frictionfactors, np.int) or isinstance(frictionfactors, np.float):
81  fricfac = []
82  for i in range(len(slenderobject.thickness)):
83  fricfac.append(frictionfactors)
84  elif max(abs(frictionfactors)) == 5:
85  fricfac = slenderobject.fricfac
86  elif len(frictionfactors) == 1:
87  fricfac = []
88  for i in range(len(slenderobject.thickness)):
89  fricfac.append(frictionfactors)
90  elif len(frictionfactors) == len(slenderobject.fricfac):
91  fricfac = frictionfactors
92  else:
93  print("Cannot parse the friction factors given. Needs to be one single friction "
94  "factor, or the same number of friction factors as defined layers in "
95  "the slender object")
96 
97  tmp = contact_pressure.shape
98  dim1len=tmp[0]
99  dim2len = len(slenderobject.thickness)
100  critcurv = np.zeros((dim2len,dim1len))
101  for i in range(len(slenderobject.layer_radii)):
102  outerfillfac=slenderobject.comp_number[i]*slenderobject.width[i]/\
103  (2*np.pi*(slenderobject.layer_radii[i]-slenderobject.thickness[i])*
104  np.cos(slenderobject.lay_angle[i]))
105  innerfillfac=slenderobject.comp_number[i]*slenderobject.width[i]/\
106  (2*np.pi*(slenderobject.layer_radii[i]+slenderobject.thickness[i])*
107  np.cos(slenderobject.lay_angle[i]))
108  if not i == len(slenderobject.fricfac)-1:
109  if slenderobject.lay_angle[i] == 0:
110  critcurv[i] = 0.0
111  else:
112  critcurv[i] = ((fricfac[i] * contact_pressure.T[i]/outerfillfac + fricfac[i + 1]/innerfillfac * contact_pressure.T[i + 1]) /
113  (slenderobject.youngs_modulus[i] * slenderobject.thickness[i] *
114  np.cos(slenderobject.lay_angle[i]) ** 2.0 *
115  abs(np.sin(slenderobject.lay_angle[i]))))
116  else:
117  if slenderobject.lay_angle[i] == 0:
118  critcurv[i] = 0.0
119  else:
120  critcurv[i] = (fricfac[i] * contact_pressure.T[i] /
121  (slenderobject.youngs_modulus[i] * slenderobject.thickness[i] *
122  np.cos(slenderobject.lay_angle[i]) ** 2.0 *
123  abs(np.sin(slenderobject.lay_angle[i]))))
124 
125  return critcurv.T
126 
127 
128 # @profile
129 def local_bending(thickness,width, alpha, theta, phi, e,r, type,bend_model="Savik"):
130  """ Calculating the local bending coefficients
131  Equations from 'On stresses and fatigue in flexible pipes' by Savik 1992 and
132  'Validity and limitation of analytical models for the bending stress of a helical
133  wire in unbonded flexible pipes' Tang et.al. 2015
134 
135  :param bend_model: Which bend model to apply. Savik or Tan implemented
136  :param e: Youngs modulus. One for each layer
137  :param geometry of the tendon. one item means circular, two means rectangular
138  :param alpha: lay_angle of slender structure, list
139  :param theta: position around the crossection for calculation, numpy vector
140  :param phi: local position for calculation of coefficient, numpy vector
141  :return:list of numpy arrays defining the coefficients for each layer
142  """
143  # reshaping the arrays to given input
144  phi = np.reshape(phi, (1, -1))
145  bendcoeff = []
146  # Choosing bending model
147  for i in range(len(thickness)):
148  if type[i]=="wires":
149  if bend_model.upper() == "SAVIK":
150  weak_curvoncurv = -(np.cos(alpha[i]) ** 4) * np.cos(theta)
151 
152  strong_curvoncurv = (1 + (np.sin(alpha[i])) ** 2) * np.cos(alpha[i]) * np.sin(theta)
153  elif bend_model.upper() == "TAN":
154  strong_curvoncurv = np.sin(theta)
155  weak_curvoncurv = -np.cos(theta) * np.cos(alpha[i])
156 
157  tmp = np.zeros((len(theta[:, 0]), len(theta[0, :]), 4))
158  tmp[:, :, 0] = np.squeeze(-weak_curvoncurv * thickness[i] * 0.5 - strong_curvoncurv * width[i] * 0.5)
159  tmp[:, :, 1] = np.squeeze(
160  weak_curvoncurv * thickness[i] * 0.5 - strong_curvoncurv * width[i] * 0.5)
161  tmp[:, :, 2] = np.squeeze(
162  +weak_curvoncurv * thickness[i] * 0.5 + strong_curvoncurv * width[i] * 0.5)
163  tmp[:, :, 3] = np.squeeze(-weak_curvoncurv * thickness[i] * 0.5 + strong_curvoncurv * width[i] * 0.5)
164  bendcoeff.append(tmp * e[i])
165  elif type[i]=="sheath":
166  bendcoeff.append(e[i]*(r[i]+thickness[i]/2.0)*np.cos(theta))
167 
168  return bendcoeff
169 
170 
171 def tension_stress_history(t_eff, p_int,p_ext,alpha,R,thick,A,E,n):
172  """
173  Solving for axial stress accorind got Handbook B1.10, B1.23 and B1.13
174 
175  :param t_eff: history of effective tension
176  :param p_int: history of internal pressure
177  :param p_ext: history of external pressure
178  :param alpha: lay angles of the layers
179  :param R: radiuses of the layers
180  :param thick: thickness of the layers
181  :param A: Area of the tendons
182  :param E: young's modulus of the tendons
183  :param n: number of tendons in each layer
184  :return: numpy array with tension stress histories
185  """
186  h_length=len(t_eff)
187  r_int=R[0]-thick[0]/2.0
188  r_ext=R[-1]+thick[-1]/2.0
189  Ka = t_eff+np.pi*p_int*r_int**2-np.pi*p_ext*r_ext**2
190  Kp = 2*np.pi*(p_int*r_int-p_ext*r_ext)
191  K1 = 0.0
192  K2 = 0.0
193  K3 = 0.0
194  for i in range(len(A)):
195  K1+=n[i]*A[i]*E[i]*np.sin(alpha[i])**2*np.cos(alpha[i])/R[i]
196  K2+=n[i]*A[i]*E[i]*np.sin(alpha[i])**4/(R[i]**2*np.cos(alpha[i]))
197  K3+=n[i]*A[i]*E[i]*np.cos(alpha[i])**3
198 
199  u3 = (Ka*K1-K3*Kp)/(K1**2-K3*K2)
200  eps_p = (Ka-K1*u3)/K3
201 
202  sigma=np.zeros((i+1,h_length))
203  for i in range(len(A)):
204  sigma[i]=eps_p*E[i]*np.cos(alpha[i])**2+u3*E[i]*np.sin(alpha[i])**2/R[i]
205 
206  return sigma.T
207 
208 
209 def bending_stress_history(slenderobject, curvhist, ntheta=16, nphi=16, bend_model="Savik"):
210  """
211  Calculates the stress history from time histories of curvatures and axial stress coefficient
212  :param bend_model: Which bend model to apply. Savik or Tan implemented
213  :param nphi: Number of points around tendon to perform calculation. 4 is used of rectangular
214  tendon given.
215  :param ntheta: number of points around the cross section to perform calculation
216  :param slenderobject, instande of the Slender class
217  :param curvhist: numpy array containg each curvature time series as a column vector
218  :return: stress history for each point on defined in bendcoeff
219  """
220  phi = np.arange(0, 2 * np.pi, 2 * np.pi / nphi)
221  # decompose curvature in order to find the relative theta
222  theta_load = np.arctan2(curvhist[:, 1], curvhist[:, 0])
223  theta_load = theta_load.reshape(-1, 1)
224  abscurv = np.sqrt(curvhist[:, 0] ** 2 + curvhist[:, 1] ** 2)
225  # augment thetas for call and for call to bendcoeff
226  theta0 = np.arange(0, 2 * np.pi, 2 * np.pi / ntheta)
227  bendstress = []
228  tmp = np.repeat(theta0, len(theta_load))
229  theta0_expanded = tmp.reshape((len(theta0), len(theta_load)))
230  theta = np.subtract(theta0_expanded.T, theta_load)
231  del theta0
232  del theta0_expanded
233  del tmp
234  del theta_load
235  del curvhist
236  bendcoeff = local_bending(slenderobject.thickness,slenderobject.width, slenderobject.lay_angle,
237  theta, phi, slenderobject.youngs_modulus,
238  slenderobject.layer_radii,slenderobject.layer_type,
239  bend_model=bend_model)
240  for j in range(len(slenderobject.thickness)):
241  bendstress.append(np.multiply(bendcoeff[j].T, abscurv).T)
242  return bendstress
243 
244 
245 def stick_stress(model, curv, critcurv, theta=None):
246  """Calculating the stick stress at position theta on the crossection, limited by the critical curvature.
247  Equations from 'Bending Behavior of Helically Wrapped Cables' Hong et.al. 2005
248  :param theta: Position around cross section range [0 2*pi]
249  :param critcurv: Critical curvature. Curvature at which slip initiates for each layer
250  :param curv: Curvature history Dim: 2xN
251  :param model: Slender object as defined in slenders.Slender"""
252  curv_norm = np.sqrt(curv[:, 0] ** 2 + curv[:, 1] ** 2)
253  scaler = []
254  scaled_curv = []
255  count = 0
256  if not theta:
257  theta = []
258  # find angles from standarddev if we have more than one length
259  # if not, we calculate directly
260  for i in range(len(model.layer_radii)):
261  if len(curv[:, 0]) > 1:
262  y = np.std(curv[:, 1]) # +np.pi/2.0
263  x = np.std(curv[:, 0]) # +np.pi/2.0
264  else:
265  y = curv[:, 1] # +np.pi/2.0
266  x = curv[:, 0] # +np.pi/2.0
267  tmp = np.arctan2(y, x)
268  if y == 0:
269  tmp = np.pi / 2.0
270  if x == 0:
271  tmp = 0
272  if tmp < 0:
273  theta.append(tmp + np.pi / 2)
274  else:
275  theta.append(tmp - np.pi / 2)
276 
277  for i in np.transpose(critcurv):
278  tmp = np.clip(i / np.clip(curv_norm,0.0000000001,float("inf")), 0, 1)
279  scaled_curv.append(curv[:, 0] * tmp * np.sin(theta[count]) - curv[:, 1] * tmp * np.cos(theta[count]))
280  count += 1
281  stickstress = []
282  for i in range(len(model.layer_radii)):
283  outer_radius = model.layer_radii[i] + model.width[i]/2.0
284  stickstress.append(model.youngs_modulus[i] * np.cos(model.lay_angle[i]) ** 2 * outer_radius * scaled_curv[i])
285 
286  return stickstress
287 
288 
289 def fric_stress(curv, eps_mat, sig_mat, midpoint):
290  """
291  2D elastoplastic materialmodel with kinematic hardening
292  :param midpoint: the midpoint of the yield surface at simulation start
293  :param sig_mat: the stress at yield
294  :param eps_mat: the strain at yield
295  :param curv: curvature history 2xN
296  :return: Frictional stress
297  """
298  # it should take in 2 curvatures, the midpoint and the material model
299  # and should return the moment or stress or whatever is the quantity of interest
300  # Possibly also the corresponding stiffness
301  dimension = len(curv[0, :])
302  # taking advantage of that the stick stiffness doesnt vary with time
303  # calculating stiffnesses for each elastic-perfectly plastic region
304  stiffness = sig_mat[0] / eps_mat[0]
305  stresshistory = []
306  # Starting timeloop
307  for i in range(len(curv[:, 0])):
308  stress = 0.0
309  # calculate radius from mid
310  rad = 0.0
311  for j in range(dimension):
312  rad += (curv[i, j] - midpoint[j]) ** 2
313  rad = np.sqrt(rad)
314  diffcurv = curv[i, :] - midpoint
315  # finding the distance that the midpoint must be moved
316  if rad > 0.0:
317  movefactor = ((rad - eps_mat[i]) / rad)
318  else:
319  movefactor = 0.0
320  if movefactor > 0.0:
321  # Moving midpoint in direction current curvature relative to mid point
322  midpoint += movefactor * diffcurv
323  diffcurv = curv[i, :] - midpoint
324  # Calculating stress contributions
325  tmpstress = stiffness * diffcurv.T
326  stress += tmpstress
327  stresshistory.append(stress)
328  stresshistory = np.array(stresshistory)
329  return stresshistory, midpoint
330 
331 
332 def max_stickstress(model, critcurv):
333  max_stick_stress = []
334  for i in range(len(model.layer_radii)):
335  outer_radius = model.layer_radii[i] + model.thickness[i] / 2.0
336  max_stick_stress.append(model.youngs_modulus[i] * np.cos(model.lay_angle[i]) ** 2 * outer_radius * critcurv[i])
337 
338  return max_stick_stress
def local_bending(thickness, width, alpha, theta, phi, e, r, type, bend_model="Savik")
def analytical_contact_pressures(sigma, alpha, n, A, R, t, p_int, p_ext)
Definition: coefficients.py:17
def fric_stress(curv, eps_mat, sig_mat, midpoint)
def bending_stress_history(slenderobject, curvhist, ntheta=16, nphi=16, bend_model="Savik")
def max_stickstress(model, critcurv)
def tension_stress_history(t_eff, p_int, p_ext, alpha, R, thick, A, E, n)
def stick_stress(model, curv, critcurv, theta=None)
def critical_curvature(slenderobject, contact_pressure, frictionfactors=np.array([5, 5, 5]))
Definition: coefficients.py:72