Skip to content

Commit

Permalink
Add lamina stress strain function tools
Browse files Browse the repository at this point in the history
  • Loading branch information
banghuazhao committed Oct 8, 2024
1 parent 0cdb9b9 commit 84c8cee
Show file tree
Hide file tree
Showing 15 changed files with 578 additions and 176 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import 'dart:math';

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

import '../models/lamina_stress_strain_input.dart';
import '../models/lamina_stress_strain_output.dart';

class LaminaStressStrainCalculator {
static LaminaStressStrainOutput calculate(LaminaStressStrainInput input) {
double e1 = input.E1;
double e2 = input.E2;
double g12 = input.G12;
double nu12 = input.nu12;
double layupAngle = input.layupAngle;

double alpha11 = input.alpha11;
double alpha22 = input.alpha22;
double alpha12 = input.alpha12;
double deltaT = input.deltaT;

double angleRadian = layupAngle * pi / 180;
double s = sin(angleRadian);
double c = cos(angleRadian);

var S = Matrix([
[1 / e1, -nu12 / e1, 0],
[-nu12 / e1, 1 / e2, 0],
[0, 0, 1 / g12]
]);
var Q = S.inverse();

Matrix T_epsilon = Matrix([
[c * c, s * s, -s * c],
[s * s, c * c, s * c],
[2 * s * c, -2 * s * c, c * c - s * s]
]);

Matrix T_sigma = Matrix([
[c * c, s * s, -2 * s * c],
[s * s, c * c, 2 * s * c],
[s * c, -s * c, c * c - s * s]
]);

Matrix Q_bar = T_sigma.transpose() * Q * T_sigma;
Matrix S_bar = T_epsilon.transpose() * S * T_epsilon;

TensorType tensorType = input.tensorType;
AnalysisType analysisType = input.analysisType;

if (tensorType == TensorType.stress) {
double sigma11 = input.sigma11;
double sigma22 = input.sigma22;
double sigma12 = input.sigma12;
var stressVector = Matrix([
[sigma11],
[sigma22],
[sigma12]
]);

Matrix strainVector;
if (analysisType == AnalysisType.elastic) {
strainVector = S_bar * stressVector;
} else {
double alpha11DeltaT = alpha11 * deltaT;
double alpha22DeltaT = alpha22 * deltaT;
double alpha12DeltaT = alpha12 * deltaT;
var cteVector = Matrix([
[alpha11DeltaT],
[alpha22DeltaT],
[2 * alpha12DeltaT]
]);
var 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]
]);
strainVector = S_bar * stressVector + R_epsilon_e * cteVector;
}
return LaminaStressStrainOutput(
tensorType: TensorType.strain,
epsilon11: strainVector[0][0],
epsilon22: strainVector[1][0],
gamma12: strainVector[2][0]);
} else {
double epsilon11 = input.epsilon11;
double epsilon22 = input.epsilon22;
double gamma12 = input.gamma12;
var strainVector = Matrix([
[epsilon11],
[epsilon22],
[gamma12]
]);

Matrix stressVector;
if (analysisType == AnalysisType.elastic) {
stressVector = Q_bar * strainVector;
} else {
double alpha11DeltaT = alpha11 * deltaT;
double alpha22DeltaT = alpha22 * deltaT;
double alpha12DeltaT = alpha12 * deltaT;
var cteVector = Matrix([
[alpha11DeltaT],
[alpha22DeltaT],
[2 * alpha12DeltaT]
]);
var 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]
]);
stressVector = Q_bar * (strainVector - R_epsilon_e * cteVector);
}
return LaminaStressStrainOutput(
tensorType: TensorType.stress,
sigma11: stressVector[0][0],
sigma22: stressVector[1][0],
sigma12: stressVector[2][0]);
}
}
}
111 changes: 111 additions & 0 deletions composite_calculator/lib/models/lamina_stress_strain_input.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import 'package:composite_calculator/models/analysis_type.dart';
import 'package:composite_calculator/models/tensor_type.dart';

