-
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 lamina stress strain function tools
- Loading branch information
1 parent
0cdb9b9
commit 84c8cee
Showing
15 changed files
with
578 additions
and
176 deletions.
There are no files selected for viewing
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 |
---|---|---|
|
@@ -32,7 +32,6 @@ | |
/build/ | ||
|
||
# Web related | ||
lib/generated_plugin_registrant.dart | ||
|
||
# Symbolication related | ||
app.*.symbols | ||
|
123 changes: 123 additions & 0 deletions
123
composite_calculator/lib/calculators/lamina_stress_strain_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,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
111
composite_calculator/lib/models/lamina_stress_strain_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,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
51
composite_calculator/lib/models/lamina_stress_strain_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,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; | ||
} | ||
} |
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,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'; | ||
} | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
composite_calculator/test/lamina_stress_strain_calculator_tests.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,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)); | ||
}); | ||
}); | ||
} |
Oops, something went wrong.