Skip to content

Commit 835a76a

Browse files
authored
added linear thermal triclinic model (#32)
* added linear thermal triclinic model similar to linear elastic triclinic model * fixed readme.md indent causing linting error
1 parent 4f85789 commit 835a76a

File tree

5 files changed

+130
-53
lines changed

5 files changed

+130
-53
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ set_property(TARGET FANS_FANS PROPERTY PUBLIC_HEADER
133133
include/solver.h
134134
include/setup.h
135135

136-
include/material_models/LinearThermalIsotropic.h
136+
include/material_models/LinearThermal.h
137137
include/material_models/LinearElastic.h
138138
include/material_models/PseudoPlastic.h
139139
include/material_models/J2Plasticity.h

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,20 @@ FANS requires a JSON input file specifying the problem parameters. Example input
178178
179179
```json
180180
"method": "cg",
181-
"TOL": 1e-10,
182-
"n_it": 100
181+
"error_parameters":{
182+
"measure": "Linfinity",
183+
"type": "absolute",
184+
"tolerance": 1e-10
185+
},
186+
"n_it": 100,
183187
```
184188
185189
- `method`: This indicates the numerical method to be used for solving the system of equations. `cg` stands for the Conjugate Gradient method, and `fp` stands for the Fixed Point method.
186-
- `TOL`: This sets the tolerance level for the solver. It defines the convergence criterion which is based on the L-infinity norm of the nodal finite element residual; the solver iterates until the solution meets this tolerance.
187-
- `n_it`: This specifies the maximum number of iterations allowed for the FANS solver.
190+
- `error_parameters`: This section defines the error parameters for the solver. Error control is applied on the finite element nodal residual of the problem.
191+
- `measure`: Specifies the norm used to measure the error. Options include `Linfinity`, `L1`, or `L2`.
192+
- `type`: Defines the type of error measurement. Options are `absolute` or `relative`.
193+
- `tolerance`: Sets the tolerance level for the solver, defining the convergence criterion based on the chosen error measure. The solver iterates until the solution meets this tolerance.
194+
- `n_it`: Specifies the maximum number of iterations allowed for the FANS solver.
188195
189196
### Macroscale Loading Conditions
190197
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#ifndef LINEARTHERMAL_H
2+
#define LINEARTHERMAL_H
3+
4+
#include "matmodel.h"
5+
#include <Eigen/StdVector> // For Eigen's aligned_allocator
6+
7+
class LinearThermalIsotropic : public ThermalModel, public LinearModel<1> {
8+
public:
9+
LinearThermalIsotropic(vector<double> l_e, json materialProperties)
10+
: ThermalModel(l_e)
11+
{
12+
try {
13+
conductivity = materialProperties["conductivity"].get<vector<double>>();
14+
} catch (const std::exception &e) {
15+
throw std::runtime_error("Missing material properties for the requested material model.");
16+
}
17+
n_mat = conductivity.size();
18+
19+
double kappa_ref = (*max_element(conductivity.begin(), conductivity.end()) +
20+
*min_element(conductivity.begin(), conductivity.end())) /
21+
2;
22+
kapparef_mat = kappa_ref * Matrix3d::Identity();
23+
24+
Matrix3d phase_kappa;
25+
phase_stiffness = new Matrix<double, 8, 8>[n_mat];
26+
27+
for (size_t i = 0; i < n_mat; ++i) {
28+
phase_stiffness[i] = Matrix<double, 8, 8>::Zero();
29+
phase_kappa = conductivity[i] * Matrix3d::Identity();
30+
31+
for (int p = 0; p < 8; ++p) {
32+
phase_stiffness[i] += B_int[p].transpose() * phase_kappa * B_int[p] * v_e * 0.1250;
33+
}
34+
}
35+
}
36+
37+
void get_sigma(int i, int mat_index, ptrdiff_t element_idx) override
38+
{
39+
sigma(i + 0, 0) = conductivity[mat_index] * eps(i + 0, 0);
40+
sigma(i + 1, 0) = conductivity[mat_index] * eps(i + 1, 0);
41+
sigma(i + 2, 0) = conductivity[mat_index] * eps(i + 2, 0);
42+
}
43+
44+
private:
45+
vector<double> conductivity;
46+
};
47+
48+
class LinearThermalTriclinic : public ThermalModel, public LinearModel<1> {
49+
public:
50+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW // Ensure proper alignment for Eigen structures
51+
52+
LinearThermalTriclinic(vector<double> l_e, json materialProperties)
53+
: ThermalModel(l_e)
54+
{
55+
vector<string> K_keys = {
56+
"K_11", "K_12", "K_13",
57+
"K_22", "K_23",
58+
"K_33"};
59+
60+
try {
61+
n_mat = materialProperties.at("K_11").get<vector<double>>().size();
62+
size_t num_constants = K_keys.size();
63+
64+
// Initialize matrix to hold all constants
65+
K_constants.resize(num_constants, n_mat);
66+
67+
// Load material constants into matrix
68+
for (size_t k = 0; k < num_constants; ++k) {
69+
const auto &values = materialProperties.at(K_keys[k]).get<vector<double>>();
70+
if (values.size() != n_mat) {
71+
throw std::runtime_error("Inconsistent size for material property: " + K_keys[k]);
72+
}
73+
K_constants.row(k) = Eigen::Map<const RowVectorXd>(values.data(), values.size());
74+
}
75+
} catch (const std::exception &e) {
76+
throw std::runtime_error("Missing or inconsistent material properties for the requested material model.");
77+
}
78+
79+
// Assemble conductivity matrices for each material
80+
K_mats.resize(n_mat);
81+
kapparef_mat = Matrix3d::Zero();
82+
83+
for (size_t i = 0; i < n_mat; ++i) {
84+
Matrix3d K_i;
85+
K_i << K_constants(0, i), K_constants(1, i), K_constants(2, i),
86+
K_constants(1, i), K_constants(3, i), K_constants(4, i),
87+
K_constants(2, i), K_constants(4, i), K_constants(5, i);
88+
89+
K_mats[i] = K_i;
90+
kapparef_mat += K_i;
91+
}
92+
93+
kapparef_mat /= n_mat;
94+
95+
// Compute phase stiffness matrices
96+
phase_stiffness = new Matrix<double, 8, 8>[n_mat];
97+
for (size_t i = 0; i < n_mat; ++i) {
98+
phase_stiffness[i] = Matrix<double, 8, 8>::Zero();
99+
for (int p = 0; p < 8; ++p) {
100+
phase_stiffness[i] += B_int[p].transpose() * K_mats[i] * B_int[p] * v_e * 0.1250;
101+
}
102+
}
103+
}
104+
105+
void get_sigma(int i, int mat_index, ptrdiff_t element_idx) override
106+
{
107+
sigma.segment<3>(i) = K_mats[mat_index] * eps.segment<3>(i);
108+
}
109+
110+
private:
111+
std::vector<Matrix3d, Eigen::aligned_allocator<Matrix3d>> K_mats;
112+
MatrixXd K_constants;
113+
};
114+
115+
#endif // LINEARTHERMAL_H

include/material_models/LinearThermalIsotropic.h

Lines changed: 0 additions & 47 deletions
This file was deleted.

include/setup.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "solverFP.h"
33

44
// Thermal models
5-
#include "material_models/LinearThermalIsotropic.h"
5+
#include "material_models/LinearThermal.h"
66

77
// Mechanical models
88
#include "material_models/LinearElastic.h"
@@ -17,6 +17,8 @@ Matmodel<1> *createMatmodel(const Reader &reader)
1717
{
1818
if (reader.matmodel == "LinearThermalIsotropic") {
1919
return new LinearThermalIsotropic(reader.l_e, reader.materialProperties);
20+
} else if (reader.matmodel == "LinearThermalTriclinic") {
21+
return new LinearThermalTriclinic(reader.l_e, reader.materialProperties);
2022
} else {
2123
throw std::invalid_argument(reader.matmodel + " is not a valid matmodel for thermal problem");
2224
}

0 commit comments

Comments
 (0)