Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FE - Finite Elements #68

Open
wants to merge 798 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
798 commits
Select commit Hold shift + click to select a range
b02f974
Update read-me: openSUSE Leap: from 15.4 to 15.5
Megidd Jul 11, 2023
90a0b67
Merge remote-tracking branch 'public/fe' into fe
Megidd Jul 11, 2023
e69d79c
Start an easy way to set restraints and loads
Megidd Jul 11, 2023
1251b93
Benchmark cases
Megidd Jul 11, 2023
e0e8d5b
Relocate code
Megidd Jul 11, 2023
dca95ad
Relocate code
Megidd Jul 11, 2023
0ec770e
Comment
Megidd Jul 11, 2023
01a9e95
Command line arg to specify benchmark to run
Megidd Jul 12, 2023
f3e614d
Single responsibility
Megidd Jul 12, 2023
5388066
Clear file names
Megidd Jul 12, 2023
2c36e22
Rename files
Megidd Jul 12, 2023
944dcb5
Remove outdated parameter
Megidd Jul 12, 2023
3403767
Rename func
Megidd Jul 12, 2023
f4fac53
Write custom restraints
Megidd Jul 12, 2023
2e9859a
Gravity direction and magnitude
Megidd Jul 12, 2023
1801224
Restraint function for a benchmark: square
Megidd Jul 12, 2023
bdc4dac
Update material properties for benchmarks
Megidd Jul 12, 2023
eab15dd
Update read-me
Megidd Jul 12, 2023
5452d25
Comment
Megidd Jul 12, 2023
b71f541
Avoid OpenSCAD dependency, use STL instead
Megidd Jul 12, 2023
eb9229f
Increase restraint location threshold
Megidd Jul 12, 2023
3d31507
Fix file name: typo
Megidd Jul 12, 2023
9db5832
Fix file name: typo
Megidd Jul 12, 2023
5b022e5
Remove logic that avoids repeated boundary nodes:
Megidd Jul 13, 2023
eae05b5
Remove outdated files
Megidd Jul 15, 2023
7aadd9c
Pass restraints and loads
Megidd Jul 15, 2023
1d19173
New file for restraint & load
Megidd Jul 16, 2023
7fe3442
Initialize restraints
Megidd Jul 16, 2023
a88046a
Comment
Megidd Jul 16, 2023
4158a47
Function to find node & voxel for restraint
Megidd Jul 16, 2023
9fdea44
TODO
Megidd Jul 16, 2023
15bfc45
Get ready to store voxel min & max coordinates
Megidd Jul 16, 2023
5fa5868
Identify the min & max corners for each voxel
Megidd Jul 16, 2023
83d0984
Loops to indetify node ID and voxel of restraints
Megidd Jul 16, 2023
0c5aa92
Identify node/voxel by mesh pkg
Megidd Jul 16, 2023
2aeb009
Call new methods
Megidd Jul 16, 2023
6994cf4
Methods for mesh, index buffer, voxel grid
Megidd Jul 16, 2023
be2d958
Logic to get node ID & voxel
Megidd Jul 16, 2023
98ebde8
Change logic location due to var access limits
Megidd Jul 16, 2023
e68b3b3
Write boundary to file according to new logic
Megidd Jul 16, 2023
4fe8833
Change location of logic
Megidd Jul 16, 2023
1844e7a
Set voxel dimensions explicitly
Megidd Jul 17, 2023
a992076
Fix bug? How voxel index is computed
Megidd Jul 17, 2023
dfe651b
Fix: node ID: original VB against temp VB
Megidd Jul 17, 2023
4b7a307
Logic to write point load to `inp` file
Megidd Jul 17, 2023
fbc25b4
Fix: `*CLOAD` should only be used within a STEP
Megidd Jul 17, 2023
f58671a
Multiple restraints on edge
Megidd Jul 17, 2023
ac02adc
Fix bug? Fix loop? Simplify.
Megidd Jul 17, 2023
8a4af59
Set the roller restraints for circle benchmark
Megidd Jul 18, 2023
6230432
Restraints for the pinnned end
Megidd Jul 18, 2023
88804e3
Prepare for stress concentration considerations
Megidd Jul 19, 2023
fb6334d
Rename field
Megidd Jul 20, 2023
9d94451
Get a collection of points for each restraint
Megidd Jul 20, 2023
38190dd
Collection of points for each load
Megidd Jul 20, 2023
de01691
Func: intersecting voxels with points b-box
Megidd Jul 20, 2023
c40b980
New func
Megidd Jul 20, 2023
eaa6a7f
Finish up new restraint design
Megidd Jul 20, 2023
ba79e08
Remove extra labels
Megidd Jul 20, 2023
6dd9296
Fix bug: voxel intersection check
Megidd Jul 20, 2023
ec4e0fc
Fix: only 16 node IDs per line
Megidd Jul 20, 2023
62cd845
Return error
Megidd Jul 20, 2023
e88afc7
Change the way reference node is picked
Megidd Jul 20, 2023
8bd7099
Avoid panic
Megidd Jul 20, 2023
e51dce7
Simplify index calculation from 1D to 3D
Megidd Jul 22, 2023
0bfb394
Funcs to convert 3D to 1D indexing and vice versa
Megidd Jul 22, 2023
f64b541
Try to fix 3D & 1D indexing conversion
Megidd Jul 22, 2023
975c7e7
Run example according to element config
Megidd Jul 22, 2023
1df0567
Write degrees of freedom for boundaries separately
Megidd Jul 22, 2023
9b5c24d
Remove TODO
Megidd Jul 22, 2023
8a05737
Remove `rigid body`
Megidd Jul 22, 2023
911c5bd
Do not dilate SDF, keep it as is
Megidd Jul 22, 2023
fd25ba1
Each restraint has less points in it:
Megidd Jul 22, 2023
b09e08a
Remove `rigid body` comment
Megidd Jul 22, 2023
18af312
Comment
Megidd Jul 22, 2023
8958f10
Restraints for 3rd benchmark
Megidd Jul 23, 2023
b8cbcee
Restraint for I-shaped benchmark
Megidd Jul 23, 2023
af21c8d
Fix 3rd benchmark, pipe: just increment resolution
Megidd Jul 24, 2023
2bb6740
Allow running teapot in addition to benchmarks
Megidd Jul 24, 2023
dde47a6
Increase teapot resolution: didn't solve artifact
Megidd Jul 24, 2023
df0f1d1
Test: always use point at edge middle
Megidd Jul 25, 2023
db7fd4d
Undo a method: didn't work, artifact is observed
Megidd Jul 25, 2023
c8bccc7
Make consistent with the last commit
Megidd Jul 25, 2023
c531fa3
Make consistent: 1D to 3D index conversion
Megidd Jul 25, 2023
9f8e507
Merge branch 'master' into fe
Megidd Jul 26, 2023
ea475ac
Merge branch 'master' into fe
Megidd Aug 2, 2023
bcad753
Modify according to latest master changes
Megidd Aug 2, 2023
8e416a4
Comment
Megidd Aug 2, 2023
1b3c439
Placeholder func to fix disconnections
Megidd Aug 2, 2023
01d1c3f
Count disconnected components
Megidd Aug 2, 2023
134a8c0
Revert "Count disconnected components"
Megidd Aug 2, 2023
2bdce11
Rename
Megidd Aug 2, 2023
dfe93db
Remove extra file
Megidd Aug 2, 2023
1ed0b72
Count disconnected components: at voxel grid level
Megidd Aug 2, 2023
792104d
Revert "Count disconnected components: at voxel grid level"
Megidd Aug 2, 2023
8281a18
Try breadth-first search (BFS) for disconnections
Megidd Aug 2, 2023
0c93f23
New func to get neighbor voxels
Megidd Aug 2, 2023
9c36a2c
Comment
Megidd Aug 2, 2023
46512a1
New file
Megidd Aug 2, 2023
565e5b5
Move logic to voxel package
Megidd Aug 2, 2023
247372d
Simplify map declaration
Megidd Aug 2, 2023
5dd3e6d
Fix: check if a voxel is not empty
Megidd Aug 3, 2023
47d5c2b
Simplify neighbor logic
Megidd Aug 3, 2023
abfb0fb
New func to check voxel index validity
Megidd Aug 3, 2023
2c1c3be
Rename
Megidd Aug 3, 2023
02bccb6
New file: BFS element-by-element
Megidd Aug 3, 2023
baae2ca
Rename func
Megidd Aug 3, 2023
f711267
Fix func call
Megidd Aug 3, 2023
4b8dd71
Fix func call
Megidd Aug 3, 2023
a3e65bc
Comment
Megidd Aug 3, 2023
db1bb22
Comment
Megidd Aug 3, 2023
78383c8
Element-by-element BFS
Megidd Aug 3, 2023
0544f74
Comment
Megidd Aug 3, 2023
e7ca09b
TODO
Megidd Aug 3, 2023
7cc2c1a
Complete the TODO
Megidd Aug 3, 2023
4ede385
Fix: consider neighbors in same voxel
Megidd Aug 3, 2023
e238545
Fix: some neighbor directions were missing
Megidd Aug 3, 2023
88a483f
Replace directions with loops
Megidd Aug 3, 2023
54af875
Fix: skip same element while computing neighbors
Megidd Aug 5, 2023
b30804c
Merge branch 'master' into fe
Megidd Aug 5, 2023
f94e73b
The fix that smells like a hack. Change it later.
Megidd Aug 5, 2023
3da8179
Fix bug: skip same element
Megidd Aug 5, 2023
0439a33
Fix typo
Megidd Aug 5, 2023
87125ee
Merge branch 'master' into fe
Megidd Aug 6, 2023
bf49b90
Nested loop order: make it consistent
Megidd Aug 6, 2023
d146ea2
Fix bug: compute neighbors by correct voxel
Megidd Aug 6, 2023
27f6553
Fix bug: node count can be different for neighbors
Megidd Aug 6, 2023
597392a
Merge branch 'master' into fe
Megidd Aug 7, 2023
e1dd6f0
Merge branch 'master' into fe
Megidd Aug 7, 2023
69e9f5d
Rename func
Megidd Aug 8, 2023
c7034e4
Rename func
Megidd Aug 8, 2023
bbe2c74
Rename files
Megidd Aug 8, 2023
b08ad60
Move func
Megidd Aug 8, 2023
5c6c94a
Iterate by a method
Megidd Aug 8, 2023
6b79272
Iterate by a method
Megidd Aug 8, 2023
ec7dccd
Component info
Megidd Aug 8, 2023
17b66d8
Rename file
Megidd Aug 8, 2023
02190d4
Call a method rather than using `len`
Megidd Aug 8, 2023
147277c
Delete file
Megidd Aug 8, 2023
48606da
Clean disconnected components from largest one:
Megidd Aug 8, 2023
283d8a1
Log component count after clean up
Megidd Aug 8, 2023
2f9282e
Return if no component is found
Megidd Aug 8, 2023
3985029
Merge branch 'master' into fe
Megidd Aug 10, 2023
0402742
Test linear elements:
Megidd Aug 10, 2023
4d62019
No cleanup of smaller components
Megidd Aug 10, 2023
8e02c25
Tet4: use nodes at cube edge middle
Megidd Aug 10, 2023
d9881d1
Merge branch 'master' into fe
Megidd Aug 11, 2023
729ce80
Merge branch 'master' into fe
Megidd Aug 12, 2023
e438fe7
Merge branch 'fe' of https://github.com/Megidd/sdfx into fe
Megidd Aug 12, 2023
0a8296d
Apply upstream optimization and refactor:
Megidd Aug 12, 2023
f1b5ad4
Rename
Megidd Aug 12, 2023
70c5e17
Rename
Megidd Aug 12, 2023
1847e97
Fix comment
Megidd Aug 12, 2023
9ab1574
Fix comment
Megidd Aug 12, 2023
c41c61e
TODO
Megidd Aug 12, 2023
6058f65
TODO & comment
Megidd Aug 12, 2023
b870aff
Comment
Megidd Aug 12, 2023
33132a2
Merge branch 'master' into fe
Megidd Aug 14, 2023
605400e
Merge branch 'master' into fe
Megidd Aug 17, 2023
ece77db
Merge branch 'master' into fe
Megidd Aug 18, 2023
da08e66
Merge branch 'master' into fe
Megidd Aug 19, 2023
558a460
Merge branch 'master' into fe
Megidd Aug 19, 2023
da03def
Merge branch 'master' into fe
Megidd Aug 24, 2023
b92cb4f
Test file
Megidd Aug 28, 2023
6ea5562
JSON of specs
Megidd Aug 29, 2023
33fa3c1
New type
Megidd Aug 29, 2023
103e92b
Error handling
Megidd Aug 29, 2023
e779f27
Restraints
Megidd Aug 29, 2023
4fadc7e
Restraints for next test
Megidd Aug 29, 2023
5309b55
Reformat
Megidd Aug 29, 2023
daebbbc
Restraints for next test
Megidd Aug 29, 2023
8141898
Restraints for next test
Megidd Aug 29, 2023
7eb5fe0
Teapot restraints
Megidd Aug 29, 2023
2cb2412
Loads JSON
Megidd Aug 29, 2023
cff15fe
Move types
Megidd Aug 29, 2023
dc0e6c2
Load & restraint for a test case
Megidd Aug 29, 2023
449093f
Rename
Megidd Aug 29, 2023
9d578fe
Handle args
Megidd Aug 29, 2023
9b65393
Rename
Megidd Aug 29, 2023
70c0f27
Simplify log
Megidd Aug 29, 2023
2ec21f7
Comment
Megidd Aug 29, 2023
3af06ba
Comment
Megidd Aug 29, 2023
7083e9a
Finish up API
Megidd Aug 30, 2023
1e8ba72
Always consider gravity
Megidd Aug 30, 2023
f8a1520
More clear test
Megidd Aug 30, 2023
0b9e8d4
No global var
Megidd Sep 1, 2023
8e6ce96
Test case fields: specs, restraints, loads
Megidd Sep 1, 2023
0ea304b
Consistent arg order
Megidd Sep 1, 2023
939449b
Comment
Megidd Sep 1, 2023
f5ae314
Comment
Megidd Sep 1, 2023
285afe3
Import `tetrahedron-table`
Megidd Sep 1, 2023
7f1c5b3
Pass another arg
Megidd Sep 2, 2023
ba7c241
Save result info JSON
Megidd Sep 2, 2023
5246986
Error handling
Megidd Sep 2, 2023
b684089
Error handling
Megidd Sep 2, 2023
a72521d
Avoid anonymous type
Megidd Sep 2, 2023
d580d3c
Fix bug
Megidd Sep 2, 2023
f13c802
Modify read-me file
Megidd Sep 2, 2023
fce8ef0
Modify read-me
Megidd Sep 2, 2023
bda8dbb
Update read-me
Megidd Sep 2, 2023
c9a25f8
Change API: prepare for layer-by-layer
Megidd Sep 3, 2023
4e350fc
Only one arg is passed: specs
Megidd Sep 3, 2023
88cd066
Rename
Megidd Sep 3, 2023
c1d8039
Result info contains layer count
Megidd Sep 3, 2023
5afb33e
Rename
Megidd Sep 3, 2023
a47f93f
Layer by layer result
Megidd Sep 3, 2023
9ea7588
Rename
Megidd Sep 3, 2023
08f7726
Log
Megidd Sep 3, 2023
82164eb
TODO: 3D print restraint
Megidd Sep 3, 2023
86b0905
Simplify
Megidd Sep 3, 2023
a4c26ff
Copy over another example
Megidd Sep 3, 2023
28ac064
Remove extra code from an example
Megidd Sep 3, 2023
0534b3a
Simplify for 3D print applications
Megidd Sep 3, 2023
9f9d5df
Fix: end layer is excluded
Megidd Sep 4, 2023
64a9ceb
See if gravity is needed
Megidd Sep 4, 2023
6f13da7
Gravity is always needed for 3D print analysis
Megidd Sep 4, 2023
9a7f3c7
Pass arg: gravity is needed?
Megidd Sep 4, 2023
5592f96
Comment
Megidd Sep 4, 2023
573775e
Setup load & restraint
Megidd Sep 4, 2023
8bec49f
Remove outdated statements
Megidd Sep 4, 2023
e016744
Load & restraint overhaul: a single point & voxel
Megidd Sep 4, 2023
05b1e8f
Update read-me
Megidd Sep 4, 2023
824427d
Rename
Megidd Sep 5, 2023
e2ffa51
Comment
Megidd Sep 5, 2023
a911850
Remove unnecessary statements
Megidd Sep 5, 2023
9cb0f88
New API: FEA log file
Megidd Sep 5, 2023
d567fdb
Fatal log: inconsistent voxel for point load
Megidd Sep 5, 2023
c76f2b0
Comment
Megidd Sep 5, 2023
3ca2f11
Test: new API
Megidd Sep 5, 2023
2932126
Layer to start FEA
Megidd Sep 5, 2023
8473e7a
Delete unneeded API: FEA log file
Megidd Sep 5, 2023
280e2d1
Fix log
Megidd Sep 5, 2023
e2a16fc
Tensile strength
Megidd Sep 11, 2023
24f9529
Remove unneeded field
Megidd Sep 13, 2023
9e14350
Revert "Remove unneeded field"
Megidd Sep 13, 2023
93b5460
Delete unneeded field
Megidd Sep 13, 2023
0a1d1be
Rename and delete unneeded
Megidd Sep 15, 2023
bdef1e1
Fields order
Megidd Sep 15, 2023
c259198
Fields order
Megidd Sep 15, 2023
f6dcdcd
Allow the same start & end layer
Megidd Sep 15, 2023
ad7dcd4
Fix start layer
Megidd Sep 15, 2023
df1526d
Log
Megidd Sep 16, 2023
d7fa8c1
Test with new func to debug
Megidd Sep 16, 2023
9802d86
New test case
Megidd Sep 16, 2023
ce28856
Skip tests. Consider gravity
Megidd Sep 17, 2023
058ba81
Gravity didn't fix the empty analysis results
Megidd Sep 17, 2023
a6830c1
Increasing resolution, fixed the empty analysis result
Megidd Sep 17, 2023
cf5056c
Avoid `tet` points too close to voxel corners.
Megidd Oct 1, 2023
d812b20
Merge branch 'master' into fe
Megidd Nov 23, 2023
1bb2ba8
Merge branch 'master' into fe
Megidd Dec 27, 2023
d2ccbb9
Fix: when load/restraint points are outside voxels
Megidd Jan 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions examples/finite_elements/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Output

