Skip to content

Commit

Permalink
Add laminate stress strain function tool (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
banghuazhao authored Oct 13, 2024
1 parent fb22db0 commit 0f4c7e3
Show file tree
Hide file tree
Showing 11 changed files with 657 additions and 170 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'dart:math';

import 'package:composite_calculator/models/tensor_type.dart';
import 'package:linalg/matrix.dart';

import '../models/laminar_stress_strain_input.dart';
import '../models/laminar_stress_strain_output.dart';
import '../utils/layup_parser.dart';

class LaminarStressStrainCalculator {
static LaminarStressStrainOutput calculate(LaminarStressStrainInput input) {
Matrix A = Matrix.fill(3, 3);
Matrix B = Matrix.fill(3, 3);
Matrix D = Matrix.fill(3, 3);
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;

List<double> bzi = [];
List<Matrix> Q = [];
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();

Q.add(Qe);

A += Qe * thickness;
B += Qe * thickness * bzi[i];
D += Qe * (thickness * bzi[i] * bzi[i] + pow(thickness, 3) / 12);
}

Matrix ABD = Matrix([
[A[0][0], A[0][1], A[0][2], B[0][0], B[0][1], B[0][2]],
[A[1][0], A[1][1], A[1][2], B[1][0], B[1][1], B[1][2]],
[A[2][0], A[2][1], A[2][2], B[2][0], B[2][1], B[2][2]],
[B[0][0], B[0][1], B[0][2], D[0][0], D[0][1], D[0][2]],
[B[1][0], B[1][1], B[1][2], D[1][0], D[1][1], D[1][2]],
[B[2][0], B[2][1], B[2][2], D[2][0], D[2][1], D[2][2]]
]);

Matrix ABD_inverese = ABD.inverse();

LaminarStressStrainOutput output;
if (input.tensorType == TensorType.stress) {
Matrix stressVector = Matrix([
[input.N11],
[input.N22],
[input.N12],
[input.M11],
[input.M22],
[input.M12],
]);
Matrix strainVector = ABD_inverese * stressVector;
output = LaminarStressStrainOutput(
tensorType: TensorType.strain,
epsilon11: strainVector[0][0],
epsilon22: strainVector[1][0],
epsilon12: strainVector[2][0],
kappa11: strainVector[3][0],
kappa22: strainVector[4][0],
kappa12: strainVector[5][0]);
} else {
Matrix strainVector = Matrix([
[input.epsilon11],
[input.epsilon22],
[input.epsilon12],
[input.kappa11],
[input.kappa22],
[input.kappa12]
]);
Matrix stressVector = ABD * strainVector;
output = LaminarStressStrainOutput(
tensorType: TensorType.stress,
N11: stressVector[0][0],
N22: stressVector[1][0],
N12: stressVector[2][0],
M11: stressVector[3][0],
M22: stressVector[4][0],
M12: stressVector[5][0]);
}

return output;
}

static List<Matrix> getQMatrices(LaminarStressStrainInput 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;

List<double> bzi = [];
List<Matrix> Q = [];
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();

Q.add(Qe);
}
return Q;
}
}
5 changes: 4 additions & 1 deletion composite_calculator/lib/composite_calculator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ 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 'models/laminar_stress_strain_input.dart';
export 'models/laminar_stress_strain_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_3d_properties_calculator.dart';
export 'calculators/laminate_3d_properties_calculator.dart';
export 'calculators/laminar_stress_strain_calculator.dart';
116 changes: 116 additions & 0 deletions composite_calculator/lib/models/laminar_stress_strain_input.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import 'package:composite_calculator/models/tensor_type.dart';

import 'analysis_type.dart';

