Skip to content

Commit

Permalink
Create composite calculator package and lamina engineering constants …
Browse files Browse the repository at this point in the history
…function calling
  • Loading branch information
banghuazhao committed Oct 6, 2024
1 parent c89a73d commit 0cdb9b9
Show file tree
Hide file tree
Showing 18 changed files with 456 additions and 190 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import 'dart:math';

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

import '../models/lamina_engineering_constants_input.dart';
import '../models/lamina_engineering_constants_output.dart';

class LaminaEngineeringConstantsCalculator {
static LaminaEngineeringConstantsOutput calculate(
LaminaEngineeringConstantsInput input) {
double e1 = input.E1;
double e2 = input.E2;
double g12 = input.G12;
double nu12 = input.nu12;
double layupAngle = input.layupAngle;

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;

double E_x = 1 / S_bar[0][0];
double E_y = 1 / S_bar[1][1];
double G_xy = 1 / S_bar[2][2];
double nu_xy = -S_bar[0][1] * E_x;
double eta_x_xy = S_bar[2][0] * E_x;
double eta_y_xy = S_bar[2][1] * E_y;

LaminaEngineeringConstantsOutput output = LaminaEngineeringConstantsOutput(
analysisType: input.analysisType,
E1: E_x,
E2: E_y,
G12: G_xy,
nu12: nu_xy,
eta1_12: eta_x_xy,
eta2_12: eta_y_xy,
Q: Q_bar.toListOfLists(),
S: S_bar.toListOfLists());

if (input.analysisType == AnalysisType.thermalElastic) {
double alpha11 = input.alpha11;
double alpha22 = input.alpha22;
double alpha12 = input.alpha12;

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]
]);
Matrix alpha_p = R_epsilon_e * cteVector;
double alpha_xx = alpha_p[0][0];
double alpha_yy = alpha_p[1][0];
double alpha_xy = alpha_p[2][0] / 2;
output.alpha_11 = alpha_xx;
output.alpha_22 = alpha_yy;
output.alpha_12 = alpha_xy;
}

return output;
}
}
11 changes: 4 additions & 7 deletions composite_calculator/lib/composite_calculator.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
library composite_calculator;

