20 #ifndef __mast_mesh_generation_heat_sink_3d_h__ 21 #define __mast_mesh_generation_heat_sink_3d_h__ 30 #include <libmesh/system.h> 31 #include <libmesh/unstructured_mesh.h> 32 #include <libmesh/fe_type.h> 33 #include <libmesh/string_to_enum.h> 34 #include <libmesh/mesh_generation.h> 35 #include <libmesh/elem.h> 36 #include <libmesh/node.h> 37 #include <libmesh/boundary_info.h> 38 #include <libmesh/dirichlet_boundaries.h> 39 #include <libmesh/zero_function.h> 40 #include <libmesh/mesh_refinement.h> 41 #include <libmesh/mesh_modification.h> 46 namespace Generation {
53 template <
typename Context>
58 length = c.input(
"length",
"length of domain along x-axis", 1.),
59 height = c.input(
"height",
"length of domain along y-axis", 1.),
60 width = c.input(
"width",
"length of domain along z-axis", 1.);
62 return length * height * width;
77 return i + (nx+1)*(j + k*(ny+1));
82 return i + (2*nx+1)*(j + k*(2*ny+1));
86 Error(
false,
"Invalid element type");
89 return libMesh::invalid_uint;
100 const real_t dirichlet_length_fraction,
101 const libMesh::ElemType type) {
103 Assert0(type == libMesh::HEX8 || type == libMesh::HEX27,
104 "Method only implemented for Hex8/Hex27");
109 libMesh::BoundaryInfo & boundary_info = mesh.get_boundary_info();
111 mesh.set_mesh_dimension(3);
112 mesh.set_spatial_dimension(3);
113 mesh.reserve_elem(nx*ny*nz);
115 if (type == libMesh::HEX8)
116 mesh.reserve_nodes( (nx+1)*(ny+1)*(nz+1) );
117 else if (type == libMesh::HEX27)
118 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) );
127 std::map<uint_t, libMesh::Node*> nodes;
135 case libMesh::HEX8: {
137 for (
uint_t k=0; k<=nz; k++)
138 for (
uint_t j=0; j<=ny; j++)
139 for (
uint_t i=0; i<=nx; i++) {
141 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(nx)*length,
142 static_cast<real_t>(j)/static_cast<real_t>(ny)*height,
143 static_cast<real_t>(k)/static_cast<real_t>(nz)*width),
152 case libMesh::HEX27: {
154 for (
uint_t k=0; k<=(2*nz); k++)
155 for (
uint_t j=0; j<=(2*ny); j++)
156 for (
uint_t i=0; i<=(2*nx); i++) {
158 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(2*nx)*length,
159 static_cast<real_t>(j)/static_cast<real_t>(2*ny)*height,
160 static_cast<real_t>(k)/static_cast<real_t>(2*nz)*width),
170 Assert0(
false,
"ERROR: Unrecognized 3D element type.");
180 for (
uint_t k=0; k<nz; k++)
181 for (
uint_t j=0; j<ny; j++)
182 for (
uint_t i=0; i<nx; i++) {
186 elem->set_id(elem_id++);
189 elem->set_node(0) = nodes[
idx(type,nx,ny,i,j,k) ];
190 elem->set_node(1) = nodes[
idx(type,nx,ny,i+1,j,k) ];
191 elem->set_node(2) = nodes[
idx(type,nx,ny,i+1,j+1,k) ];
192 elem->set_node(3) = nodes[
idx(type,nx,ny,i,j+1,k) ];
193 elem->set_node(4) = nodes[
idx(type,nx,ny,i,j,k+1) ];
194 elem->set_node(5) = nodes[
idx(type,nx,ny,i+1,j,k+1) ];
195 elem->set_node(6) = nodes[
idx(type,nx,ny,i+1,j+1,k+1)];
196 elem->set_node(7) = nodes[
idx(type,nx,ny,i,j+1,k+1) ];
199 boundary_info.add_side(elem, 0, 0);
202 boundary_info.add_side(elem, 5, 5);
205 boundary_info.add_side(elem, 1, 1);
208 boundary_info.add_side(elem, 3, 3);
211 boundary_info.add_side(elem, 4, 4);
214 boundary_info.add_side(elem, 2, 2);
217 (i <= .5*(1.+dirichlet_length_fraction) * nx) &&
218 (i >= .5*(1.-dirichlet_length_fraction) * nx) &&
219 (k <= .5*(1.+dirichlet_length_fraction) * nz) &&
220 (k >= .5*(1.-dirichlet_length_fraction) * nz))
221 boundary_info.add_side(elem, 1, 6);
227 case libMesh::HEX27: {
229 for (
uint_t k=0; k<(2*nz); k += 2)
230 for (
uint_t j=0; j<(2*ny); j += 2)
231 for (
uint_t i=0; i<(2*nx); i += 2)
235 elem->set_id(elem_id++);
238 elem->set_node(0) = nodes[
idx(type,nx,ny,i, j, k) ];
239 elem->set_node(1) = nodes[
idx(type,nx,ny,i+2,j, k) ];
240 elem->set_node(2) = nodes[
idx(type,nx,ny,i+2,j+2,k) ];
241 elem->set_node(3) = nodes[
idx(type,nx,ny,i, j+2,k) ];
242 elem->set_node(4) = nodes[
idx(type,nx,ny,i, j, k+2)];
243 elem->set_node(5) = nodes[
idx(type,nx,ny,i+2,j, k+2)];
244 elem->set_node(6) = nodes[
idx(type,nx,ny,i+2,j+2,k+2)];
245 elem->set_node(7) = nodes[
idx(type,nx,ny,i, j+2,k+2)];
246 elem->set_node(8) = nodes[
idx(type,nx,ny,i+1,j, k) ];
247 elem->set_node(9) = nodes[
idx(type,nx,ny,i+2,j+1,k) ];
248 elem->set_node(10) = nodes[
idx(type,nx,ny,i+1,j+2,k) ];
249 elem->set_node(11) = nodes[
idx(type,nx,ny,i, j+1,k) ];
250 elem->set_node(12) = nodes[
idx(type,nx,ny,i, j, k+1)];
251 elem->set_node(13) = nodes[
idx(type,nx,ny,i+2,j, k+1)];
252 elem->set_node(14) = nodes[
idx(type,nx,ny,i+2,j+2,k+1)];
253 elem->set_node(15) = nodes[
idx(type,nx,ny,i, j+2,k+1)];
254 elem->set_node(16) = nodes[
idx(type,nx,ny,i+1,j, k+2)];
255 elem->set_node(17) = nodes[
idx(type,nx,ny,i+2,j+1,k+2)];
256 elem->set_node(18) = nodes[
idx(type,nx,ny,i+1,j+2,k+2)];
257 elem->set_node(19) = nodes[
idx(type,nx,ny,i, j+1,k+2)];
259 elem->set_node(20) = nodes[
idx(type,nx,ny,i+1,j+1,k) ];
260 elem->set_node(21) = nodes[
idx(type,nx,ny,i+1,j, k+1)];
261 elem->set_node(22) = nodes[
idx(type,nx,ny,i+2,j+1,k+1)];
262 elem->set_node(23) = nodes[
idx(type,nx,ny,i+1,j+2,k+1)];
263 elem->set_node(24) = nodes[
idx(type,nx,ny,i, j+1,k+1)];
264 elem->set_node(25) = nodes[
idx(type,nx,ny,i+1,j+1,k+2)];
265 elem->set_node(26) = nodes[
idx(type,nx,ny,i+1,j+1,k+1)];
268 boundary_info.add_side(elem, 0, 0);
271 boundary_info.add_side(elem, 5, 5);
274 boundary_info.add_side(elem, 1, 1);
277 boundary_info.add_side(elem, 3, 3);
280 boundary_info.add_side(elem, 4, 4);
283 boundary_info.add_side(elem, 2, 2);
286 (i <= .5*(1.+dirichlet_length_fraction) * 2*nx) &&
287 (i >= .5*(1.-dirichlet_length_fraction) * 2*nx) &&
288 (k <= .5*(1.+dirichlet_length_fraction) * 2*nz) &&
289 (k >= .5*(1.-dirichlet_length_fraction) * 2*nz))
290 boundary_info.add_side(elem, 1, 6);
296 Assert0(
false,
"ERROR: Unrecognized 3D element type.");
300 boundary_info.sideset_name(0) =
"back";
301 boundary_info.sideset_name(1) =
"bottom";
302 boundary_info.sideset_name(2) =
"right";
303 boundary_info.sideset_name(3) =
"top";
304 boundary_info.sideset_name(4) =
"left";
305 boundary_info.sideset_name(5) =
"front";
306 boundary_info.sideset_name(6) =
"dirichlet";
309 boundary_info.nodeset_name(0) =
"back";
310 boundary_info.nodeset_name(1) =
"bottom";
311 boundary_info.nodeset_name(2) =
"right";
312 boundary_info.nodeset_name(3) =
"top";
313 boundary_info.nodeset_name(4) =
"left";
314 boundary_info.nodeset_name(5) =
"front";
317 mesh.prepare_for_use ();
322 template <
typename Context>
325 libMesh::UnstructuredMesh& mesh) {
328 length = c.input(
"length",
"length of domain along x-axis", 1.),
329 height = c.input(
"height",
"length of domain along y-axis", 1.),
330 width = c.input(
"width",
"length of domain along z-axis", 1.),
331 dirichlet_length_fraction = c.input
332 (
"dirichlet_length_fraction",
333 "length fraction of the truss boundary where dirichlet condition is applied",
337 nx_divs = c.input(
"nx_divs",
"number of elements along x-axis", 20),
338 ny_divs = c.input(
"ny_divs",
"number of elements along y-axis", 20),
339 nz_divs = c.input(
"nz_divs",
"number of elements along z-axis", 20),
340 n_refine= c.input(
"n_uniform_refinement",
"number of times the mesh is uniformly refined", 0);
343 t = c.input(
"elem_type",
"type of geometric element in the mesh",
"hex8");
346 e_type = libMesh::Utility::string_to_enum<libMesh::ElemType>(t);
352 if (c.fe_order > 1 && e_type == libMesh::HEX8)
353 e_type = libMesh::HEX27;
354 else if (c.fe_order > 1 && e_type == libMesh::TET4)
355 e_type = libMesh::TET10;
361 nx_divs, ny_divs, nz_divs,
365 dirichlet_length_fraction,
371 libMesh::MeshRefinement(mesh).uniformly_refine(n_refine);
372 libMesh::MeshTools::Modification::flatten(mesh);
378 template <
typename Context>
382 c.sys->get_dof_map().add_dirichlet_boundary
383 (libMesh::DirichletBoundary({6}, {0}, libMesh::ZeroFunction<real_t>()));
387 template <
typename ScalarType,
typename Context>
396 Assert2(c.fe_family == libMesh::LAGRANGE,
397 c.fe_family, libMesh::LAGRANGE,
398 "Method assumes Lagrange interpolation function for density");
402 length = c.input(
"length",
"length of domain along x-axis", 1.),
403 height = c.input(
"height",
"length of domain along y-axis", 1.),
404 filter_radius = c.input(
"filter_radius",
"radius of geometric filter for level set field", 0.1),
405 vf = c.input(
"volume_fraction",
"upper limit for the volume fraction", 0.3);
408 sys_num = c.rho_sys->number(),
409 first_dof = c.rho_sys->get_dof_map().first_dof(c.rho_sys->comm().rank()),
410 end_dof = c.rho_sys->get_dof_map().end_dof(c.rho_sys->comm().rank()),
416 libMesh::MeshBase::const_element_iterator
417 e_it = c.mesh->active_local_elements_begin(),
418 e_end = c.mesh->active_local_elements_end();
420 std::set<const libMesh::Node*> nodes;
422 for ( ; e_it != e_end; e_it++) {
424 const libMesh::Elem* e = *e_it;
426 for (
uint_t i=0; i<e->n_nodes(); i++) {
428 const libMesh::Node& n = *e->node_ptr(i);
439 dof_id = n.dof_number(sys_num, 0, 0);
445 if (dof_id >= first_dof &&
454 c.rho_sys->solution->close();
463 #endif // __mast_mesh_generation_truss_3d_h__
uint_t idx(const libMesh::ElemType type, const uint_t nx, const uint_t ny, const uint_t i, const uint_t j, const uint_t k)
MAST::Base::ParameterData & add_ghosted_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
void init_simp_dvs(Context &c, MAST::Optimization::DesignParameterVector< ScalarType > &dvs)
MAST::Base::ParameterData & add_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
real_t reference_volume(Context &c)
void init_analysis_dirichlet_conditions(Context &c)
#define Assert0(cond, msg)
#define Assert2(cond, v1, v2, msg)
void build_cube(libMesh::UnstructuredMesh &mesh, const uint_t nx, const uint_t ny, const uint_t nz, const real_t length, const real_t height, const real_t width, const real_t dirichlet_length_fraction, const libMesh::ElemType type)
void set_point(real_t x, real_t y=0., real_t z=0.)
void init_analysis_mesh(Context &c, libMesh::UnstructuredMesh &mesh)
void synchronize(const libMesh::DofMap &dof_map)
std::unique_ptr< ValType > build(const libMesh::System &sys)