class LaminarStressStrainInput {
double E1;
double E2;
double G12;
double nu12;
String layupSequence;
double layerThickness;

TensorType tensorType;

double N11;
double N22;
double N12;
double M11;
double M22;
double M12;

double epsilon11;
double epsilon22;
double epsilon12;
double kappa11;
double kappa22;
double kappa12;

LaminarStressStrainInput({
this.E1 = 0,
this.E2 = 0,
this.G12 = 0,
this.nu12 = 0,
this.layupSequence = "",
this.layerThickness = 0,
this.tensorType = TensorType.stress,
this.N11 = 0,
this.N22 = 0,
this.N12 = 0,
this.M11 = 0,
this.M22 = 0,
this.M12 = 0,
this.epsilon11 = 0,
this.epsilon22 = 0,
this.epsilon12 = 0,
this.kappa11 = 0,
this.kappa22 = 0,
this.kappa12 = 0,
});

// Factory method to create an instance with default values
factory LaminarStressStrainInput.withDefaults() {
return LaminarStressStrainInput(
E1: 150000,
E2: 10000,
G12: 5000,
nu12: 0.3,
layupSequence: "[0/90/45/-45]s",
layerThickness: 0.125,
tensorType: TensorType.stress,
N11: 1,
);
}

Map<String, dynamic> toJson() {
return {
'E1': E1,
'E2': E2,
'G12': G12,
'nu12': nu12,
'layup_sequence': layupSequence,
'layer_thickness': layerThickness,
'tensorType': tensorType,
'N11': N11,
'N22': N22,
'N12': N12,
'M11': M11,
'M22': M22,
'M12': M12,
'epsilon11': epsilon11,
'epsilon22': epsilon22,
'epsilon12': epsilon12,
'kappa11': kappa11,
'kappa22': kappa22,
'kappa12': kappa12,
};
}

// Factory method to create an instance from a JSON map
factory LaminarStressStrainInput.fromJson(Map<String, dynamic> json) {
return LaminarStressStrainInput(
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(),
tensorType: TensorType.values.firstWhere(
(e) => e.toString() == 'TensorType.' + (json['tensorType'] ?? 'stress'),
orElse: () => TensorType.stress, // Default value if not found
),
N11: (json['N11'] ?? 0).toDouble(),
N22: (json['N22'] ?? 0).toDouble(),
N12: (json['N12'] ?? 0).toDouble(),
M11: (json['M11'] ?? 0).toDouble(),
M22: (json['M22'] ?? 0).toDouble(),
M12: (json['M12'] ?? 0).toDouble(),
epsilon11: (json['epsilon11'] ?? 0).toDouble(),
epsilon22: (json['epsilon22'] ?? 0).toDouble(),
epsilon12: (json['epsilon12'] ?? 0).toDouble(),
kappa11: (json['kappa11'] ?? 0).toDouble(),
kappa22: (json['kappa22'] ?? 0).toDouble(),
kappa12: (json['kappa12'] ?? 0).toDouble(),
);
}
}
58 changes: 58 additions & 0 deletions composite_calculator/lib/models/laminar_stress_strain_output.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:composite_calculator/models/tensor_type.dart';

class LaminarStressStrainOutput {
TensorType tensorType;

double N11;
double N22;
double N12;
double M11;
double M22;
double M12;
double epsilon11;
double epsilon22;
double epsilon12;
double kappa11;
double kappa22;
double kappa12;

LaminarStressStrainOutput({
this.tensorType = TensorType.stress,
this.N11 = 0,
this.N22 = 0,
this.N12 = 0,
this.M11 = 0,
this.M22 = 0,
this.M12 = 0,
this.epsilon11 = 0,
this.epsilon22 = 0,
this.epsilon12 = 0,
this.kappa11 = 0,
this.kappa22 = 0,
this.kappa12 = 0,
});

Map<String, double> toJson() {
Map<String, double> result = {};
if (tensorType == TensorType.stress) {
result.addAll({
'N11': N11,
'N22': N22,
'N12': N12,
'M11': M11,
'M22': M22,
'M12': M12,
});
} else {
result.addAll({
'epsilon11': epsilon11,
'epsilon22': epsilon22,
'epsilon12': epsilon12,
'kappa11': kappa11,
'kappa22': kappa22,
'kappa12': kappa12,
});
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:composite_calculator/calculators/laminar_stress_strain_calculator.dart';
import 'package:composite_calculator/models/laminar_stress_strain_input.dart';
import 'package:composite_calculator/models/tensor_type.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group('LaminarStressStrainCalculator Tests', () {
test('Default input test case', () {
// Arrange: Create input data with default values
var input = LaminarStressStrainInput.withDefaults();

// Act: Calculate the output using the calculator
var output = LaminarStressStrainCalculator.calculate(input);

expect(output.epsilon11, closeTo(0.000017421124109966436, 1e-3));
expect(output.epsilon22, closeTo(-0.000005445220495508603, 1e-3));
expect(output.epsilon12, closeTo(4.712693325579657e-22, 1e-3));
expect(output.kappa11, closeTo(3.261347510124405e-22, 1e-3));
expect(output.kappa22, closeTo(-1.6068855629179688e-21, 1e-3));
expect(output.kappa12, closeTo(2.184974840156989e-22, 1e-3));

});

test('Default input test case with custom strain input', () {
// Arrange: Create input data with default values
var input = LaminarStressStrainInput.withDefaults();
input.tensorType = TensorType.strain;
input.epsilon11 = 1e-5;

// Act: Calculate the output using the calculator
var output = LaminarStressStrainCalculator.calculate(input);

expect(output.N11, closeTo(0.6361670020120725, 1e-3));
expect(output.N22, closeTo(0.19884305835010055, 1e-3));
expect(output.N12, closeTo(2.2638717237759187e-19, 1e-3));
expect(output.M11, closeTo(0, 1e-3));
expect(output.M22, closeTo(0, 1e-3));
expect(output.M12, closeTo(0, 1e-3));
});

});
}
Loading

0 comments on commit 0f4c7e3

Please sign in to comment.