class LaminaStressStrainInput {
AnalysisType analysisType;
double E1;
double E2;
double G12;
double nu12;
double layupAngle;

double alpha11;
double alpha22;
double alpha12;
double deltaT;

TensorType tensorType;

double sigma11;
double sigma22;
double sigma12;

double epsilon11;
double epsilon22;
double gamma12;

LaminaStressStrainInput({
this.analysisType = AnalysisType.elastic,
this.E1 = 0,
this.E2 = 0,
this.G12 = 0,
this.nu12 = 0,
this.layupAngle = 0,
this.alpha11 = 0,
this.alpha22 = 0,
this.alpha12 = 0,
this.deltaT = 0,
this.tensorType = TensorType.stress,
this.sigma11 = 0,
this.sigma22 = 0,
this.sigma12 = 0,
this.epsilon11 = 0,
this.epsilon22 = 0,
this.gamma12 = 0,
});

// Factory method to create an instance with default values
factory LaminaStressStrainInput.withDefaults() {
return LaminaStressStrainInput(
E1: 150000,
E2: 10000,
G12: 5000,
nu12: 0.3,
layupAngle: 45,
sigma11: 0.1,
);
}

Map<String, dynamic> toJson() {
return {
'analysis_type': analysisType.toJson(),
'E1': E1,
'E2': E2,
'G12': G12,
'nu12': nu12,
'layup_angle': layupAngle,
'alpha11': alpha11,
'alpha22': alpha22,
'alpha12': alpha12,
'deltaT': deltaT,
'tensorType': tensorType,
'sigma11': sigma11,
'sigma22': sigma22,
'sigma12': sigma12,
'epsilon11': epsilon11,
'epsilon22': epsilon22,
'gamma12': gamma12,
};
}

// Factory method to create an instance from a JSON map
factory LaminaStressStrainInput.fromJson(Map<String, dynamic> json) {
return LaminaStressStrainInput(
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(),
layupAngle: (json['layup_angle'] ?? 0).toDouble(),
alpha11: (json['alpha11'] ?? 0).toDouble(),
alpha22: (json['alpha22'] ?? 0).toDouble(),
alpha12: (json['alpha12'] ?? 0).toDouble(),
deltaT: (json['deltaT'] ?? 0).toDouble(),
tensorType: TensorType.values.firstWhere(
(e) => e.toString() == 'TensorType.' + (json['tensorType'] ?? 'stress'),
orElse: () => TensorType.stress, // Default value if not found
),
sigma11: (json['sigma11'] ?? 0).toDouble(),
sigma22: (json['sigma22'] ?? 0).toDouble(),
sigma12: (json['sigma12'] ?? 0).toDouble(),
epsilon11: (json['epsilon11'] ?? 0).toDouble(),
epsilon22: (json['epsilon22'] ?? 0).toDouble(),
gamma12: (json['gamma12'] ?? 0).toDouble(),
);
}
}
51 changes: 51 additions & 0 deletions composite_calculator/lib/models/lamina_stress_strain_output.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:composite_calculator/models/analysis_type.dart';
import 'package:composite_calculator/models/tensor_type.dart';

class LaminaStressStrainOutput {
TensorType tensorType;

double sigma11;
double sigma22;
double sigma12;

double epsilon11;
double epsilon22;
double gamma12;

List<List<double>> Q;
List<List<double>> S;

LaminaStressStrainOutput({
this.tensorType = TensorType.stress,
this.sigma11 = 0,
this.sigma22 = 0,
this.sigma12 = 0,
this.epsilon11 = 0,
this.epsilon22 = 0,
this.gamma12 = 0,
List<List<double>>? Q, // Make it nullable and initialize later
List<List<double>>? S, // Make it nullable and initialize later
}) : Q = Q ?? [],
S = S ?? [];

Map<String, dynamic> toJson() {
Map<String, dynamic> result = {
'Q': Q,
'S': S,
};
if (tensorType == TensorType.stress) {
result.addAll({
'sigma11': sigma11,
'sigma22': sigma22,
'sigma12': sigma12,
});
} else {
result.addAll({
'epsilon11': epsilon11,
'epsilon22': epsilon22,
'gamma12': gamma12,
});
}
return result;
}
}
14 changes: 14 additions & 0 deletions composite_calculator/lib/models/tensor_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
enum TensorType {
stress,
strain;

// Method to convert enum to JSON-friendly string
String toJson() {
switch (this) {
case TensorType.stress:
return 'stress';
case TensorType.strain:
return 'strain';
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'package:composite_calculator/calculators/lamina_stress_strain_calculator.dart';
import 'package:composite_calculator/models/lamina_stress_strain_input.dart';
import 'package:composite_calculator/models/tensor_type.dart';
import 'package:flutter_test/flutter_test.dart';

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

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

expect(output.epsilon11, closeTo(2.257 * 10e-5, 1e-3));
expect(output.epsilon11, closeTo(-1.743 * 10e-5, 1e-3));
expect(output.epsilon11, closeTo(2.333 * 10e-5, 1e-3));

// Optionally check the Q and S matrices for expected values
List<List<double>> expectedQ = [
[43000.503, 40500.503, -70422.535],
[40500.503, 43000.503, -70422.535],
[-70422.535, -70422.535, 154929.577]
];

for (int i = 0; i < output.Q.length; i++) {
for (int j = 0; j < output.Q[i].length; j++) {
expect(output.Q[i][j], closeTo(expectedQ[i][j], 1e-3));
}
}
});

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

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

expect(output.sigma11, closeTo(4.3e-1, 1e-3));
expect(output.sigma22, closeTo(4.05e-1, 1e-3));
expect(output.sigma12, closeTo(-7.042e-1, 1e-3));

// Optionally check the Q and S matrices for expected values
List<List<double>> expectedQ = [
[43000.503, 40500.503, -70422.535],
[40500.503, 43000.503, -70422.535],
[-70422.535, -70422.535, 154929.577]
];

for (int i = 0; i < output.Q.length; i++) {
for (int j = 0; j < output.Q[i].length; j++) {
expect(output.Q[i][j], closeTo(expectedQ[i][j], 1e-3));
}
}
});

test('Custom input test case', () {
// Arrange: Create custom input data
var input = LaminaStressStrainInput(
E1: 200000,
E2: 12000,
G12: 6000,
nu12: 0.25,
layupAngle: 30,
tensorType: TensorType.strain,
epsilon11: 1e-5);

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

expect(output.sigma11, closeTo(1.159, 1e-3));
expect(output.sigma22, closeTo(4.066e-1, 1e-3));
expect(output.sigma12, closeTo(-1.252, 1e-3));
});
});
}
Loading

0 comments on commit 84c8cee

Please sign in to comment.