## Nodes and elements

Output is generated as `inp` files for ABAQUS or CalculiX. Nodes and elements are saved in separate files, which are then included inside a single, final `inp` file. This final `inp` file can be opened and viewed using [FreeCAD](https://en.wikipedia.org/wiki/FreeCAD).

## Loading

The final `inp` file can apply a distributed *gravity* load to all elements. Additional point loads can be defined by a JSON file.

## Boundary

In the final `inp` file, the boundary is defined by the point restraints inside a JSON file.

## Modification

Currently, a convenient way for making adjustments is provided. Simply modify the load, restraint, and specification JSON files. Examining the unit tests is helpful to figure out how.

# CCX and CGX

The results can be consumed by ABAQUS or CalculiX.

CalculiX and CalculiX GraphiX binaries are available for different platforms, like Linux distributions.

## openSUSE

openSUSE has [CCX](https://software.opensuse.org/package/ccx) package and also [CGX](https://software.opensuse.org/package/cgx) one.

To install CCX and CGX on openSUSE Leap 15.5 you can run as root:

```bash
zypper addrepo https://download.opensuse.org/repositories/science/15.5/science.repo
zypper refresh
zypper install ccx
zypper install cgx
```

# Visualize `inp` file

To visualize the `inp` file by CalculiX GraphiX:

```bash
cgx -c hex8.inp
```

# Analyze `inp` file

To run the `inp` files by FEA engines like CalculiX:

```bash
ccx -i hex8
```

The above `-i` flag expects a `hex8.inp` file.

The above command creates `frd` files containing the results. They can be viewed by CalculiX GraphiX:

```bash
cgx hex8.frd
```

The boundary conditions and loads used in the calculation will be available together with the results if you run:

```bash
cgx hex8.frd hex8.inp
```

## Math solver

The default CCX math solver is `SPOOLES` which is slow. Apparently `PARDISO` is faster and `PaStiX` is the fastest. But it's needed to build the CCX with `PARDISO` or `PaStiX` math libraries.

### PARDISO

#### Linux executable with the Intel Pardiso Solver

You can download [here](https://www.dropbox.com/s/x8axi53l9dk9w4g/ccx_2.19_MT?dl=1) an executable with the Intel Pardiso solver for x86_64 Linux systems. The executable has all the libraries statically linked into it. So it should run by itself without any dependency. Thanks to [these guys](https://www.feacluster.com/calculix.php).
190 changes: 190 additions & 0 deletions examples/finite_elements/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//-----------------------------------------------------------------------------
/*

Finite elements from triangle mesh.
The result `inp` file is consumable by ABAQUS or CalculiX.

*/
//-----------------------------------------------------------------------------

package main

import (
"encoding/json"
"log"
"os"

"github.com/deadsy/sdfx/obj"
"github.com/deadsy/sdfx/render"
"github.com/deadsy/sdfx/sdf/finiteelements/mesh"
v3 "github.com/deadsy/sdfx/vec/v3"
)

type Specs struct {
PathResult string // Result file, consumable by ABAQUS or CalculiX.
PathReport string // Report some details after finite elements are generated.
PathStl string // Input STL file.
PathLoadPoints string // File containing point loads.
PathRestraintPoints string // File containing point restraints.
MassDensity float64
YoungModulus float64
PoissonRatio float64
GravityDirectionX float64
GravityDirectionY float64
GravityDirectionZ float64
GravityMagnitude float64
GravityIsNeeded bool
Resolution int // Number of voxels on the longest axis of 3D model AABB.
NonlinearConsidered bool // If true, nonlinear finite elements are generated.
ExactSurfaceConsidered bool // If true, surface is approximated by tetrahedral finite elements.
}

type Restraint struct {
LocX float64
LocY float64
LocZ float64
IsFixedX bool
IsFixedY bool
IsFixedZ bool
}

type Load struct {
LocX float64
LocY float64
LocZ float64
MagX float64
MagY float64
MagZ float64
}

type Component struct {
VoxelCount int
}

type Report struct {
VoxelsX int
VoxelsY int
VoxelsZ int
ComponentCount int
Components []Component
}

// Render STL to SDF3 to finite elements.
// Write finite elements to an `inp` file.
// Written file can be used by ABAQUS or CalculiX.
func main() {
if len(os.Args) != 2 {
log.Fatalf("usage: wrong argument count")
}

pthSpecs := os.Args[1]

jsonData, err := os.ReadFile(pthSpecs)
if err != nil {
log.Fatalf(err.Error())
}

var specs Specs
err = json.Unmarshal(jsonData, &specs)
if err != nil {
log.Fatalf(err.Error())
}

jsonData, err = os.ReadFile(specs.PathLoadPoints)
if err != nil {
log.Fatalf(err.Error())
}

var loads []Load
err = json.Unmarshal(jsonData, &loads)
if err != nil {
log.Fatalf(err.Error())
}

jsonData, err = os.ReadFile(specs.PathRestraintPoints)
if err != nil {
log.Fatalf(err.Error())
}

var restraints []Restraint
err = json.Unmarshal(jsonData, &restraints)
if err != nil {
log.Fatalf(err.Error())
}

// create the SDF from the STL mesh
inSdf, err := obj.ImportSTL(specs.PathStl, 20, 3, 5)
if err != nil {
log.Fatalf(err.Error())
}

var order render.Order
if specs.NonlinearConsidered {
order = render.Quadratic
} else {
order = render.Linear
}

var shape render.Shape
if specs.ExactSurfaceConsidered {
shape = render.HexAndTet
} else {
shape = render.Hexahedral
}

// Create a mesh of finite elements.
m, voxelsX, voxelsY, voxelsZ := mesh.NewFem(inSdf, render.NewMarchingCubesFeUniform(specs.Resolution, order, shape))

components := m.Components()
report := Report{
VoxelsX: voxelsX,
VoxelsY: voxelsY,
VoxelsZ: voxelsZ,
ComponentCount: len(components),
Components: make([]Component, len(components)),
}
for i, component := range components {
report.Components[i] = Component{VoxelCount: component.VoxelCount()}
}

jsonData, err = json.MarshalIndent(report, "", " ")
if err != nil {
log.Fatalf(err.Error())
}
err = os.WriteFile(specs.PathReport, jsonData, 0644)
if err != nil {
log.Fatalf(err.Error())
}

// Generate finite elements for all layers of mesh.
err = m.WriteInp(
specs.PathResult,
float32(specs.MassDensity), float32(specs.YoungModulus), float32(specs.PoissonRatio),
restraintsConvert(restraints),
loadsConvert(loads),
v3.Vec{X: specs.GravityDirectionX, Y: specs.GravityDirectionY, Z: specs.GravityDirectionZ}, specs.GravityMagnitude,
specs.GravityIsNeeded,
)

if err != nil {
log.Fatalf(err.Error())
}
}

func restraintsConvert(rs []Restraint) []*mesh.Restraint {
restraints := make([]*mesh.Restraint, len(rs))
for i, r := range rs {
restraint := mesh.NewRestraint(v3.Vec{X: r.LocX, Y: r.LocY, Z: r.LocZ}, r.IsFixedX, r.IsFixedY, r.IsFixedZ)
restraints[i] = restraint
}
return restraints
}

func loadsConvert(ls []Load) []*mesh.Load {
loads := make([]*mesh.Load, len(ls))
for i, l := range ls {
load := mesh.NewLoad(v3.Vec{X: l.LocX, Y: l.LocY, Z: l.LocZ}, v3.Vec{X: l.MagX, Y: l.MagY, Z: l.MagZ})
loads[i] = load
}
return loads
}
Loading