16 std::vector<std::shared_ptr<varform::DifferentiableVarForm>> varforms,
17 std::vector<std::shared_ptr<DiffCache>> diff_caches,
19 : varforms_(std::move(varforms)),
20 diff_caches_(std::move(diff_caches)),
21 parametrization_(std::move(parametrization)),
22 dimension_(varforms_[0]->get_mesh().dimension()),
23 meshing_(settings.at(
"meshing"))
27 if (varform->get_mesh().dimension() !=
dimension_ || !varform->is_homogenization())
32 const Eigen::MatrixXd offsets = varform->periodic_tile_offsets();
33 if (offsets.cols() !=
dimension_ || Eigen::FullPivLU<Eigen::MatrixXd>(offsets).rank() !=
dimension_)
39 const auto parameters = settings.at(
"initial").get<std::vector<double>>();
40 initial_ = Eigen::Map<const Eigen::VectorXd>(parameters.data(), parameters.size());
43 const std::string symmetry = settings.at(
"symmetry").get<std::string>();
44 if (
dimension_ == 2 && (symmetry ==
"auto" || symmetry ==
"doubly_periodic"))
46 options_.cell_type = inflator::CellType::Periodic2D;
48 else if (
dimension_ == 2 && symmetry ==
"orthotropic")
50 options_.cell_type = inflator::CellType::Orthotropic2D;
52 else if (
dimension_ == 3 && (symmetry ==
"auto" || symmetry ==
"orthotropic"))
54 options_.cell_type = inflator::CellType::Orthotropic3D;
60 options_.tiles = settings.at(
"tiles").get<std::size_t>();
61 options_.graph_radius = settings.at(
"graph_radius").get<std::size_t>();
62 options_.contour_resolution =
meshing_.at(
"marchingSquaresGridSize").get<std::size_t>();
63 options_.force_contour_resolution =
meshing_.at(
"forceMSGridSize").get<
bool>();
84 if (parameters.size() !=
initial_.size() || !parameters.allFinite() || parameters(0) <= 0)
94 if (!std::filesystem::create_directory(directory))
107 const inflator::Mesh mesh = inflator::inflate(
wire_,
options_, parameters.data() + 1, parameters.size() - 1);
114 for (
int vertex = 0; vertex < vertices.rows(); ++vertex)
118 const double cell_length = axis == 0 ? parameters(0) : 1.0;
119 vertices(vertex, axis) = mesh.vertices[vertex *
dimension_ + axis] * cell_length / 2;
122 for (
int cell = 0; cell < cells.rows(); ++cell)
124 for (
int corner = 0; corner < cells.cols(); ++corner)
126 cells(cell, corner) = mesh.elements[cell * (
dimension_ + 1) + corner];
132 for (
int vertex = 0; vertex < vertices.rows(); ++vertex)
139 for (
int parameter = 1; parameter < parameters.size(); ++parameter)
141 const std::size_t parameter_offset = (parameter - 1) * mesh.vertices.size();
142 for (
int vertex = 0; vertex < vertices.rows(); ++vertex)
146 const Eigen::Index coordinate =
dimension_ * vertex + axis;
147 const double velocity = mesh.boundary_shape_velocities[parameter_offset + coordinate];
148 const double cell_length = axis == 0 ? parameters(0) : 1.0;
159 periodic_map_ = std::make_unique<PeriodicMeshToMesh>(vertices);
164 std::vector<bool> visited(
periodic_map_->n_periodic_dof(),
false);
165 for (
int vertex = 0; vertex < vertices.rows(); ++vertex)
167 const int representative =
periodic_map_->full_to_periodic(vertex);
168 if (visited[representative])
173 visited[representative] =
true;
176 const double tiled_length =
options_.tiles * (axis == 0 ? parameters(0) : 1.0);
179 periodic_derivatives = physical_derivatives / tiled_length;
187 const std::string mesh_path = (directory /
"mesh.msh").
string();
188 const std::vector<int> body_ids(cells.rows(), 0);
191 for (
int state = 0; state <
varforms_.size(); ++state)
193 varforms_[state]->replace_mesh(mesh_path);
199 adjoint_logger().info(
"Inflated mesh generation {}: {} vertices, {} elements",
generation_ - 1, vertices.rows(), cells.rows());