weac 2.6.4__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
weac/eigensystem.py DELETED
@@ -1,658 +0,0 @@
1
- """Base class for the elastic analysis of layered snow slabs."""
2
- # pylint: disable=invalid-name,too-many-instance-attributes
3
- # pylint: disable=too-many-arguments,too-many-locals
4
-
5
- # Third party imports
6
- import numpy as np
7
-
8
- # Project imports
9
- from weac.tools import bergfeld, calc_center_of_gravity, load_dummy_profile
10
-
11
-
12
- class Eigensystem:
13
- """
14
- Base class for a layered beam on an elastic foundation.
15
-
16
- Provides geometry, material and loading attributes, and methods
17
- for the assembly of a fundamental system.
18
-
19
- Attributes
20
- ----------
21
- g : float
22
- Gravitational constant (mm/s^2). Default is 9180.
23
- lski : float
24
- Effective out-of-plance length of skis (mm). Default is 1000.
25
- tol : float
26
- Relative Romberg integration toleranc. Default is 1e-3.
27
- system : str
28
- Type of boundary value problem. Default is 'pst-'.
29
- weak : dict
30
- Dictionary that holds the weak layer properties Young's
31
- modulus (MPa) and Poisson's ratio. Defaults are 0.25
32
- and 0.25, respectively.
33
- t : float
34
- Weak-layer thickness (mm). Default is 30.
35
- kn : float
36
- Compressive foundation (weak-layer) stiffness (N/mm^3).
37
- kt : float
38
- Shear foundation (weak-layer) stiffness (N/mm^3).
39
- tc : float
40
- Weak-layer thickness after collapse (mm).
41
- slab : ndarray
42
- Matrix that holds the elastic properties of all slab layers.
43
- Columns are density (kg/m^3), layer heigth (mm), Young's
44
- modulus (MPa), shear modulus (MPa), and Poisson's ratio.
45
- k : float
46
- Shear correction factor of the slab. Default is 5/6.
47
- h : float
48
- Slab thickness (mm). Default is 300.
49
- zs : float
50
- Z-coordinate of the center of gravity of the slab (mm).
51
- A11 : float
52
- Extensional stiffness of the slab (N/mm).
53
- B11 : float
54
- Bending-extension coupling stiffness of the slab (N).
55
- D11 : float
56
- Bending stiffness of the slab (Nmm).
57
- kA55 : float
58
- Shear stiffness of the slab (N/mm).
59
- K0 : float
60
- Characteristic stiffness value (N).
61
- ewC : ndarray
62
- List of complex eigenvalues.
63
- ewR : ndarray
64
- List of real eigenvalues.
65
- evC : ndarray
66
- Matrix with eigenvectors corresponding to complex
67
- eigenvalues as columns.
68
- evR : ndarray
69
- Matrix with eigenvectors corresponding to real
70
- eigenvalues as columns.
71
- sC : float
72
- X-coordinate shift (mm) of complex parts of the solution.
73
- Used for numerical stability.
74
- sR : float
75
- X-coordinate shift (mm) of real parts of the solution.
76
- Used for numerical stability.
77
- sysmat : ndarray
78
- System matrix.
79
- lC : float
80
- Cracklength whose maximum deflection equals the
81
- weak-layer thickness (mm).
82
- lS : float
83
- Cracklength when touchdown exerts maximum support
84
- on the slab (mm). Corresponds to the longest possible
85
- unbedded length.
86
- ratio : float
87
- Increment factor for the weak-layer stiffness from intact
88
- to collapsed state.
89
- beta : float
90
- Describes the stiffnesses of weak-layer and slab.
91
- """
92
-
93
- def __init__(self, system="pst-", touchdown=False):
94
- """
95
- Initialize eigensystem with user input.
96
-
97
- Arguments
98
- ---------
99
- system : {'pst-', '-pst', 'vpst-', '-vpst', 'skier', 'skiers'}, optional
100
- Type of system to analyse: PST cut from the right (pst-),
101
- PST cut form the left (-pst), PST with vertical faces cut
102
- from the right (vpst-), PST with vertical faces cut from the
103
- left (-vpst), one skier on infinite slab (skier) or multiple
104
- skiers on infinite slab (skiers). Default is 'pst-'.
105
- layers : list, optional
106
- 2D list of layer densities and thicknesses. Columns are
107
- density (kg/m^3) and thickness (mm). One row corresponds
108
- to one layer. Default is [[240, 200], ].
109
- """
110
- # Assign global attributes
111
- self.g = 9810 # Gravitaiton (mm/s^2)
112
- self.lski = 1000 # Effective out-of-plane length of skis (mm)
113
- self.tol = 1e-3 # Relative Romberg integration tolerance
114
- self.system = system # 'pst-', '-pst', 'vpst-', '-vpst', 'skier', 'skiers'
115
-
116
- # Initialize weak-layer attributes that will be filled later
117
- self.weak = False # Weak-layer properties dictionary
118
- self.t = False # Weak-layer thickness (mm)
119
- self.kn = False # Weak-layer compressive stiffness
120
- self.kt = False # Weak-layer shear stiffness
121
-
122
- # Initialize slab attributes
123
- self.p = 0 # Surface line load (N/mm)
124
- self.slab = False # Slab properties dictionary
125
- self.k = False # Slab shear correction factor
126
- self.h = False # Total slab height (mm)
127
- self.zs = False # Z-coordinate of slab center of gravity (mm)
128
- self.phi = False # Slab inclination (°)
129
- self.A11 = False # Slab extensional stiffness
130
- self.B11 = False # Slab bending-extension coupling stiffness
131
- self.D11 = False # Slab bending stiffness
132
- self.kA55 = False # Slab shear stiffness
133
- self.K0 = False # Stiffness determinant
134
-
135
- # Inizialize eigensystem attributes
136
- self.ewC = False # Complex eigenvalues
137
- self.ewR = False # Real eigenvalues
138
- self.evC = False # Complex eigenvectors
139
- self.evR = False # Real eigenvectors
140
- self.sC = False # Stability shift of complex eigenvalues
141
- self.sR = False # Stability shift of real eigenvalues
142
-
143
- # Initialize touchdown attributes
144
- self.touchdown = touchdown # Flag whether touchdown is possible
145
- self.a = False # Cracklength
146
- self.tc = False # Weak-layer collapse height (mm)
147
- self.ratio = False # Stiffness ratio of collapsed to uncollapsed weak-layer
148
- self.betaU = False # Ratio of slab to bedding stiffness (uncollapsed)
149
- self.betaC = False # Ratio of slab to bedding stiffness (collapsed)
150
- self.mode = False # Touchdown-mode can be either A, B, C or D
151
- self.td = False # Touchdown length
152
-
153
- def set_foundation_properties(
154
- self, t: float = 30.0, E: float = 0.25, nu: float = 0.25, update: bool = False
155
- ):
156
- """
157
- Set material properties and geometry of foundation (weak layer).
158
-
159
- Arguments
160
- ---------
161
- t : float, optional
162
- Weak-layer thickness (mm). Default is 30.
163
- cf : float
164
- Fraction by which the weak-layer thickness is reduced
165
- due to collapse. Default is 0.5.
166
- E : float, optional
167
- Weak-layer Young modulus (MPa). Default is 0.25.
168
- nu : float, optional
169
- Weak-layer Poisson ratio. Default is 0.25.
170
- update : bool, optional
171
- If true, recalculate the fundamental system after
172
- foundation properties have changed.
173
- """
174
- # Geometry
175
- self.t = t # Weak-layer thickness (mm)
176
-
177
- # Material properties
178
- self.weak = {
179
- "nu": nu, # Poisson's ratio (-)
180
- "E": E, # Young's modulus (MPa)
181
- }
182
-
183
- # Recalculate the fundamental system after properties have changed
184
- if update:
185
- self.calc_fundamental_system()
186
-
187
- def set_beam_properties(self, layers, C0=6.5, C1=4.4, nu=0.25, update=False):
188
- """
189
- Set material and properties geometry of beam (slab).
190
-
191
- Arguments
192
- ---------
193
- layers : list or str
194
- 2D list of top-to-bottom layer densities and thicknesses.
195
- Columns are density (kg/m^3) and thickness (mm). One row
196
- corresponds to one layer. If entered as str, last split
197
- must be available in database.
198
- C0 : float, optional
199
- Multiplicative constant of Young modulus parametrization
200
- according to Bergfeld et al. (2023). Default is 6.5.
201
- C1 : float, optional
202
- Exponent of Young modulus parameterization according to
203
- Bergfeld et al. (2023). Default is 4.6.
204
- nu : float, optional
205
- Possion's ratio. Default is 0.25
206
- update : bool, optional
207
- If true, recalculate the fundamental system after
208
- foundation properties have changed.
209
- """
210
- if isinstance(layers, str):
211
- # Read layering and Young's modulus from database
212
- layers, E = load_dummy_profile(layers.split()[-1])
213
- else:
214
- # Compute Young's modulus from density parametrization
215
- layers = np.array(layers)
216
- E = bergfeld(layers[:, 0], C0=C0, C1=C1) # Young's modulus
217
-
218
- # Derive other elastic properties
219
- nu = nu * np.ones(layers.shape[0]) # Global poisson's ratio
220
- G = E / (2 * (1 + nu)) # Shear modulus
221
- self.k = 5 / 6 # Shear correction factor
222
-
223
- # Compute total slab thickness and center of gravity
224
- self.h, self.zs = calc_center_of_gravity(layers)
225
-
226
- # Assemble layering into matrix (top to bottom)
227
- # Columns are density (kg/m^3), layer thickness (mm)
228
- # Young's modulus (MPa), shear modulus (MPa), and
229
- # Poisson's ratio
230
- self.slab = np.vstack([layers.T, E, G, nu]).T
231
-
232
- # Recalculate the fundamental system after properties have changed
233
- if update:
234
- self.calc_fundamental_system()
235
-
236
- def set_surface_load(self, p):
237
- """
238
- Set surface line load.
239
-
240
- Define a distributed surface load (N/mm) that acts
241
- in vertical (gravity) direction on the top surface
242
- of the slab.
243
-
244
- Arguments
245
- ---------
246
- p : float
247
- Surface line load (N/mm) that acts in vertical
248
- (gravity) direction onm the top surface of the
249
- slab.
250
- """
251
- self.p = p
252
-
253
- def calc_foundation_stiffness(self):
254
- """Compute foundation normal and shear stiffness."""
255
- # Elastic moduli (MPa) under plane-strain conditions
256
- G = self.weak["E"] / (2 * (1 + self.weak["nu"])) # Shear modulus
257
- E = self.weak["E"] / (1 - self.weak["nu"] ** 2) # Young's modulus
258
-
259
- # Foundation (weak layer) stiffnesses (N/mm^3)
260
- self.kn = E / self.t # Normal stiffness
261
- self.kt = G / self.t # Shear stiffness
262
-
263
- def get_ply_coordinates(self):
264
- """
265
- Calculate ply (layer) z-coordinates.
266
-
267
- Returns
268
- -------
269
- ndarray
270
- Ply (layer) z-coordinates (top to bottom) in coordinate system with
271
- downward pointing z-axis (z-list will be negative to positive).
272
-
273
- """
274
- # Get list of ply (layer) thicknesses and prepend 0
275
- t = np.concatenate(([0], self.slab[:, 1]))
276
- # Calculate and return ply z-coordiantes
277
- return np.cumsum(t) - self.h / 2
278
-
279
- def calc_laminate_stiffness_matrix(self):
280
- """
281
- Provide ABD matrix.
282
-
283
- Return plane-strain laminate stiffness matrix (ABD matrix).
284
- """
285
- # Get ply coordinates (z-list is top to bottom, negative to positive)
286
- z = self.get_ply_coordinates()
287
- # Initialize stiffness components
288
- A11, B11, D11, kA55 = 0, 0, 0, 0
289
- # Add layerwise contributions
290
- for i in range(len(z) - 1):
291
- E, G, nu = self.slab[i, 2:5]
292
- A11 = A11 + E / (1 - nu**2) * (z[i + 1] - z[i])
293
- B11 = B11 + 1 / 2 * E / (1 - nu**2) * (z[i + 1] ** 2 - z[i] ** 2)
294
- D11 = D11 + 1 / 3 * E / (1 - nu**2) * (z[i + 1] ** 3 - z[i] ** 3)
295
- kA55 = kA55 + self.k * G * (z[i + 1] - z[i])
296
-
297
- self.A11 = A11
298
- self.B11 = B11
299
- self.D11 = D11
300
- self.kA55 = kA55
301
- self.K0 = B11**2 - A11 * D11
302
-
303
- def calc_system_matrix(self):
304
- """
305
- Assemble first-order ODE system matrix K.
306
-
307
- Using the solution vector z = [u, u', w, w', psi, psi']
308
- the ODE system is written in the form Az' + Bz = d
309
- and rearranged to z' = -(A ^ -1)Bz + (A ^ -1)d = Kz + q
310
-
311
- Returns
312
- -------
313
- ndarray
314
- System matrix K (6x6).
315
- """
316
- kn = self.kn
317
- kt = self.kt
318
-
319
- # Abbreviations (MIT t/2 im GGW, MIT w' in Kinematik)
320
- K21 = kt * (-2 * self.D11 + self.B11 * (self.h + self.t)) / (2 * self.K0)
321
- K24 = (
322
- 2 * self.D11 * kt * self.t
323
- - self.B11 * kt * self.t * (self.h + self.t)
324
- + 4 * self.B11 * self.kA55
325
- ) / (4 * self.K0)
326
- K25 = (
327
- -2 * self.D11 * self.h * kt
328
- + self.B11 * self.h * kt * (self.h + self.t)
329
- + 4 * self.B11 * self.kA55
330
- ) / (4 * self.K0)
331
- K43 = kn / self.kA55
332
- K61 = kt * (2 * self.B11 - self.A11 * (self.h + self.t)) / (2 * self.K0)
333
- K64 = (
334
- -2 * self.B11 * kt * self.t
335
- + self.A11 * kt * self.t * (self.h + self.t)
336
- - 4 * self.A11 * self.kA55
337
- ) / (4 * self.K0)
338
- K65 = (
339
- 2 * self.B11 * self.h * kt
340
- - self.A11 * self.h * kt * (self.h + self.t)
341
- - 4 * self.A11 * self.kA55
342
- ) / (4 * self.K0)
343
-
344
- # System matrix
345
- K = [
346
- [0, 1, 0, 0, 0, 0],
347
- [K21, 0, 0, K24, K25, 0],
348
- [0, 0, 0, 1, 0, 0],
349
- [0, 0, K43, 0, 0, -1],
350
- [0, 0, 0, 0, 0, 1],
351
- [K61, 0, 0, K64, K65, 0],
352
- ]
353
-
354
- return np.array(K)
355
-
356
- def get_load_vector(self, phi):
357
- """
358
- Compute sytem load vector q.
359
-
360
- Using the solution vector z = [u, u', w, w', psi, psi']
361
- the ODE system is written in the form Az' + Bz = d
362
- and rearranged to z' = -(A ^ -1)Bz + (A ^ -1)d = Kz + q
363
-
364
- Arguments
365
- ---------
366
- phi : float
367
- Inclination (degrees). Counterclockwise positive.
368
-
369
- Returns
370
- -------
371
- ndarray
372
- System load vector q (6x1).
373
- """
374
- qn, qt = self.get_weight_load(phi)
375
- pn, pt = self.get_surface_load(phi)
376
- return np.array(
377
- [
378
- [0],
379
- [
380
- (
381
- self.B11 * (self.h * pt - 2 * qt * self.zs)
382
- + 2 * self.D11 * (qt + pt)
383
- )
384
- / (2 * self.K0)
385
- ],
386
- [0],
387
- [-(qn + pn) / self.kA55],
388
- [0],
389
- [
390
- -(
391
- self.A11 * (self.h * pt - 2 * qt * self.zs)
392
- + 2 * self.B11 * (qt + pt)
393
- )
394
- / (2 * self.K0)
395
- ],
396
- ]
397
- )
398
-
399
- def calc_eigensystem(self):
400
- """Calculate eigenvalues and eigenvectors of the system matrix."""
401
- # Calculate eigenvalues (ew) and eigenvectors (ev)
402
- ew, ev = np.linalg.eig(self.calc_system_matrix())
403
- # Classify real and complex eigenvalues
404
- real = (ew.imag == 0) & (ew.real != 0) # real eigenvalues
405
- cmplx = ew.imag > 0 # positive complex conjugates
406
- # Eigenvalues
407
- self.ewC = ew[cmplx]
408
- self.ewR = ew[real].real
409
- # Eigenvectors
410
- self.evC = ev[:, cmplx]
411
- self.evR = ev[:, real].real
412
- # Prepare positive eigenvalue shifts for numerical robustness
413
- self.sR, self.sC = np.zeros(self.ewR.shape), np.zeros(self.ewC.shape)
414
- self.sR[self.ewR > 0], self.sC[self.ewC > 0] = -1, -1
415
-
416
- def calc_fundamental_system(self):
417
- """Calculate the fundamental system of the problem."""
418
- self.calc_foundation_stiffness()
419
- self.calc_laminate_stiffness_matrix()
420
- self.calc_eigensystem()
421
-
422
- def get_weight_load(self, phi):
423
- """
424
- Calculate line loads from slab mass.
425
-
426
- Arguments
427
- ---------
428
- phi : float
429
- Inclination (degrees). Counterclockwise positive.
430
-
431
- Returns
432
- -------
433
- qn : float
434
- Line load (N/mm) at center of gravity in normal direction.
435
- qt : float
436
- Line load (N/mm) at center of gravity in tangential direction.
437
- """
438
- # Convert units
439
- phi = np.deg2rad(phi) # Convert inclination to rad
440
- rho = self.slab[:, 0] * 1e-12 # Convert density to t/mm^3
441
- # Sum up layer weight loads
442
- q = sum(rho * self.g * self.slab[:, 1]) # Line load (N/mm)
443
- # Split into components
444
- qn = q * np.cos(phi) # Normal direction
445
- qt = -q * np.sin(phi) # Tangential direction
446
-
447
- return qn, qt
448
-
449
- def get_surface_load(self, phi):
450
- """
451
- Calculate surface line loads.
452
-
453
- Arguments
454
- ---------
455
- phi : float
456
- Inclination (degrees). Counterclockwise positive.
457
-
458
- Returns
459
- -------
460
- pn : float
461
- Surface line load (N/mm) in normal direction.
462
- pt : float
463
- Surface line load (N/mm) in tangential direction.
464
- """
465
- # Convert units
466
- phi = np.deg2rad(phi) # Convert inclination to rad
467
- # Split into components
468
- pn = self.p * np.cos(phi) # Normal direction
469
- pt = -self.p * np.sin(phi) # Tangential direction
470
-
471
- return pn, pt
472
-
473
- def get_skier_load(self, m, phi):
474
- """
475
- Calculate skier point load.
476
-
477
- Arguments
478
- ---------
479
- m : float
480
- Skier weight (kg).
481
- phi : float
482
- Inclination (degrees). Counterclockwise positive.
483
-
484
- Returns
485
- -------
486
- Fn : float
487
- Skier load (N) in normal direction.
488
- Ft : float
489
- Skier load (N) in tangential direction.
490
- """
491
- phi = np.deg2rad(phi) # Convert inclination to rad
492
- F = 1e-3 * np.array(m) * self.g / self.lski # Total skier load (N)
493
- Fn = F * np.cos(phi) # Normal skier load (N)
494
- Ft = -F * np.sin(phi) # Tangential skier load (N)
495
-
496
- return Fn, Ft
497
-
498
- def zh(self, x, l=0, bed=True):
499
- """
500
- Compute bedded or free complementary solution at position x.
501
-
502
- Arguments
503
- ---------
504
- x : float
505
- Horizontal coordinate (mm).
506
- l : float, optional
507
- Segment length (mm). Default is 0.
508
- bed : bool
509
- Indicates whether segment has foundation or not. Default
510
- is True.
511
-
512
- Returns
513
- -------
514
- zh : ndarray
515
- Complementary solution matrix (6x6) at position x.
516
- """
517
- if bed:
518
- zh = np.concatenate(
519
- [
520
- # Real
521
- self.evR * np.exp(self.ewR * (x + l * self.sR)),
522
- # Complex
523
- np.exp(self.ewC.real * (x + l * self.sC))
524
- * (
525
- self.evC.real * np.cos(self.ewC.imag * x)
526
- - self.evC.imag * np.sin(self.ewC.imag * x)
527
- ),
528
- # Complex
529
- np.exp(self.ewC.real * (x + l * self.sC))
530
- * (
531
- self.evC.imag * np.cos(self.ewC.imag * x)
532
- + self.evC.real * np.sin(self.ewC.imag * x)
533
- ),
534
- ],
535
- axis=1,
536
- )
537
- else:
538
- # Abbreviations
539
- H14 = 3 * self.B11 / self.A11 * x**2
540
- H24 = 6 * self.B11 / self.A11 * x
541
- H54 = -3 * x**2 + 6 * self.K0 / (self.A11 * self.kA55)
542
- # Complementary solution matrix of free segments
543
- zh = np.array(
544
- [
545
- [0, 0, 0, H14, 1, x],
546
- [0, 0, 0, H24, 0, 1],
547
- [1, x, x**2, x**3, 0, 0],
548
- [0, 1, 2 * x, 3 * x**2, 0, 0],
549
- [0, -1, -2 * x, H54, 0, 0],
550
- [0, 0, -2, -6 * x, 0, 0],
551
- ]
552
- )
553
-
554
- return zh
555
-
556
- def zp(self, x, phi, bed=True):
557
- """
558
- Compute bedded or free particular integrals at position x.
559
-
560
- Arguments
561
- ---------
562
- x : float
563
- Horizontal coordinate (mm).
564
- phi : float
565
- Inclination (degrees).
566
- bed : bool
567
- Indicates whether segment has foundation (True) or not
568
- (False). Default is True.
569
-
570
- Returns
571
- -------
572
- zp : ndarray
573
- Particular integral vector (6x1) at position x.
574
- """
575
- # Get weight and surface loads
576
- qn, qt = self.get_weight_load(phi)
577
- pn, pt = self.get_surface_load(phi)
578
-
579
- # Set foundation stiffnesses
580
- kn = self.kn
581
- kt = self.kt
582
-
583
- # Unpack laminate stiffnesses
584
- A11 = self.A11
585
- B11 = self.B11
586
- kA55 = self.kA55
587
- K0 = self.K0
588
-
589
- # Unpack geometric properties
590
- h = self.h
591
- t = self.t
592
- zs = self.zs
593
-
594
- # Assemble particular integral vectors
595
- if bed:
596
- zp = np.array(
597
- [
598
- [
599
- (qt + pt) / kt
600
- + h * qt * (h + t - 2 * zs) / (4 * kA55)
601
- + h * pt * (2 * h + t) / (4 * kA55)
602
- ],
603
- [0],
604
- [(qn + pn) / kn],
605
- [0],
606
- [-(qt * (h + t - 2 * zs) + pt * (2 * h + t)) / (2 * kA55)],
607
- [0],
608
- ]
609
- )
610
- else:
611
- zp = np.array(
612
- [
613
- [(-3 * (qt + pt) / A11 - B11 * (qn + pn) * x / K0) / 6 * x**2],
614
- [(-2 * (qt + pt) / A11 - B11 * (qn + pn) * x / K0) / 2 * x],
615
- [-A11 * (qn + pn) * x**4 / (24 * K0)],
616
- [-A11 * (qn + pn) * x**3 / (6 * K0)],
617
- [
618
- A11 * (qn + pn) * x**3 / (6 * K0)
619
- + ((zs - B11 / A11) * qt - h * pt / 2 - (qn + pn) * x) / kA55
620
- ],
621
- [(qn + pn) * (A11 * x**2 / (2 * K0) - 1 / kA55)],
622
- ]
623
- )
624
-
625
- return zp
626
-
627
- def z(self, x, C, l, phi, bed=True):
628
- """
629
- Assemble solution vector at positions x.
630
-
631
- Arguments
632
- ---------
633
- x : float or squence
634
- Horizontal coordinate (mm). Can be sequence of length N.
635
- C : ndarray
636
- Vector of constants (6xN) at positions x.
637
- l : float
638
- Segment length (mm).
639
- phi : float
640
- Inclination (degrees).
641
- bed : bool
642
- Indicates whether segment has foundation (True) or not
643
- (False). Default is True.
644
-
645
- Returns
646
- -------
647
- z : ndarray
648
- Solution vector (6xN) at position x.
649
- """
650
- if isinstance(x, (list, tuple, np.ndarray)):
651
- z = np.concatenate(
652
- [np.dot(self.zh(xi, l, bed), C) + self.zp(xi, phi, bed) for xi in x],
653
- axis=1,
654
- )
655
- else:
656
- z = np.dot(self.zh(x, l, bed), C) + self.zp(x, phi, bed)
657
-
658
- return z
weac/inverse.py DELETED
@@ -1,51 +0,0 @@
1
- """Class for the elastic analysis of layered snow slabs."""
2
- # pylint: disable=invalid-name
3
-
4
- # Project imports
5
- from weac.eigensystem import Eigensystem
6
- from weac.mixins import AnalysisMixin, FieldQuantitiesMixin, OutputMixin, SolutionMixin
7
-
8
-
9
- class Inverse(
10
- FieldQuantitiesMixin, SolutionMixin, AnalysisMixin, OutputMixin, Eigensystem
11
- ):
12
- """
13
- Fit the elastic properties of the layers of a snowpack.
14
-
15
- Allows for the inverse identification of the elastic properties
16
- of the layers of a snowpack from full-field displacement
17
- measurements.
18
-
19
- Inherits methods for the eigensystem calculation from the base
20
- class Eigensystem(), methods for the calculation of field
21
- quantities from FieldQuantitiesMixin(), methods for the solution
22
- of the system from SolutionMixin() and methods for the output
23
- analysis from AnalysisMixin().
24
- """
25
-
26
- def __init__(self, system="pst-", layers=None, parameters=(6.0, 4.6, 0.25)):
27
- """
28
- Initialize model with user input.
29
-
30
- Arguments
31
- ---------
32
- system : str, optional
33
- Type of system to analyse. Default is 'pst-'.
34
- layers : list, optional
35
- List of layer densities and thicknesses. Default is None.
36
- parameters : tuple, optional
37
- Fitting parameters C0, C1, and Eweak. Multiplicative constant
38
- of Young modulus parametrization, exponent constant of Young
39
- modulus parametrization, and weak-layer Young modulus,
40
- respectively. Default is (6.0, 4.6, 0.25).
41
- """
42
- # Call parent __init__
43
- super().__init__(system=system)
44
-
45
- # Unpack fitting parameters
46
- C0, C1, Eweak = parameters
47
-
48
- # Set material properties and set up model
49
- self.set_beam_properties(layers=layers, C0=C0, C1=C1)
50
- self.set_foundation_properties(E=Eweak)
51
- self.calc_fundamental_system()