17 return (E * nu) / ((1.0 + nu) * (1.0 - 2.0 * nu));
19 return (nu * E) / (1.0 - nu * nu);
24 std::vector<Eigen::Vector3d> read_cell_vectors_legacy_vtk(
25 const std::string &path,
const std::string &field_name)
27 std::ifstream in(path);
31 std::vector<Eigen::Vector3d> out;
36 while (std::getline(in, line))
38 std::istringstream ss(line);
41 if (tok ==
"CELL_DATA")
45 else if (tok ==
"VECTORS")
49 if (name != field_name)
53 out.resize(n_cell_data);
54 for (
int i = 0; i < n_cell_data; ++i)
56 if (!(in >> out[i].
x() >> out[i].
y() >> out[i].
z()))
58 "Fiber VTK '{}' ended early: expected {} vectors", path, n_cell_data));
66 "VECTORS '{}' not found under CELL_DATA in {}", field_name, path));
72 return E / (2.0 * (1.0 + nu));
77 : param_name_(param_name)
83 for (
int i =
param_.size(); i <= index; ++i)
86 param_.back().set_unit_type(unit_type);
97 const double x = p(0);
98 const double y = p(1);
99 const double z = p.size() == 3 ? p(2) : 0;
101 return (*
this)(
x,
y,
z, t, index);
110 return tmp_param(
x,
y,
z, t, index);
114 : param_name_(param_name)
127 for (
int i = 0; i < params_array.size(); ++i)
130 for (
int i = 0; i <
params_.size(); ++i)
132 for (
int j =
params_.at(i).param_.size(); j <= index; ++j)
134 params_.at(i).param_.emplace_back();
135 params_.at(i).param_.back().set_unit_type(unit_type);
138 params_.at(i).param_[index].init(params_array[i], root_path);
186 entries[3], stress_units, root_path);
212 stress_units, root_path);
227 entries[8], stress_units, root_path);
266 (*this)(0, 0) = 2 * mu + lambda;
267 (*this)(0, 1) = lambda;
270 (*this)(1, 1) = 2 * mu + lambda;
277 (*this)(0, 0) = 2 * mu + lambda;
278 (*this)(0, 1) = lambda;
279 (*this)(0, 2) = lambda;
284 (*this)(1, 1) = 2 * mu + lambda;
285 (*this)(1, 2) = lambda;
290 (*this)(2, 2) = 2 * mu + lambda;
312 0.0, 0.0, (1.0 - nu) / 2.0;
320 v, 1. - v, v, 0, 0, 0,
321 v, v, 1. - v, 0, 0, 0,
322 0, 0, 0, (1. - 2. * v) / 2., 0, 0,
323 0, 0, 0, 0, (1. - 2. * v) / 2., 0,
324 0, 0, 0, 0, 0, (1. - 2. * v) / 2.;
330 double Ex,
double Ey,
double Ez,
331 double nuXY,
double nuXZ,
double nuYZ,
332 double muYZ,
double muZX,
double muXY,
const std::string &stress_units,
const std::string &root_path)
337 double nuYX = nuXY * Ey / Ex;
338 double nuZX = nuXZ * Ez / Ex;
339 double nuZY = nuYZ * Ez / Ey;
341 Eigen::MatrixXd compliance;
342 compliance.setZero(6, 6);
343 compliance << 1 / Ex, -nuYX / Ey, -nuZX / Ez, 0, 0, 0,
344 -nuXY / Ex, 1 / Ey, -nuZY / Ez, 0, 0, 0,
345 -nuXZ / Ex, -nuYZ / Ey, 1 / Ez, 0, 0, 0,
346 0, 0, 0, 1 / (2 * muYZ), 0, 0,
347 0, 0, 0, 0, 1 / (2 * muZX), 0,
348 0, 0, 0, 0, 0, 1 / (2 * muXY);
357 double nuYX = nuXY * Ey / Ex;
359 Eigen::MatrixXd compliance;
360 compliance.setZero(3, 3);
361 compliance << 1.0 / Ex, -nuYX / Ey, 0.0,
362 -nuXY / Ex, 1.0 / Ey, 0.0,
363 0.0, 0.0, 1.0 / (2 * muXY);
368 double Et,
double Ea,
369 double nu_t,
double nu_a,
370 double Ga,
const std::string &stress_units,
const std::string &root_path)
375 Eigen::MatrixXd compliance;
376 compliance.setZero(6, 6);
377 compliance << 1 / Et, -nu_t / Et, -nu_a / Ea, 0, 0, 0,
378 -nu_t / Et, 1 / Et, -nu_a / Ea, 0, 0, 0,
379 -nu_a / Ea, -nu_a / Ea, 1 / Ea, 0, 0, 0,
380 0, 0, 0, 1 / Ga, 0, 0,
381 0, 0, 0, 0, 1 / Ga, 0,
382 0, 0, 0, 0, 0, (2 * (1 + nu_t)) / Et;
391 for (
int k = 0; k < DIM; ++k)
392 res += (*
this)(j, k) * strain[k];
428 double llambda = tmp1(
x,
y,
z, t, el_id);
429 double mmu = tmp2(
x,
y,
z, t, el_id);
448 assert(!std::isnan(lambda));
449 assert(!std::isnan(mu));
450 assert(!std::isinf(lambda));
451 assert(!std::isinf(mu));
456 const int size = is_volume ? 3 : 2;
468 if (params.count(
"young"))
470 set_e_nu(index, params[
"young"], params[
"nu"], stress_unit, root_path);
472 else if (params.count(
"E"))
474 set_e_nu(index, params[
"E"], params[
"nu"], stress_unit, root_path);
476 else if (params.count(
"lambda"))
479 mu_or_nu_[index].init(params[
"mu"], root_path);
482 mu_or_nu_[index].set_unit_type(stress_unit);
502 rho_.back().init(1.0);
507 assert(
rho_.size() == 1 || el_id <
rho_.size());
509 const auto &tmp =
rho_.size() == 1 ?
rho_[0] :
rho_[el_id];
510 const double res = tmp(
x,
y,
z, t, el_id);
511 assert(!std::isnan(res));
512 assert(!std::isinf(res));
518 for (
int i =
rho_.size(); i <= index; ++i)
523 if (params.count(
"rho"))
525 rho_[index].init(params[
"rho"], root_path);
527 else if (params.count(
"density"))
529 rho_[index].init(params[
"density"], root_path);
532 rho_[index].set_unit_type(density_unit);
536 : rho_(
"rho"), heat_capacity_(
"heat_capacity")
556 assert(!std::isnan(res));
557 assert(!std::isinf(res));
563 return rho_(p, t, el_id);
577 assert(size == 2 || size == 3);
581 for (
const auto &m :
dir_)
583 assert((m.rows() == size && m.cols() == size) || (m.rows() == size && m.cols() == 1));
588 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3>
FiberDirection::operator()(
double px,
double py,
double pz,
double x,
double y,
double z,
double t,
int el_id)
const
594 if (el_id < 0 || el_id >=
static_cast<int>(
per_el_fibers_.size()))
596 "Fiber el_id {} out of range [0,{})", el_id,
per_el_fibers_.size()));
597 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3> res;
598 res.resize(
size_, 1);
599 for (
int i = 0; i <
size_; ++i)
604 assert(
dir_.size() == 1 || el_id <
dir_.size());
606 const auto &tmp =
dir_.size() == 1 ?
dir_[0] :
dir_[el_id];
607 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3> res;
608 res.resize(tmp.rows(), tmp.cols());
609 for (
int i = 0; i < tmp.rows(); ++i)
611 for (
int j = 0; j < tmp.cols(); ++j)
613 res(i, j) = tmp(i, j)(
x,
y,
z, t, el_id);
615 assert(!std::isnan(res(i, j)));
616 assert(!std::isinf(res(i, j)));
622 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 6, 6>
FiberDirection::stiffness_rotation_voigt(
double px,
double py,
double pz,
double x,
double y,
double z,
double t,
int el_id)
const
627 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3> rot = (*this)(px, py, pz,
x,
y,
z, t, el_id);
628 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 1, 6, 6> res;
630 int dim = rot.rows();
632 static const double sqrt2 = std::sqrt(2.0);
647 res << rot(0, 0) * rot(0, 0), rot(0, 1) * rot(0, 1), rot(0, 2) * rot(0, 2), sqrt2 * rot(0, 1) * rot(0, 2), sqrt2 * rot(0, 0) * rot(0, 2), sqrt2 * rot(0, 0) * rot(0, 1),
648 rot(1, 0) * rot(1, 0), rot(1, 1) * rot(1, 1), rot(1, 2) * rot(1, 2), sqrt2 * rot(1, 1) * rot(1, 2), sqrt2 * rot(1, 0) * rot(1, 2), sqrt2 * rot(1, 0) * rot(1, 1),
649 rot(2, 0) * rot(2, 0), rot(2, 1) * rot(2, 1), rot(2, 2) * rot(2, 2), sqrt2 * rot(2, 1) * rot(2, 2), sqrt2 * rot(2, 0) * rot(2, 2), sqrt2 * rot(2, 0) * rot(2, 1),
650 sqrt2 * rot(1, 0) * rot(2, 0), sqrt2 * rot(1, 1) * rot(2, 1), sqrt2 * rot(1, 2) * rot(2, 2), rot(1, 1) * rot(2, 2) + rot(1, 2) * rot(2, 1), rot(1, 0) * rot(2, 2) + rot(1, 2) * rot(2, 0), rot(1, 0) * rot(2, 1) + rot(1, 1) * rot(2, 0),
651 sqrt2 * rot(0, 0) * rot(2, 0), sqrt2 * rot(0, 1) * rot(2, 1), sqrt2 * rot(0, 2) * rot(2, 2), rot(0, 1) * rot(2, 2) + rot(0, 2) * rot(2, 1), rot(0, 0) * rot(2, 2) + rot(0, 2) * rot(2, 0), rot(0, 0) * rot(2, 1) + rot(0, 1) * rot(2, 0),
652 sqrt2 * rot(0, 0) * rot(1, 0), sqrt2 * rot(0, 1) * rot(1, 1), sqrt2 * rot(0, 2) * rot(1, 2), rot(0, 1) * rot(1, 2) + rot(0, 2) * rot(1, 1), rot(0, 0) * rot(1, 2) + rot(0, 2) * rot(1, 0), rot(0, 0) * rot(1, 1) + rot(0, 1) * rot(1, 0);
666 if (dir.is_object() && dir.value(
"type", std::string()) ==
"per_element_file")
668 const std::string field = dir.value(
"field", std::string(
"FIB_DIR1"));
674 const double n = v.norm();
681 logger().info(
"FiberDirection: loaded {} per-element fibers ('{}') from {}",
686 for (
int i =
dir_.size(); i <= index; ++i)
691 if (dir.size() == 3 || dir.size() == 2)
693 const int size = dir.size();
694 const int other_size = dir[0].is_array() ? size : 1;
696 assert(size ==
size_);
697 dir_[index].resize(size, other_size);
698 for (
int i = 0; i < size; ++i)
702 if (dir[i].is_array())
704 log_and_throw_error(fmt::format(
"Fiber must be a {} vector, row {} is {}", size, i, dir[i].dump()));
706 dir_[index](i, 0).init(dir[i], root_path);
707 dir_[index](i, 0).set_unit_type(unit);
710 if (dir[i].size() != size)
712 log_and_throw_error(fmt::format(
"Fiber must be {}x{}, row {} is {}", size, other_size, i, dir[i].dump()));
714 for (
int j = 0; j < size; ++j)
716 dir_[index](i, j).init(dir[i][j], root_path);
717 dir_[index](i, j).set_unit_type(unit);
722 else if (dir.size() == 9 || dir.size() == 4)
724 const int size = dir.size() == 9 ? 3 : 2;
725 assert(size ==
size_);
726 dir_[index].resize(size, size);
727 for (
int i = 0; i < size; ++i)
729 for (
int j = 0; j < size; ++j)
731 dir_[index](i, j).init(dir[i * size + j], root_path);
732 dir_[index](i, j).set_unit_type(unit);
737 else if (dir.empty())
740 for (
int i = 0; i <
size_; ++i)
742 for (
int j = 0; j <
size_; ++j)
744 dir_[index](i, j).init(i == j ? 1.0 : 0.0);
745 dir_[index](i, j).set_unit_type(unit);
757 template double ElasticityTensor::compute_stress<3>(
const std::array<double, 3> &strain,
const int j)
const;
758 template double ElasticityTensor::compute_stress<6>(
const std::array<double, 6> &strain,
const int j)
const;
std::vector< Eigen::Triplet< double > > entries
std::vector< utils::ExpressionValue > rho_
virtual double operator()(double px, double py, double pz, double x, double y, double z, double t, int el_id) const
virtual void add_multimaterial(const int index, const json ¶ms, const std::string &density_unit, const std::string &root_path)
double operator()(int i, int j) const
void set_from_young_poisson(const double young, const double poisson, const std::string &stress_unit, const std::string &root_path)
void rotate_stiffness(const Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 6, 6 > &rotation_mtx_voigt)
void resize(const int size)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 6, 6 > stiffness_tensor_
void set_transversely_isotropic(double Et, double Ea, double nu_t, double nu_a, double Ga, const std::string &stress_units, const std::string &root_path)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, 6, 6 > reference_stiffness_tensor_
void set_orthotropic(double Ex, double Ey, double Ez, double nuXY, double nuXZ, double nuYZ, double muYZ, double muZX, double muXY, const std::string &stress_unit, const std::string &root_path)
double compute_stress(const std::array< double, DIM > &strain, const int j) const
void set_from_entries(const std::vector< double > &entries, const std::string &stress_unit, const std::string &root_path)
void set_from_lambda_mu(const double lambda, const double mu, const std::string &stress_unit, const std::string &root_path)
void unrotate_stiffness()
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 1, 6, 6 > stiffness_rotation_voigt(double px, double py, double pz, double x, double y, double z, double t, int el_id) const
std::vector< Eigen::Matrix< utils::ExpressionValue, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3 > > dir_
bool use_per_element_file_
void resize(const int size)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 1, 3, 3 > operator()(double px, double py, double pz, double x, double y, double z, double t, int el_id) const
void add_multimaterial(const int index, const json ¶ms, const std::string &unit, const std::string &root_path)
std::vector< Eigen::Vector3d > per_el_fibers_
double operator()(const RowVectorNd &p, double t, int index) const
GenericMatParam(const std::string ¶m_name)
void add_multimaterial(const int index, const json ¶ms, const std::string &unit_type, const std::string &root_path)
std::vector< utils::ExpressionValue > param_
const std::string param_name_
std::vector< GenericMatParam > params_
GenericMatParams(const std::string ¶m_name)
const std::string param_name_
void add_multimaterial(const int index, const json ¶ms, const std::string &unit_type, const std::string &root_path)
std::vector< utils::ExpressionValue > mu_or_nu_
void lambda_mu(double px, double py, double pz, double x, double y, double z, double t, int el_id, double &lambda, double &mu) const
std::vector< utils::ExpressionValue > lambda_or_E_
void set_e_nu(const int index, const json &E, const json &nu, const std::string &stress_unit, const std::string &root_path)
Eigen::MatrixXd lambda_mat_
void add_multimaterial(const int index, const json ¶ms, const bool is_volume, const std::string &stress_unit, const std::string &root_path)
double rho(const RowVectorNd &p, double t, int el_id) const
double heat_capacity(const RowVectorNd &p, double t, int el_id) const
GenericMatParam heat_capacity_
double operator()(double px, double py, double pz, double x, double y, double z, double t, int el_id) const override
void add_multimaterial(const int index, const json ¶ms, const std::string &density_unit, const std::string &root_path) override
std::string resolve_path(const std::string &path, const std::string &input_file_path, const bool only_if_exists=false)
std::vector< T > json_as_array(const json &j)
Return the value of a json object as an array.
spdlog::logger & logger()
Retrieves the current logger.
double convert_to_mu(const double E, const double nu)
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
double convert_to_lambda(const bool is_volume, const double E, const double nu)
void log_and_throw_error(const std::string &msg)