awatif-fem
Version:
Awatif Finite Element Method (FEM) Solver
249 lines (230 loc) • 7.02 kB
text/typescript
import { Node, Element, NodeInputs, ElementInputs } from "./data-model";
import { deformCpp } from "./deformCpp";
describe("deformCpp", () => {
test("Bars from Logan's book example 3.9", () => {
const nodes: Node[] = [
[],
[],
[],
[],
];
const elements: Element[] = [
[],
[],
[],
];
const nodeInputs: NodeInputs = {
supports: new Map(),
loads: new Map(),
};
const elementInputs: ElementInputs = {
elasticities: new Map(),
areas: new Map(),
};
nodeInputs.supports?.set(1, [true, true, true, false, false, false]);
nodeInputs.supports?.set(2, [true, true, true, false, false, false]);
nodeInputs.supports?.set(3, [true, true, true, false, false, false]);
nodeInputs.loads?.set(0, [20, 0, 0, 0, 0, 0]);
elements.forEach((_, i) => {
elementInputs.elasticities?.set(i, 210e6);
elementInputs.areas?.set(i, 10e-4);
});
const deformOutputs = deformCpp(nodes, elements, nodeInputs, elementInputs);
expect(deformOutputs).toEqual({
deformations: new Map([
[
0,
[
0.001383724933236592, -0.000051566432467165236,
0.000060150375939849595, 0, 0, 0,
],
],
[]],
[]],
[]],
]),
reactions: new Map([
[
1,
[-18.947368421052634, 4.736842105263158, 6.31578947368421, 0, 0, 0],
],
[]],
[
3,
[
-1.0526315789473686, -4.736842105263158, -2.105263157894737, 0, 0,
0,
],
],
]),
});
});
test("Frames from Logan's book example 5.8", () => {
const nodes: Node[] = [
[],
[],
[],
[],
];
const elements: Element[] = [
[],
[],
[],
];
const nodeInputs: NodeInputs = {
supports: new Map(),
loads: new Map(),
};
const elementInputs: ElementInputs = {
elasticities: new Map(),
shearModuli: new Map(),
torsionalConstants: new Map(),
areas: new Map(),
momentsOfInertiaY: new Map(),
momentsOfInertiaZ: new Map(),
};
nodeInputs.supports?.set(1, [true, true, true, true, true, true]);
nodeInputs.supports?.set(2, [true, true, true, true, true, true]);
nodeInputs.supports?.set(3, [true, true, true, true, true, true]);
nodeInputs.loads?.set(0, [0, -200e3, 0, -100e3, 0, 0]);
elements.forEach((_, i) => {
elementInputs.elasticities?.set(i, 200e9);
elementInputs.shearModuli?.set(i, 60e9);
elementInputs.momentsOfInertiaZ?.set(i, 40e-6);
elementInputs.momentsOfInertiaY?.set(i, 40e-6);
elementInputs.torsionalConstants?.set(i, 20e-6);
elementInputs.areas?.set(i, 6.25e-3);
});
const deformOutputs = deformCpp(nodes, elements, nodeInputs, elementInputs);
// Expected values (kept from original test for toBeCloseTo comparison)
const expectedDeformations = new Map([
[
0,
[
0.0000017466534414748468, -0.00033564417271263484,
-0.000056507877693047675, -0.003752156183061716,
0.00001715470855495142, -0.00009935435371409366,
],
],
[]],
[]],
[]],
]);
const expectedReactions = new Map([
[
1,
[
-873.3267207374234, 1299.1563606221894, 215.43623884405807,
1801.0349678696236, -324.19036593091715, 1941.8793826628366,
],
],
[
2,
[
121.01672295760545, 30878.757283060415, 28253.938846523837,
-26591.54681802802, 96.37583632116227, 47.69008978276496,
],
],
[
3,
[
752.309997779818, 167822.08635631742, -28469.3750853679,
-23579.819070912377, -8.23426010637668, -622.4535653396727,
],
],
]);
// Compare sizes first
expect(deformOutputs.deformations.size).toEqual(expectedDeformations.size);
expect(deformOutputs.reactions.size).toEqual(expectedReactions.size);
// Compare deformations using toBeCloseTo
deformOutputs.deformations.forEach((actualDef, nodeIndex) => {
const expectedDef = expectedDeformations.get(nodeIndex);
expect(expectedDef).toBeDefined(); // Ensure the node exists in expected
actualDef.forEach((val, i) => {
expect(val).toBeCloseTo(expectedDef[i], 8); // Use 8 decimal places for tolerance
});
});
// Compare reactions using toBeCloseTo
deformOutputs.reactions.forEach((actualReact, nodeIndex) => {
const expectedReact = expectedReactions.get(nodeIndex);
expect(expectedReact).toBeDefined(); // Ensure the node exists in expected
actualReact.forEach((val, i) => {
expect(val).toBeCloseTo(expectedReact[i], 8); // Use 8 decimal places for tolerance
});
});
});
test("Plate", () => {
const nodes: Node[] = [
[],
[],
[],
[],
[],
];
const elements: Element[] = [
[],
[],
];
const fixedSupport = [true, true, true, true, true, true] as any;
const nodeInputs: NodeInputs = {
supports: new Map([
[],
[],
[],
[],
]),
loads: new Map([[2, [0, 0, -1, 0, 0, 0]]]),
};
const elementInputs: ElementInputs = {
elasticities: new Map(elements.map((_, i) => [i, 10])),
thicknesses: new Map(elements.map((_, i) => [i, 1])),
poissonsRatios: new Map(elements.map((_, i) => [i, 0.3])),
};
const deformOutputs = deformCpp(nodes, elements, nodeInputs, elementInputs);
expect(deformOutputs).toEqual({
deformations: new Map([
[]],
[]],
[
2,
[
0, 0, -1.3467100041517628, 0.2006829256574201, -0.08312558954401499,
0,
],
],
[]],
[]],
]),
reactions: new Map([
[
0,
[
0, 0, 0.36780676281428193, 0.11886720202236686, 0.9739614221402426,
0,
],
],
[
1,
[
0, 0, 0.13219323718571813, 0.14298603128138881, 0.5624946747141107,
0,
],
],
[
3,
[
0, 0, 0.13219323718571813, -0.29663740653764714,
-0.4988501912056905, 0,
],
],
[
4,
[
0, 0, 0.367806762814282, -0.6046429215987722, -0.7727465308201459,
0,
],
],
]),
});
});
});