Skip to content

Commit

Permalink
Add laminate 3d properties function tool (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
banghuazhao authored Oct 13, 2024
1 parent 8857636 commit fb22db0
Show file tree
Hide file tree
Showing 12 changed files with 562 additions and 144 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'dart:math';

import 'package:composite_calculator/composite_calculator.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_3d_properties_input.dart';
import '../models/laminate_3d_properties_output.dart';

class Laminate3DPropertiesCalculator {
static Laminate3DPropertiesOutput calculate(
Laminate3DPropertiesInput input) {
double thickness = input.layerThickness;
List<double> layups = LayupParser.parse(input.layupSequence) ?? [];
int nPly = layups.length;
double e1 = input.E1;
double e2 = input.E2;
double g12 = input.G12;
double nu12 = input.nu12;
double nu23 = input.nu23;
double e3 = e2;
double g13 = g12;
double g23 = e2 / (2 * (1 + nu23));
double nu13 = nu12;

List<double> bzi = [];
for (int i = 1; i <= nPly; i++) {
double bz = (-(nPly + 1) * thickness) / 2 + i * thickness;
bzi.add(bz);
}

Matrix C = Matrix.fill(6, 6);
Matrix alpha_temp = Matrix.fill(3, 1);
Matrix Q_start = Matrix.fill(3, 3);

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 Sp = Matrix([
[1 / e1, -nu12 / e1, -nu13 / e1, 0, 0, 0],
[-nu12 / e1, 1 / e2, -nu23 / e2, 0, 0, 0],
[-nu13 / e1, -nu23 / e2, 1 / e3, 0, 0, 0],
[0, 0, 0, 1 / g23, 0, 0],
[0, 0, 0, 0, 1 / g13, 0],
[0, 0, 0, 0, 0, 1 / g12]
]);

Matrix Cp = Sp.inverse();

Matrix Rsigma = Matrix([
[c * c, s * s, 0, 0, 0, -2 * s * c],
[s * s, c * c, 0, 0, 0, 2 * s * c],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, c, s, 0],
[0, 0, 0, -s, c, 0],
[s * c, -s * c, 0, 0, 0, c * c - s * s]
]);
Matrix C_single = Rsigma * Cp * Rsigma.transpose();
C += C_single;

if (input.analysisType == AnalysisType.thermalElastic) {
double alpha11 = input.alpha11;
double alpha22 = input.alpha22;
double alpha12 = input.alpha12;
Matrix cteVector = Matrix([
[alpha11],
[alpha22],
[2 * alpha12]
]);
Matrix S_single = C_single.inverse();
Matrix Se = Matrix([
[S_single[0][0], S_single[0][1], S_single[0][5]],
[S_single[0][1], S_single[1][1], S_single[1][5]],
[S_single[0][5], S_single[1][5], S_single[5][5]]
]);
Matrix Q = Se.inverse();
Q_start += Q;

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]
]);

alpha_temp += Q * R_epsilon_e * cteVector;
}
}

C = C * (1 / nPly);
Matrix S = C.inverse();

Laminate3DPropertiesOutput output = Laminate3DPropertiesOutput();
output.stiffness = C.toListOfLists();
output.compliance = S.toListOfLists();

output.engineeringConstants["E1"] = 1 / S[0][0];
output.engineeringConstants["E2"] = 1 / S[1][1];
output.engineeringConstants["E3"] = 1 / S[2][2];
output.engineeringConstants["G12"] = 1 / S[5][5];
output.engineeringConstants["G13"] = 1 / S[4][4];
output.engineeringConstants["G23"] = 1 / S[3][3];
output.engineeringConstants["nu12"] = -1 / S[0][0] * S[0][1];
output.engineeringConstants["nu13"] = -1 / S[0][0] * S[0][2];
output.engineeringConstants["nu23"] = -1 / S[1][1] * S[1][2];

if (input.analysisType == AnalysisType.thermalElastic) {
Q_start = Q_start * (1 / nPly);
alpha_temp = alpha_temp * (1 / nPly);
Matrix alpha_CTE = Q_start.inverse() * alpha_temp;
output.engineeringConstants["alpha11"] = alpha_CTE[0][0];
output.engineeringConstants["alpha22"] = alpha_CTE[1][0];
output.engineeringConstants["alpha12"] = alpha_CTE[2][0];
}

return output;
}
}
5 changes: 4 additions & 1 deletion composite_calculator/lib/composite_calculator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ 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 'models/laminate_3d_properties_input.dart';
export 'models/laminate_3d_properties_output.dart';

export 'calculators/lamina_engineering_constants_calculator.dart';
export 'calculators/lamina_stress_strain_calculator.dart';
export 'calculators/laminate_plate_properties_calculator.dart';
export 'calculators/laminate_plate_properties_calculator.dart';
export 'calculators/laminate_3d_properties_calculator.dart';
81 changes: 81 additions & 0 deletions composite_calculator/lib/models/laminate_3d_properties_input.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import 'analysis_type.dart';

class Laminate3DPropertiesInput {
AnalysisType analysisType;
double E1;
double E2;
double G12;
double nu12;
double nu23;
String layupSequence;
double layerThickness;

double alpha11;
double alpha22;
double alpha12;

Laminate3DPropertiesInput({
this.analysisType = AnalysisType.elastic,
this.E1 = 0,
this.E2 = 0,
this.G12 = 0,
this.nu12 = 0,
this.nu23 = 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 Laminate3DPropertiesInput.withDefaults() {
return Laminate3DPropertiesInput(
E1: 150000,
E2: 10000,
G12: 5000,
nu12: 0.3,
nu23: 0.25,
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,
'nu23' : nu23,
'layup_sequence': layupSequence,
'layer_thickness': layerThickness,
'alpha11': alpha11,
'alpha22': alpha22,
'alpha12': alpha12,
};
}

// Factory method to create an instance from a JSON map
factory Laminate3DPropertiesInput.fromJson(Map<String, dynamic> json) {
return Laminate3DPropertiesInput(
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(),
nu23: (json['nu23'] ?? 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(),
);
}
}
21 changes: 21 additions & 0 deletions composite_calculator/lib/models/laminate_3d_properties_output.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Laminate3DPropertiesOutput {
List<List<double>> stiffness;
List<List<double>> compliance;

Map<String, double> engineeringConstants;

Laminate3DPropertiesOutput({
this.stiffness = const [],
this.compliance = const [],
Map<String, double>?
engineeringConstants, // Make it nullable and initialize later
}) : engineeringConstants = engineeringConstants ?? {};

Map<String, dynamic> toJson() {
return {
'stiffness': stiffness,
'compliance': compliance,
'engineeringConstants': engineeringConstants
};
}
}
Loading

0 comments on commit fb22db0

Please sign in to comment.