-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add laminate plate properties function tool (#13)
- Loading branch information
1 parent
6d6f0f8
commit 53cd5bd
Showing
21 changed files
with
678 additions
and
220 deletions.
There are no files selected for viewing
158 changes: 158 additions & 0 deletions
158
composite_calculator/lib/calculators/laminate_plate_properties_calculator.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import 'dart:math'; | ||
|
||
import 'package:composite_calculator/composite_calculator.dart'; | ||
import 'package:composite_calculator/models/in-plane-properties.dart'; | ||
import 'package:composite_calculator/utils/layup_parser.dart'; | ||
import 'package:composite_calculator/utils/matrix_to_list_extension.dart'; | ||
import 'package:linalg/linalg.dart'; | ||
import 'package:linalg/matrix.dart'; | ||
|
||
import '../models/laminate_plate_properties_input.dart'; | ||
import '../models/laminate_plate_properties_output.dart'; | ||
|
||
class LaminatePlatePropertiesCalculator { | ||
static LaminatePlatePropertiesOutput calculate( | ||
LaminatePlatePropertiesInput input) { | ||
Matrix A = Matrix.fill(3, 3); | ||
Matrix B = Matrix.fill(3, 3); | ||
Matrix D = Matrix.fill(3, 3); | ||
|
||
double e1 = input.E1; | ||
double e2 = input.E2; | ||
double g12 = input.G12; | ||
double nu12 = input.nu12; | ||
double thickness = input.layerThickness; | ||
String layupSequence = input.layupSequence; | ||
List<double> layups = LayupParser.parse(layupSequence) ?? []; | ||
int nPly = layups.length; | ||
|
||
List<double> bzi = []; | ||
for (int i = 1; i <= nPly; i++) { | ||
double bz = (-(nPly + 1) * thickness) / 2 + i * thickness; | ||
bzi.add(bz); | ||
} | ||
for (int i = 0; i < nPly; i++) { | ||
double layup = layups[i]; | ||
|
||
double angleRadian = layup * pi / 180; | ||
double s = sin(angleRadian); | ||
double c = cos(angleRadian); | ||
|
||
Matrix Sep = Matrix([ | ||
[1 / e1, -nu12 / e1, 0], | ||
[-nu12 / e1, 1 / e2, 0], | ||
[0, 0, 1 / g12] | ||
]); | ||
|
||
Matrix Qep = Sep.inverse(); | ||
|
||
Matrix Rsigmae = Matrix([ | ||
[c * c, s * s, -2 * s * c], | ||
[s * s, c * c, 2 * s * c], | ||
[s * c, -s * c, c * c - s * s] | ||
]); | ||
|
||
Matrix Qe = Rsigmae * Qep * Rsigmae.transpose(); | ||
|
||
A += Qe * thickness; | ||
B += Qe * thickness * bzi[i]; | ||
D += Qe * (thickness * bzi[i] * bzi[i] + pow(thickness, 3) / 12); | ||
} | ||
|
||
LaminatePlatePropertiesOutput output = LaminatePlatePropertiesOutput( | ||
A: A.toListOfLists(), | ||
B: B.toListOfLists(), | ||
D: D.toListOfLists(), | ||
); | ||
|
||
double h = nPly * thickness; | ||
|
||
Matrix Ses = A.inverse() * h; | ||
Matrix Sesf = D.inverse() * (pow(h, 3) / 12); | ||
|
||
output.inPlaneProperties = InPlaneProperties( | ||
analysisType: input.analysisType, | ||
E1: 1 / Ses[0][0], | ||
E2: 1 / Ses[1][1], | ||
G12: 1 / Ses[2][2], | ||
nu12: -1 / Ses[0][0] * Ses[0][1], | ||
eta121: -1 / Ses[2][2] * Ses[0][2], | ||
eta122: -1 / Ses[2][2] * Ses[1][2], | ||
); | ||
|
||
output.flexuralProperties = InPlaneProperties( | ||
analysisType: input.analysisType, | ||
E1: 1 / Sesf[0][0], | ||
E2: 1 / Sesf[1][1], | ||
G12: 1 / Sesf[2][2], | ||
nu12: -1 / Sesf[0][0] * Sesf[0][1], | ||
eta121: -1 / Sesf[2][2] * Sesf[0][2], | ||
eta122: -1 / Sesf[2][2] * Sesf[1][2], | ||
); | ||
|
||
if (input.analysisType == AnalysisType.thermalElastic) { | ||
double alpha11 = input.alpha11; | ||
double alpha22 = input.alpha22; | ||
double alpha12 = input.alpha12; | ||
|
||
Matrix temp_eff = Matrix.fill(3, 1); | ||
Matrix temp_flex = Matrix.fill(3, 1); | ||
|
||
for (int i = 0; i < nPly; i++) { | ||
double layup = layups[i]; | ||
|
||
double angleRadian = layup * pi / 180; | ||
double s = sin(angleRadian); | ||
double c = cos(angleRadian); | ||
|
||
Matrix Sep = Matrix([ | ||
[1 / e1, -nu12 / e1, 0], | ||
[-nu12 / e1, 1 / e2, 0], | ||
[0, 0, 1 / g12] | ||
]); | ||
|
||
Matrix Qep = Sep.inverse(); | ||
|
||
Matrix Rsigmae = Matrix([ | ||
[c * c, s * s, -2 * s * c], | ||
[s * s, c * c, 2 * s * c], | ||
[s * c, -s * c, c * c - s * s] | ||
]); | ||
|
||
Matrix Qe = Rsigmae * Qep * Rsigmae.transpose(); | ||
|
||
Matrix R_epsilon_e = Matrix([ | ||
[c * c, s * s, -s * c], | ||
[s * s, c * c, s * c], | ||
[2 * s * c, -2 * s * c, c * c - s * s] | ||
]); | ||
|
||
Matrix cteVector = Matrix([ | ||
[alpha11], | ||
[alpha22], | ||
[2 * alpha12] | ||
]); | ||
|
||
temp_eff += Qe * R_epsilon_e * cteVector * thickness; | ||
temp_flex += Qe * | ||
R_epsilon_e * | ||
cteVector * | ||
(thickness * bzi[i] * bzi[i] + | ||
thickness * thickness * thickness / 12); | ||
} | ||
|
||
Matrix cteVector_effective = A.inverse() * temp_eff; | ||
Matrix cteVector_flexural = D.inverse() * temp_flex; | ||
|
||
output.inPlaneProperties.alpha11 = cteVector_effective[0][0]; | ||
output.inPlaneProperties.alpha22 = cteVector_effective[1][0]; | ||
output.inPlaneProperties.alpha12 = cteVector_effective[2][0]; | ||
|
||
output.flexuralProperties.alpha11 = cteVector_flexural[0][0]; | ||
output.flexuralProperties.alpha22 = cteVector_flexural[1][0]; | ||
output.flexuralProperties.alpha12 = cteVector_flexural[2][0]; | ||
} | ||
|
||
return output; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,12 @@ | ||
export 'models/analysis_type.dart'; | ||
|
||
export 'models/lamina_engineering_constants_input.dart'; | ||
export 'models/lamina_engineering_constants_output.dart'; | ||
export 'calculators/lamina_engineering_constants_calculator.dart'; | ||
export 'models/lamina_stress_strain_input.dart'; | ||
export 'models/lamina_stress_strain_output.dart'; | ||
export 'models/laminate_plate_properties_input.dart'; | ||
export 'models/laminate_plate_properties_output.dart'; | ||
|
||
export 'calculators/lamina_engineering_constants_calculator.dart'; | ||
export 'calculators/lamina_stress_strain_calculator.dart'; | ||
export 'calculators/laminate_plate_properties_calculator.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import 'analysis_type.dart'; | ||
|
||
class InPlaneProperties { | ||
AnalysisType analysisType; | ||
double E1; | ||
double E2; | ||
double G12; | ||
double nu12; | ||
double eta121; | ||
double eta122; | ||
double alpha11; | ||
double alpha22; | ||
double alpha12; | ||
|
||
InPlaneProperties({ | ||
this.analysisType = AnalysisType.elastic, | ||
this.E1 = 0, | ||
this.E2 = 0, | ||
this.G12 = 0, | ||
this.nu12 = 0, | ||
this.eta121 = 0, | ||
this.eta122 = 0, | ||
this.alpha11 = 0, | ||
this.alpha22 = 0, | ||
this.alpha12 = 0, | ||
}); | ||
|
||
Map<String, dynamic> toJson() { | ||
Map<String, dynamic> result = { | ||
'E1': E1, | ||
'E2': E2, | ||
'G12': G12, | ||
'nu12': nu12, | ||
'eta121': eta121, | ||
'eta122': eta122, | ||
}; | ||
if (analysisType == AnalysisType.thermalElastic) { | ||
result.addAll({ | ||
'alpha11': alpha11, | ||
'alpha22': alpha22, | ||
'alpha12': alpha12, | ||
}); | ||
} | ||
return result; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
composite_calculator/lib/models/laminate_plate_properties_input.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import 'analysis_type.dart'; | ||
|
||
class LaminatePlatePropertiesInput { | ||
AnalysisType analysisType; | ||
double E1; | ||
double E2; | ||
double G12; | ||
double nu12; | ||
String layupSequence; | ||
double layerThickness; | ||
|
||
double alpha11; | ||
double alpha22; | ||
double alpha12; | ||
|
||
LaminatePlatePropertiesInput({ | ||
this.analysisType = AnalysisType.elastic, | ||
this.E1 = 0, | ||
this.E2 = 0, | ||
this.G12 = 0, | ||
this.nu12 = 0, | ||
this.layupSequence = "", | ||
this.layerThickness = 0, | ||
this.alpha11 = 0, | ||
this.alpha22 = 0, | ||
this.alpha12 = 0, | ||
}); | ||
|
||
// Factory method to create an instance with default values | ||
factory LaminatePlatePropertiesInput.withDefaults() { | ||
return LaminatePlatePropertiesInput( | ||
E1: 150000, | ||
E2: 10000, | ||
G12: 5000, | ||
nu12: 0.3, | ||
layupSequence: "[0/90/45/-45]s", | ||
layerThickness: 0.125 | ||
); | ||
} | ||
|
||
Map<String, dynamic> toJson() { | ||
return { | ||
'analysis_type': analysisType.toJson(), | ||
'E1': E1, | ||
'E2': E2, | ||
'G12': G12, | ||
'nu12': nu12, | ||
'layup_sequence': layupSequence, | ||
'layer_thickness': layerThickness, | ||
'alpha11': alpha11, | ||
'alpha22': alpha22, | ||
'alpha12': alpha12, | ||
}; | ||
} | ||
|
||
// Factory method to create an instance from a JSON map | ||
factory LaminatePlatePropertiesInput.fromJson(Map<String, dynamic> json) { | ||
return LaminatePlatePropertiesInput( | ||
analysisType: AnalysisType.values.firstWhere( | ||
(e) => | ||
e.toString() == | ||
'AnalysisType.' + (json['analysis_type'] ?? "elastic"), | ||
orElse: () => AnalysisType.elastic, // Default value if not found | ||
), | ||
E1: (json['E1'] ?? 0).toDouble(), | ||
E2: (json['E2'] ?? 0).toDouble(), | ||
G12: (json['G12'] ?? 0).toDouble(), | ||
nu12: (json['nu12'] ?? 0).toDouble(), | ||
layupSequence: (json['layup_sequence'] ?? "").toString(), | ||
layerThickness: (json['layer_thickness'] ?? 0).toDouble(), | ||
alpha11: (json['alpha11'] ?? 0).toDouble(), | ||
alpha22: (json['alpha22'] ?? 0).toDouble(), | ||
alpha12: (json['alpha12'] ?? 0).toDouble(), | ||
); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
composite_calculator/lib/models/laminate_plate_properties_output.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import 'package:composite_calculator/models/in-plane-properties.dart'; | ||
|
||
class LaminatePlatePropertiesOutput { | ||
List<List<double>> A; | ||
List<List<double>> B; | ||
List<List<double>> D; | ||
|
||
InPlaneProperties inPlaneProperties; | ||
InPlaneProperties flexuralProperties; | ||
|
||
LaminatePlatePropertiesOutput({ | ||
this.A = const [], | ||
this.B = const [], | ||
this.D = const [], | ||
InPlaneProperties? inPlaneProperties, | ||
InPlaneProperties? flexuralProperties, | ||
}) : inPlaneProperties = inPlaneProperties ?? InPlaneProperties(), | ||
flexuralProperties = flexuralProperties ?? InPlaneProperties(); | ||
|
||
Map<String, dynamic> toJson() { | ||
return { | ||
'A': A, | ||
'B': B, | ||
'D': D, | ||
'in-plane_properties': inPlaneProperties, | ||
'flexural_properties': flexuralProperties, | ||
}; | ||
} | ||
} |
Oops, something went wrong.