/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
}
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';
14 changes: 14 additions & 0 deletions composite_calculator/lib/models/analysis_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
enum AnalysisType {
elastic,
thermalElastic;

// Method to convert enum to JSON-friendly string
String toJson() {
switch (this) {
case AnalysisType.elastic:
return 'elastic';
case AnalysisType.thermalElastic:
return 'thermalElastic';
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import 'package:composite_calculator/models/analysis_type.dart';

class LaminaEngineeringConstantsInput {
final double E1;
final double E2;
final double G12;
final double nu12;
final double layupAngle;
AnalysisType analysisType;
double E1;
double E2;
double G12;
double nu12;
double layupAngle;

double alpha11;
double alpha22;
double alpha12;

LaminaEngineeringConstantsInput({
required this.E1,
required this.E2,
required this.G12,
required this.nu12,
required this.layupAngle,
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,
});

// Factory method to create an instance with default values
Expand All @@ -26,11 +37,35 @@ class LaminaEngineeringConstantsInput {

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,
};
}
}

// Factory method to create an instance from a JSON map
factory LaminaEngineeringConstantsInput.fromJson(Map<String, dynamic> json) {
return LaminaEngineeringConstantsInput(
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(),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:composite_calculator/models/analysis_type.dart';

class LaminaEngineeringConstantsOutput {
AnalysisType analysisType;

double E1;
double E2;
double G12;
double nu12;
double eta1_12;
double eta2_12;
List<List<double>> Q;
List<List<double>> S;

double alpha_11 = 0;
double alpha_22 = 0;
double alpha_12 = 0;

LaminaEngineeringConstantsOutput({
this.analysisType = AnalysisType.elastic,
this.E1 = 0,
this.E2 = 0,
this.G12 = 0,
this.nu12 = 0,
this.eta1_12 = 0,
this.eta2_12 = 0,
List<List<double>>? Q, // Make it nullable and initialize later
List<List<double>>? S, // Make it nullable and initialize later
this.alpha_11 = 0,
this.alpha_22 = 0,
this.alpha_12 = 0,
}) : Q = Q ?? [],
S = S ?? [];

Map<String, dynamic> toJson() {
Map<String, dynamic> result = {
'analysis_type': analysisType.toJson(),
'E_1': E1,
'E_2': E2,
'G_12': G12,
'nu_12': nu12,
'eta_1_12': eta1_12,
'eta_2_12': eta2_12,
'Q': Q,
'S': S,
};
if (analysisType == AnalysisType.thermalElastic) {
result.addAll({
'alpha_11': alpha_11,
'alpha_22': alpha_22,
'alpha_12': alpha_12,
});
}
return result;
}
}
16 changes: 16 additions & 0 deletions composite_calculator/lib/utils/matrix_to_list_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:linalg/linalg.dart';

// Extension on Matrix class to convert it to a List<List<double>>
extension MatrixToListExtension on Matrix {
List<List<double>> toListOfLists() {
List<List<double>> list = [];
for (int i = 0; i < this.m; i++) {
List<double> row = [];
for (int j = 0; j < this.n; j++) {
row.add(this[i][j]);
}
list.add(row);
}
return list;
}
}
2 changes: 2 additions & 0 deletions composite_calculator/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ environment:
dependencies:
flutter:
sdk: flutter
linalg: ^0.4.0

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
test: ^1.16.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
12 changes: 0 additions & 12 deletions composite_calculator/test/composite_calculator_test.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:composite_calculator/calculators/lamina_engineering_constants_calculator.dart';
import 'package:composite_calculator/models/lamina_engineering_constants_input.dart';
import 'package:flutter_test/flutter_test.dart';

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

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

// Assert: Check the output against expected values (you will need to provide real expected values here)
expect(output.E1, closeTo(4431.314, 1e-3));
expect(output.E2, closeTo(4431.314, 1e-3));
expect(output.G12, closeTo(36144.578, 1e-3));
expect(output.nu12, closeTo(0.77252, 1e-5));
expect(output.eta1_12, closeTo(0.10339, 1e-5));
expect(output.eta2_12, closeTo(0.10339, 1e-5));

// 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 = LaminaEngineeringConstantsInput(
E1: 200000, E2: 12000, G12: 6000, nu12: 0.25, layupAngle: 30);

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

// Assert: Check if the output matches your expected results for custom input
// Assert: Check the output against expected values (you will need to provide real expected values here)
expect(output.E1, closeTo(7544.204322200394, 1e-3));
expect(output.E2, closeTo(5823.475887170155, 1e-3));
expect(output.G12, closeTo(17036.379769299012, 1e-3));
expect(output.nu12, closeTo(0.8239685658153242, 1e-5));
expect(output.eta1_12, closeTo(0.5982210844216282, 1e-5));
expect(output.eta2_12, closeTo(-0.2642467565080819, 1e-5));

// Optionally check the Q and S matrices for expected values
List<List<double>> expectedQ = [
[115930.52070263491, 40656.68130489335, -125181.96189496155],
[40656.68130489335, 21576.693851944787, -38243.6600989902],
[-125181.96189496154, -38243.66009899021, 156581.55583437887]
];

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));
}
}
});
});
}
6 changes: 3 additions & 3 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2409171739;
CURRENT_PROJECT_VERSION = 2409292247;
DEVELOPMENT_TEAM = F694X76A5X;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand Down Expand Up @@ -492,7 +492,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2409171739;
CURRENT_PROJECT_VERSION = 2409292247;
DEVELOPMENT_TEAM = F694X76A5X;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -519,7 +519,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2409171739;
CURRENT_PROJECT_VERSION = 2409292247;
DEVELOPMENT_TEAM = F694X76A5X;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand Down
Loading

0 comments on commit 0cdb9b9

Please sign in to comment.