def test_reduced_dof_freq_plate(): models = ['plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell'] for model in models: print('Test reduced_dof solver, prestress=True, model={0}'.format(model)) p = Panel() p.model = model p.a = 1. p.b = 0.5 p.r = 100. p.alphadeg = 0. p.stack = [0, 90, -45, +45] p.plyt = 1e-3*0.125 p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9) p.mu = 1.3e3 p.m = 11 p.n = 12 p.Nxx = -60. p.Nyy = -5. k0 = p.calc_k0(silent=True) M = p.calc_kM(silent=True) kG0 = p.calc_kG0(silent=True) k0 += kG0 eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True) reduced_false = eigvals[0] freq(k0, M, sparse_solver=True, reduced_dof=True, silent=True) reduced_true = eigvals[0] assert np.isclose(reduced_false, reduced_true, rtol=0.001)
def test_reduced_dof_freq_plate(): models = ['plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell'] for model in models: print( 'Test reduced_dof solver, prestress=True, model={0}'.format(model)) p = Panel() p.model = model p.a = 1. p.b = 0.5 p.r = 100. p.alphadeg = 0. p.stack = [0, 90, -45, +45] p.plyt = 1e-3 * 0.125 p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9) p.mu = 1.3e3 p.m = 11 p.n = 12 p.Nxx = -60. p.Nyy = -5. k0 = p.calc_k0(silent=True) M = p.calc_kM(silent=True) kG0 = p.calc_kG0(silent=True) k0 += kG0 eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True) reduced_false = eigvals[0] freq(k0, M, sparse_solver=True, reduced_dof=True, silent=True) reduced_true = eigvals[0] assert np.isclose(reduced_false, reduced_true, rtol=0.001)
def test_panel_freq(): for model in [ 'plate_clt_donnell_bardell', 'plate_clt_donnell_bardell_w', 'cpanel_clt_donnell_bardell', 'kpanel_clt_donnell_bardell' ]: for prestress in [True, False]: print('Frequency Analysis, prestress={0}, model={1}'.format( prestress, model)) p = Panel() p.model = model p.a = 1. p.b = 0.5 p.r = 1.e8 p.alphadeg = 0. p.stack = [0, 90, -45, +45] p.plyt = 1e-3 * 0.125 p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9) p.mu = 1.3e3 p.m = 11 p.n = 12 p.Nxx = -60. p.Nyy = -5. k0 = p.calc_k0(silent=True) M = p.calc_kM(silent=True) if prestress: kG0 = p.calc_kG0(silent=True) k0 += kG0 eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True) if prestress: if '_w' in model: assert np.isclose(eigvals[0], 19.9272, rtol=0.001) else: assert np.isclose(eigvals[0], 17.85875, rtol=0.001) else: if '_w' in model: assert np.isclose(eigvals[0], 40.37281, rtol=0.001) else: assert np.isclose(eigvals[0], 39.31476, rtol=0.001)
def test_panel_freq(): for model in ['plate_clt_donnell_bardell', 'plate_clt_donnell_bardell_w', 'cpanel_clt_donnell_bardell', 'kpanel_clt_donnell_bardell']: for prestress in [True, False]: print('Frequency Analysis, prestress={0}, model={1}'.format( prestress, model)) p = Panel() p.model = model p.a = 1. p.b = 0.5 p.r = 1.e8 p.alphadeg = 0. p.stack = [0, 90, -45, +45] p.plyt = 1e-3*0.125 p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9) p.mu = 1.3e3 p.m = 11 p.n = 12 p.Nxx = -60. p.Nyy = -5. k0 = p.calc_k0(silent=True) M = p.calc_kM(silent=True) if prestress: kG0 = p.calc_kG0(silent=True) k0 += kG0 eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True) if prestress: if '_w' in model: assert np.isclose(eigvals[0], 19.9272, rtol=0.001) else: assert np.isclose(eigvals[0], 17.85875, rtol=0.001) else: if '_w' in model: assert np.isclose(eigvals[0], 40.37281, rtol=0.001) else: assert np.isclose(eigvals[0], 39.31476, rtol=0.001)
class BladeStiff2D(object): r"""Blade Stiffener using 2D Formulation for Flange Blade-type of stiffener model using a 2D formulation for the flange and a 2D formulation for the base (padup):: || --> flange | || |-> stiffener ====== --> padup | ========================= --> panels Panel1 Panel2 Both the flange and the base are optional. The stiffener's base is modeled using the same approximation functions as the skin, with the proper offset. Each stiffener has a constant `y_s` coordinate. """ def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts, blaminaprops, fstack, fplyts, flaminaprops, mf=14, nf=11): self.bay = bay self.panel1 = panel1 self.panel2 = panel2 self.mu = mu self.ys = ys self.bb = bb self.forces_flange = [] self.bstack = bstack self.bplyts = bplyts self.blaminaprops = blaminaprops self.k0 = None self.kM = None self.kG0 = None self.base = None if bstack is not None: y1 = self.ys - bb/2. y2 = self.ys + bb/2. h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts) hb = sum(self.bplyts) self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg, stack=bstack, plyts=bplyts, laminaprops=blaminaprops, mu=mu, m=bay.m, n=bay.n, offset=(-h/2.-hb/2.), u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx, v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx, w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx, u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry, v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry, w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry, y1=y1, y2=y2) self.flange = None if fstack is not None: self.flange = Panel(m=mf, n=nf, a=bay.a, b=bf, mu=mu, stack=fstack, plyts=fplyts, laminaprops=flaminaprops, model='plate_clt_donnell_bardell', u1tx=0., u1rx=0., u2tx=0., u2rx=0., v1tx=0., v1rx=0., v2tx=0., v2rx=0., w1tx=0., w1rx=1., w2tx=0., w2rx=1., u1ty=1., u1ry=0., u2ty=1., u2ry=0., v1ty=1., v1ry=0., v2ty=1., v2ry=0., w1ty=1., w1ry=1., w2ty=1., w2ry=1.) self._rebuild() def _rebuild(self): assert self.panel1.model == self.panel2.model assert self.panel1.m == self.panel2.m assert self.panel1.n == self.panel2.n assert self.panel1.r == self.panel2.r assert self.panel1.alphadeg == self.panel2.alphadeg if self.flange is not None: self.flange.lam = laminate.read_stack(self.flange.stack, plyts=self.flange.plyts, laminaprops=self.flange.laminaprops) self.flange.lam.calc_equivalent_modulus() if self.base is not None: h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts) hb = sum(self.bplyts) self.dpb = h/2. + hb/2. self.base.lam = laminate.read_stack(self.bstack, plyts=self.bplyts, laminaprops=self.blaminaprops, offset=(-h/2.-hb/2.)) def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the linear constitutive stiffness matrix """ self._rebuild() msg('Calculating k0... ', level=2, silent=silent) flangemod = panmodelDB.db[self.flange.model]['matrices'] bay = self.bay a = bay.a b = bay.b m = bay.m n = bay.n k0 = 0. if self.base is not None: k0 += self.base.calc_k0(size=size, row0=0, col0=0, silent=True, finalize=False) if self.flange is not None: k0 += self.flange.calc_k0(size=size, row0=row0, col0=col0, silent=True, finalize=False) # connectivity between stiffener'base and stiffener's flange if self.base is None: ktbf, krbf = calc_kt_kr(self.panel1, self.flange, 'ycte') else: ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte') mod = db['bladestiff2d_clt_donnell_bardell']['connections'] k0 += mod.fkCss(ktbf, krbf, self.ys, a, b, m, n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size, 0, 0) bf = self.flange.b k0 += mod.fkCsf(ktbf, krbf, self.ys, a, b, bf, m, n, self.flange.m, self.flange.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx, self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx, self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx, self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry, self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry, self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry, size, 0, col0) k0 += mod.fkCff(ktbf, krbf, a, bf, self.flange.m, self.flange.n, self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx, self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx, self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx, self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry, self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry, self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry, size, row0, col0) if finalize: k0 = finalize_symmetric_matrix(k0) self.k0 = k0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True, c=None, NLgeom=False): """Calculate the linear geometric stiffness matrix """ self._rebuild() msg('Calculating kG0... ', level=2, silent=silent) kG0 = 0. if self.base is not None: #TODO include kG0 for pad-up and Nxx load that arrives there pass if self.flange is not None: kG0 += self.flange.calc_kG0(size=size, row0=row0, col0=col0, silent=True, finalize=False, NLgeom=NLgeom) if finalize: kG0 = finalize_symmetric_matrix(kG0) self.kG0 = kG0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the mass matrix """ self._rebuild() msg('Calculating kM... ', level=2, silent=silent) kM = 0. if self.base is not None: kM += self.base.calc_kM(size=size, row0=0, col0=0, silent=True, finalize=False) if self.flange is not None: kM += self.flange.calc_kM(size=size, row0=row0, col0=col0, silent=True, finalize=False) if finalize: kM = finalize_symmetric_matrix(kM) self.kM = kM #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent)
class BladeStiff1D(object): r"""Blade Stiffener using 1D Formulation for Flange Blade-type of stiffener model using a 1D formulation for the flange and a 2D formulation for the padup (base):: || --> flange | || |-> stiffener ====== --> padup | ========================= --> panels Panel1 Panel2 Both the flange and the padup are optional, but one must exist. Each stiffener has a constant `y` coordinate. """ def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts, blaminaprops, fstack, fplyts, flaminaprops): self.bay = bay self.panel1 = panel1 self.panel2 = panel2 self.model = 'bladestiff1d_clt_donnell_bardell' self.mu = mu self.ys = ys self.bb = bb self.hb = 0. self.bf = bf self.hf = 0. self.bstack = bstack self.bplyts = bplyts self.blaminaprops = blaminaprops self.base = None self.fstack = fstack self.fplyts = fplyts self.flaminaprops = flaminaprops self.flam = None self.As = None self.Asb = None self.Asf = None self.Jxx = None self.Iyy = None self.Fx = None self._rebuild() def _rebuild(self): assert self.panel1.model == self.panel2.model assert self.panel1.m == self.panel2.m assert self.panel1.n == self.panel2.n assert self.panel1.r == self.panel2.r assert self.panel1.alphadeg == self.panel2.alphadeg if self.fstack is not None: self.hf = sum(self.fplyts) self.Asf = self.bf*self.hf self.flam = laminate.read_stack(self.fstack, plyts=self.fplyts, laminaprops=self.flaminaprops) self.flam.calc_equivalent_modulus() h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts) hb = 0. if self.bstack is not None: hb = sum(self.bplyts) y1 = self.ys - self.bb/2. y2 = self.ys + self.bb/2. self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg, stack=self.bstack, plyts=self.bplyts, mu=self.mu, m=bay.m, n=bay.n, laminaprops=self.blaminaprops, offset=(-h/2.-hb/2.), u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx, v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx, w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx, u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry, v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry, w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry, y1=y1, y2=y2) self.Asb = self.bb*hb #TODO check offset effect on curved panels self.dbf = self.bf/2. + hb + h/2. self.Iyy = self.hf*self.bf**3/12. self.Jxx = self.hf*self.bf**3/12. + self.bf*self.hf**3/12. Asb = self.Asb if self.Asb is not None else 0. Asf = self.Asf if self.Asf is not None else 0. self.As = Asb + Asf if self.fstack is not None: self.E1 = 0 #E3 = 0 self.S1 = 0 yply = self.flam.plies[0].t/2. for i, ply in enumerate(self.flam.plies): if i > 0: yply += self.flam.plies[i-1].t/2. + self.flam.plies[i].t/2. q = ply.QL self.E1 += ply.t*(q[0,0] - q[0,1]**2/q[1,1]) #E3 += ply.t*(q[2,2] - q[1,2]**2/q[1,1]) self.S1 += -yply*ply.t*(q[0,2] - q[0,1]*q[1,2]/q[1,1]) self.F1 = self.bf**2/12.*self.E1 def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the linear constitutive stiffness matrix """ self._rebuild() msg('Calculating k0... ', level=2, silent=silent) k0 = 0. if self.base is not None: k0 += self.base.calc_k0(size=size, row0=row0, col0=col0, silent=True, finalize=False) if self.flam is not None: mod = modelDB.db[self.model]['matrices'] bay = self.bay k0 += mod.fk0f(self.ys, bay.a, bay.b, self.bf, self.dbf, self.E1, self.F1, self.S1, self.Jxx, bay.m, bay.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size=size, row0=row0, col0=col0) if finalize: k0 = finalize_symmetric_matrix(k0) self.k0 = k0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True, c=None): """Calculate the linear geometric stiffness matrix """ #TODO if c is not None: raise NotImplementedError('numerical kG0 not implemented') self._rebuild() msg('Calculating kG0... ', level=2, silent=silent) kG0 = 0. if self.base is not None: # TODO include kG0 for padup # now it is assumed that all the load goes to the flange pass if self.flam is not None: Fx = self.Fx if self.Fx is not None else 0. mod = modelDB.db[self.model]['matrices'] bay = self.bay kG0 += mod.fkG0f(self.ys, Fx, bay.a, bay.b, self.bf, bay.m, bay.n, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size, row0, col0) if finalize: kG0 = finalize_symmetric_matrix(kG0) self.kG0 = kG0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the mass matrix """ self._rebuild() msg('Calculating kM... ', level=2, silent=silent) mod = modelDB.db[self.model]['matrices'] kM = 0. if self.base is not None: kM += self.base.calc_kM(size=size, row0=row0, col0=col0, silent=silent, finalize=False) if self.flam is not None: bay = self.bay h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts) kM += mod.fkMf(self.ys, self.mu, h, self.hb, self.hf, bay.a, bay.b, self.bf, self.dbf, bay.m, bay.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size=size, row0=row0, col0=col0) if finalize: kM = finalize_symmetric_matrix(kM) self.kM = kM #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent)
class TStiff2D(object): r"""T Stiffener using 2D Formulation for the Base and Flange T-type of stiffener model using a 2D formulation for the flange and a 2D formulation for the base:: || --> flange | || |-> stiffener ====== --> base | ========================= --> panels Panel1 Panel2 The difference between this model and :class:'.BladeStiff2D' is that here the stiffener's base has independent field variables allowing the simulation of skin-stiffener debounding effects. Each stiffener has a constant `y_s` coordinate. """ def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts, blaminaprops, fstack, fplyts, flaminaprops, model='tstiff2d_clt_donnell_bardell', mb=15, nb=12, mf=15, nf=12): print( '\n\nWARNING - TStiff2D no longer recommended!\n' ' There is a numerically unstable way to compute the\n' ' connection between the skin and stiffener\'s base, it is\n' ' recommended to use panel.assembly instead.\n' ' Module panel.assembly allows stable ways to perform\n' ' connection among panels, and avoids using sliced\n' ' integration intervals that were causing trouble in\n' ' TStiff2D\n\n') self.bay = bay self.panel1 = panel1 self.panel2 = panel2 self.model = model if bstack is None: raise ValueError('Base laminate must be defined!') self.ys = ys y1 = ys - bb / 2. y2 = ys + bb / 2. self.base = Panel(a=bay.a, b=bb, r=bay.r, alphadeg=bay.alphadeg, stack=bstack, plyts=bplyts, laminaprops=blaminaprops, mu=mu, m=mb, n=nb, offset=0., u1tx=1, u1rx=0, u2tx=1, u2rx=0, v1tx=1, v1rx=0, v2tx=1, v2rx=0, w1tx=1, w1rx=1, w2tx=1, w2rx=1, u1ty=1, u1ry=0, u2ty=1, u2ry=0, v1ty=1, v1ry=0, v2ty=1, v2ry=0, w1ty=1, w1ry=1, w2ty=1, w2ry=1, y1=y1, y2=y2) self.base._rebuild() if fstack is None: raise ValueError('Flange laminate must be defined!') self.flange = Panel(a=bay.a, b=bf, model='plate_clt_donnell_bardell', stack=fstack, plyts=fplyts, laminaprops=flaminaprops, mu=mu, m=mf, n=nf, offset=0., u1tx=0, u1rx=0, u2tx=0, u2rx=0, v1tx=0, v1rx=0, v2tx=0, v2rx=0, w1tx=0, w1rx=1, w2tx=0, w2rx=1, u1ty=1, u1ry=0, u2ty=1, u2ry=0, v1ty=1, v1ry=0, v2ty=1, v2ry=0, w1ty=1, w1ry=1, w2ty=1, w2ry=1) self.flange._rebuild() self.eta_conn_base = 0. self.eta_conn_flange = -1. self.k0 = None self.kM = None self.kG0 = None self._rebuild() def _rebuild(self): assert self.panel1.model == self.panel2.model assert self.panel1.r == self.panel2.r assert self.panel1.alphadeg == self.panel2.alphadeg a = None b = None if self.panel1 is not None: a = self.panel1.a b = self.panel1.b elif self.panel2 is not None: a = self.panel2.a b = self.panel2.b if a is not None and b is not None: if a / b > 10.: if self.base.m <= 15 and self.flange.m <= 15: raise RuntimeError( 'For a/b > 10. use base.m and flange.m > 15') else: warn( 'For a/b > 10. be sure to check convergence for base.m and flange.m' ) self.flange.lam = laminate.read_stack( self.flange.stack, plyts=self.flange.plyts, laminaprops=self.flange.laminaprops) #NOTE below offset is not needed since it is already considered in the # connectivity matrices, using dpb h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts) hb = sum(self.base.plyts) self.dpb = h / 2. + hb / 2. self.base.lam = laminate.read_stack(self.base.stack, plyts=self.base.plyts, laminaprops=self.base.laminaprops, offset=0.) def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the linear constitutive stiffness matrix """ self._rebuild() msg('Calculating k0... ', level=2, silent=silent) # NOTE # row0 and col0 define where the stiffener's base matrix starts # rowf and colf define where the stiffener's flange matrix starts rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() k0 = 0. k0 += self.base.calc_k0(size=size, row0=row0, col0=col0, silent=True, finalize=False) k0 += self.flange.calc_k0(size=size, row0=rowf, col0=colf, silent=True, finalize=False) # connectivity panel-base conn = stiffmDB.db[self.model]['connections'] ktpb, krpb = calc_kt_kr(self.panel1, self.base, 'bot-top') ktpb = min(1.e7, ktpb) #TODO remove from Cython the capability to run with debonding defect y1 = self.ys - self.base.b / 2. y2 = self.ys + self.base.b / 2. bay = self.bay k0 += conn.fkCppy1y2(y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m, bay.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size, 0, 0) k0 += conn.fkCpby1y2( y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m, bay.n, self.base.m, self.base.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, self.base.u1tx, self.base.u1rx, self.base.u2tx, self.base.u2rx, self.base.v1tx, self.base.v1rx, self.base.v2tx, self.base.v2rx, self.base.w1tx, self.base.w1rx, self.base.w2tx, self.base.w2rx, self.base.u1ty, self.base.u1ry, self.base.u2ty, self.base.u2ry, self.base.v1ty, self.base.v1ry, self.base.v2ty, self.base.v2ry, self.base.w1ty, self.base.w1ry, self.base.w2ty, self.base.w2ry, size, 0, col0) k0 += conn.fkCbbpby1y2(y1, y2, ktpb, bay.a, bay.b, self.base.m, self.base.n, self.base.u1tx, self.base.u1rx, self.base.u2tx, self.base.u2rx, self.base.v1tx, self.base.v1rx, self.base.v2tx, self.base.v2rx, self.base.w1tx, self.base.w1rx, self.base.w2tx, self.base.w2rx, self.base.u1ty, self.base.u1ry, self.base.u2ty, self.base.u2ry, self.base.v1ty, self.base.v1ry, self.base.v2ty, self.base.v2ry, self.base.w1ty, self.base.w1ry, self.base.w2ty, self.base.w2ry, size, row0, col0) # connectivity base-flange ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte') ycte1 = (self.eta_conn_base + 1) / 2. * self.base.b ycte2 = (self.eta_conn_flange + 1) / 2. * self.flange.b k0 += fkCBFycte11(ktbf, krbf, self.base, ycte1, size, row0, col0) k0 += fkCBFycte12(ktbf, krbf, self.base, self.flange, ycte1, ycte2, size, row0, colf) k0 += fkCBFycte22(ktbf, krbf, self.base, self.flange, ycte2, size, rowf, colf) if finalize: k0 = finalize_symmetric_matrix(k0) self.k0 = k0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True, c=None, NLgeom=False): """Calculate the linear geometric stiffness matrix See :meth:`.Panel.calc_k0` for details on each parameter. """ self._rebuild() if c is None: msg('Calculating kG0... ', level=2, silent=silent) else: msg('Calculating kG... ', level=2, silent=silent) # NOTE: # - row0 and col0 define where the stiffener's base matrix starts # - rowf and colf define where the stiffener's flange matrix starts rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() kG0 = 0. kG0 += self.base.calc_kG0(c=c, size=size, row0=row0, col0=col0, silent=True, finalize=False, NLgeom=NLgeom) kG0 += self.flange.calc_kG0(c=c, size=size, row0=rowf, col0=colf, silent=True, finalize=False, NLgeom=NLgeom) if finalize: kG0 = finalize_symmetric_matrix(kG0) self.kG0 = kG0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the mass matrix """ self._rebuild() msg('Calculating kM... ', level=2, silent=silent) rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() kM = 0. kM += self.base.calc_kM(size=size, row0=row0, col0=col0, silent=True, finalize=False) kM += self.flange.calc_kM(size=size, row0=rowf, col0=colf, silent=True, finalize=False) if finalize: kM = finalize_symmetric_matrix(kM) self.kM = kM #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent)
class TStiff2D(object): r"""T Stiffener using 2D Formulation for the Base and Flange T-type of stiffener model using a 2D formulation for the flange and a 2D formulation for the base:: || --> flange | || |-> stiffener ====== --> base | ========================= --> panels Panel1 Panel2 The difference between this model and :class:'.BladeStiff2D' is that here the stiffener's base has independent field variables allowing the simulation of skin-stiffener debounding effects. Each stiffener has a constant `y_s` coordinate. """ def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts, blaminaprops, fstack, fplyts, flaminaprops, model='tstiff2d_clt_donnell_bardell', mb=15, nb=12, mf=15, nf=12): print('\n\nWARNING - TStiff2D no longer recommended!\n' ' There is a numerically unstable way to compute the\n' ' connection between the skin and stiffener\'s base, it is\n' ' recommended to use panel.assembly instead.\n' ' Module panel.assembly allows stable ways to perform\n' ' connection among panels, and avoids using sliced\n' ' integration intervals that were causing trouble in\n' ' TStiff2D\n\n') self.bay = bay self.panel1 = panel1 self.panel2 = panel2 self.model = model if bstack is None: raise ValueError('Base laminate must be defined!') self.ys = ys y1 = ys - bb/2. y2 = ys + bb/2. self.base = Panel(a=bay.a, b=bb, r=bay.r, alphadeg=bay.alphadeg, stack=bstack, plyts=bplyts, laminaprops=blaminaprops, mu=mu, m=mb, n=nb, offset=0., u1tx=1, u1rx=0, u2tx=1, u2rx=0, v1tx=1, v1rx=0, v2tx=1, v2rx=0, w1tx=1, w1rx=1, w2tx=1, w2rx=1, u1ty=1, u1ry=0, u2ty=1, u2ry=0, v1ty=1, v1ry=0, v2ty=1, v2ry=0, w1ty=1, w1ry=1, w2ty=1, w2ry=1, y1=y1, y2=y2) self.base._rebuild() if fstack is None: raise ValueError('Flange laminate must be defined!') self.flange = Panel(a=bay.a, b=bf, model='plate_clt_donnell_bardell', stack=fstack, plyts=fplyts, laminaprops=flaminaprops, mu=mu, m=mf, n=nf, offset=0., u1tx=0, u1rx=0, u2tx=0, u2rx=0, v1tx=0, v1rx=0, v2tx=0, v2rx=0, w1tx=0, w1rx=1, w2tx=0, w2rx=1, u1ty=1, u1ry=0, u2ty=1, u2ry=0, v1ty=1, v1ry=0, v2ty=1, v2ry=0, w1ty=1, w1ry=1, w2ty=1, w2ry=1) self.flange._rebuild() self.eta_conn_base = 0. self.eta_conn_flange = -1. self.k0 = None self.kM = None self.kG0 = None self._rebuild() def _rebuild(self): assert self.panel1.model == self.panel2.model assert self.panel1.r == self.panel2.r assert self.panel1.alphadeg == self.panel2.alphadeg a = None b = None if self.panel1 is not None: a = self.panel1.a b = self.panel1.b elif self.panel2 is not None: a = self.panel2.a b = self.panel2.b if a is not None and b is not None: if a / b > 10.: if self.base.m <= 15 and self.flange.m <= 15: raise RuntimeError('For a/b > 10. use base.m and flange.m > 15') else: warn('For a/b > 10. be sure to check convergence for base.m and flange.m') self.flange.lam = laminate.read_stack(self.flange.stack, plyts=self.flange.plyts, laminaprops=self.flange.laminaprops) #NOTE below offset is not needed since it is already considered in the # connectivity matrices, using dpb h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts) hb = sum(self.base.plyts) self.dpb = h/2. + hb/2. self.base.lam = laminate.read_stack(self.base.stack, plyts=self.base.plyts, laminaprops=self.base.laminaprops, offset=0.) def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the linear constitutive stiffness matrix """ self._rebuild() msg('Calculating k0... ', level=2, silent=silent) # NOTE # row0 and col0 define where the stiffener's base matrix starts # rowf and colf define where the stiffener's flange matrix starts rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() k0 = 0. k0 += self.base.calc_k0(size=size, row0=row0, col0=col0, silent=True, finalize=False) k0 += self.flange.calc_k0(size=size, row0=rowf, col0=colf, silent=True, finalize=False) # connectivity panel-base conn = stiffmDB.db[self.model]['connections'] ktpb, krpb = calc_kt_kr(self.panel1, self.base, 'bot-top') ktpb = min(1.e7, ktpb) #TODO remove from Cython the capability to run with debonding defect y1 = self.ys - self.base.b/2. y2 = self.ys + self.base.b/2. bay = self.bay k0 += conn.fkCppy1y2(y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m, bay.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size, 0, 0) k0 += conn.fkCpby1y2(y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m, bay.n, self.base.m, self.base.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, self.base.u1tx, self.base.u1rx, self.base.u2tx, self.base.u2rx, self.base.v1tx, self.base.v1rx, self.base.v2tx, self.base.v2rx, self.base.w1tx, self.base.w1rx, self.base.w2tx, self.base.w2rx, self.base.u1ty, self.base.u1ry, self.base.u2ty, self.base.u2ry, self.base.v1ty, self.base.v1ry, self.base.v2ty, self.base.v2ry, self.base.w1ty, self.base.w1ry, self.base.w2ty, self.base.w2ry, size, 0, col0) k0 += conn.fkCbbpby1y2(y1, y2, ktpb, bay.a, bay.b, self.base.m, self.base.n, self.base.u1tx, self.base.u1rx, self.base.u2tx, self.base.u2rx, self.base.v1tx, self.base.v1rx, self.base.v2tx, self.base.v2rx, self.base.w1tx, self.base.w1rx, self.base.w2tx, self.base.w2rx, self.base.u1ty, self.base.u1ry, self.base.u2ty, self.base.u2ry, self.base.v1ty, self.base.v1ry, self.base.v2ty, self.base.v2ry, self.base.w1ty, self.base.w1ry, self.base.w2ty, self.base.w2ry, size, row0, col0) # connectivity base-flange ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte') ycte1 = (self.eta_conn_base + 1)/2. * self.base.b ycte2 = (self.eta_conn_flange + 1)/2. * self.flange.b k0 += fkCBFycte11(ktbf, krbf, self.base, ycte1, size, row0, col0) k0 += fkCBFycte12(ktbf, krbf, self.base, self.flange, ycte1, ycte2, size, row0, colf) k0 += fkCBFycte22(ktbf, krbf, self.base, self.flange, ycte2, size, rowf, colf) if finalize: k0 = finalize_symmetric_matrix(k0) self.k0 = k0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True, c=None, NLgeom=False): """Calculate the linear geometric stiffness matrix See :meth:`.Panel.calc_k0` for details on each parameter. """ self._rebuild() if c is None: msg('Calculating kG0... ', level=2, silent=silent) else: msg('Calculating kG... ', level=2, silent=silent) # NOTE: # - row0 and col0 define where the stiffener's base matrix starts # - rowf and colf define where the stiffener's flange matrix starts rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() kG0 = 0. kG0 += self.base.calc_kG0(c=c, size=size, row0=row0, col0=col0, silent=True, finalize=False, NLgeom=NLgeom) kG0 += self.flange.calc_kG0(c=c, size=size, row0=rowf, col0=colf, silent=True, finalize=False, NLgeom=NLgeom) if finalize: kG0 = finalize_symmetric_matrix(kG0) self.kG0 = kG0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the mass matrix """ self._rebuild() msg('Calculating kM... ', level=2, silent=silent) rowf = row0 + self.base.get_size() colf = col0 + self.base.get_size() kM = 0. kM += self.base.calc_kM(size=size, row0=row0, col0=col0, silent=True, finalize=False) kM += self.flange.calc_kM(size=size, row0=rowf, col0=colf, silent=True, finalize=False) if finalize: kM = finalize_symmetric_matrix(kM) self.kM = kM #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent)
class BladeStiff2D(object): r"""Blade Stiffener using 2D Formulation for Flange Blade-type of stiffener model using a 2D formulation for the flange and a 2D formulation for the base (padup):: || --> flange | || |-> stiffener ====== --> padup | ========================= --> panels Panel1 Panel2 Both the flange and the base are optional. The stiffener's base is modeled using the same approximation functions as the skin, with the proper offset. Each stiffener has a constant `y_s` coordinate. """ def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts, blaminaprops, fstack, fplyts, flaminaprops, mf=14, nf=11): self.bay = bay self.panel1 = panel1 self.panel2 = panel2 self.mu = mu self.ys = ys self.bb = bb self.forces_flange = [] self.bstack = bstack self.bplyts = bplyts self.blaminaprops = blaminaprops self.k0 = None self.kM = None self.kG0 = None self.base = None if bstack is not None: y1 = self.ys - bb / 2. y2 = self.ys + bb / 2. h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts) hb = sum(self.bplyts) self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg, stack=bstack, plyts=bplyts, laminaprops=blaminaprops, mu=mu, m=bay.m, n=bay.n, offset=(-h / 2. - hb / 2.), u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx, v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx, w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx, u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry, v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry, w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry, y1=y1, y2=y2) self.flange = None if fstack is not None: self.flange = Panel(m=mf, n=nf, a=bay.a, b=bf, mu=mu, stack=fstack, plyts=fplyts, laminaprops=flaminaprops, model='plate_clt_donnell_bardell', u1tx=0., u1rx=0., u2tx=0., u2rx=0., v1tx=0., v1rx=0., v2tx=0., v2rx=0., w1tx=0., w1rx=1., w2tx=0., w2rx=1., u1ty=1., u1ry=0., u2ty=1., u2ry=0., v1ty=1., v1ry=0., v2ty=1., v2ry=0., w1ty=1., w1ry=1., w2ty=1., w2ry=1.) self._rebuild() def _rebuild(self): assert self.panel1.model == self.panel2.model assert self.panel1.m == self.panel2.m assert self.panel1.n == self.panel2.n assert self.panel1.r == self.panel2.r assert self.panel1.alphadeg == self.panel2.alphadeg if self.flange is not None: self.flange.lam = laminate.read_stack( self.flange.stack, plyts=self.flange.plyts, laminaprops=self.flange.laminaprops) self.flange.lam.calc_equivalent_modulus() if self.base is not None: h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts) hb = sum(self.bplyts) self.dpb = h / 2. + hb / 2. self.base.lam = laminate.read_stack(self.bstack, plyts=self.bplyts, laminaprops=self.blaminaprops, offset=(-h / 2. - hb / 2.)) def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the linear constitutive stiffness matrix """ self._rebuild() msg('Calculating k0... ', level=2, silent=silent) flangemod = panmodelDB.db[self.flange.model]['matrices'] bay = self.bay a = bay.a b = bay.b m = bay.m n = bay.n k0 = 0. if self.base is not None: k0 += self.base.calc_k0(size=size, row0=0, col0=0, silent=True, finalize=False) if self.flange is not None: k0 += self.flange.calc_k0(size=size, row0=row0, col0=col0, silent=True, finalize=False) # connectivity between stiffener'base and stiffener's flange if self.base is None: ktbf, krbf = calc_kt_kr(self.panel1, self.flange, 'ycte') else: ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte') mod = db['bladestiff2d_clt_donnell_bardell']['connections'] k0 += mod.fkCss(ktbf, krbf, self.ys, a, b, m, n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, size, 0, 0) bf = self.flange.b k0 += mod.fkCsf( ktbf, krbf, self.ys, a, b, bf, m, n, self.flange.m, self.flange.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry, self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx, self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx, self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx, self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry, self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry, self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry, size, 0, col0) k0 += mod.fkCff( ktbf, krbf, a, bf, self.flange.m, self.flange.n, self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx, self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx, self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx, self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry, self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry, self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry, size, row0, col0) if finalize: k0 = finalize_symmetric_matrix(k0) self.k0 = k0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True, c=None, NLgeom=False): """Calculate the linear geometric stiffness matrix """ self._rebuild() msg('Calculating kG0... ', level=2, silent=silent) kG0 = 0. if self.base is not None: #TODO include kG0 for pad-up and Nxx load that arrives there pass if self.flange is not None: kG0 += self.flange.calc_kG0(size=size, row0=row0, col0=col0, silent=True, finalize=False, NLgeom=NLgeom) if finalize: kG0 = finalize_symmetric_matrix(kG0) self.kG0 = kG0 #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent) def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True): """Calculate the mass matrix """ self._rebuild() msg('Calculating kM... ', level=2, silent=silent) kM = 0. if self.base is not None: kM += self.base.calc_kM(size=size, row0=0, col0=0, silent=True, finalize=False) if self.flange is not None: kM += self.flange.calc_kM(size=size, row0=row0, col0=col0, silent=True, finalize=False) if finalize: kM = finalize_symmetric_matrix(kM) self.kM = kM #NOTE forcing Python garbage collector to clean the memory # it DOES make a difference! There is a memory leak not # identified, probably in the csr_matrix process gc.collect() msg('finished!', level=2, silent=silent)