Skip to content

Commit

Permalink
Add laminate plate properties function tool (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
banghuazhao authored Oct 12, 2024
1 parent 6d6f0f8 commit 53cd5bd
Show file tree
Hide file tree
Showing 21 changed files with 678 additions and 220 deletions.
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;
}
}
10 changes: 9 additions & 1 deletion composite_calculator/lib/composite_calculator.dart
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';
46 changes: 46 additions & 0 deletions composite_calculator/lib/models/in-plane-properties.dart
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;
}
}
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(),
);
}
}
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,
};
}
}
Loading

0 comments on commit 53cd5bd

Please sign in to comment.