20 #ifndef __mast_mesh_generation_bracket_3d_h__ 21 #define __mast_mesh_generation_bracket_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 {
51 template <
typename ScalarType>
61 template <
typename ContextType>
62 inline ScalarType
value(ContextType& c)
const {
63 ScalarType v=(c.qp_location(0)>=
_l1*(1.-
_frac))?
_p:0.;
67 template <
typename ContextType,
typename ScalarFieldType>
69 const ScalarFieldType& f)
const {
78 template <
typename ScalarType>
81 template <
typename Context>
86 length = c.input(
"length",
"length of domain along x-axis", 0.3),
87 height = c.input(
"height",
"length of domain along y-axis", 0.3),
88 width = c.input(
"width",
"length of domain along z-axis", 0.06);
90 return length * height * width;
105 return i + (nx+1)*(j + k*(ny+1));
110 return i + (2*nx+1)*(j + k*(2*ny+1));
114 Error(
false,
"Invalid element type");
117 return libMesh::invalid_uint;
128 const libMesh::ElemType type) {
130 Assert0(type == libMesh::HEX8 || type == libMesh::HEX27,
131 "Method only implemented for Hex8/Hex27");
136 libMesh::BoundaryInfo & boundary_info = mesh.get_boundary_info();
138 mesh.set_mesh_dimension(3);
139 mesh.set_spatial_dimension(3);
140 mesh.reserve_elem(nx*ny*nz);
142 if (type == libMesh::HEX8)
143 mesh.reserve_nodes( (nx+1)*(ny+1)*(nz+1) );
144 else if (type == libMesh::HEX27)
145 mesh.reserve_nodes( (2*nx+1)*(2*ny+1)*(2*nz+1) );
154 std::map<uint_t, libMesh::Node*> nodes;
162 case libMesh::HEX8: {
164 for (
uint_t k=0; k<=nz; k++)
165 for (
uint_t j=0; j<=ny; j++)
166 for (
uint_t i=0; i<=nx; i++) {
167 if ( i<=nx/10*4 || j>=ny/10*6) {
169 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(nx)*length,
170 static_cast<real_t>(j)/static_cast<real_t>(ny)*height,
171 static_cast<real_t>(k)/static_cast<real_t>(nz)*width),
181 case libMesh::HEX27: {
183 for (
uint_t k=0; k<=(2*nz); k++)
184 for (
uint_t j=0; j<=(2*ny); j++)
185 for (
uint_t i=0; i<=(2*nx); i++) {
186 if ( i<=2*nx/10*4 || j>=2*ny/10*6) {
188 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(2*nx)*length,
189 static_cast<real_t>(j)/static_cast<real_t>(2*ny)*height,
190 static_cast<real_t>(k)/static_cast<real_t>(2*nz)*width),
201 Assert0(
false,
"ERROR: Unrecognized 3D element type.");
211 for (
uint_t k=0; k<nz; k++)
212 for (
uint_t j=0; j<ny; j++)
213 for (
uint_t i=0; i<nx; i++) {
214 if (i < nx*4/10 || j>=ny*6/10) {
218 elem->set_id(elem_id++);
221 elem->set_node(0) = nodes[
idx(type,nx,ny,i,j,k) ];
222 elem->set_node(1) = nodes[
idx(type,nx,ny,i+1,j,k) ];
223 elem->set_node(2) = nodes[
idx(type,nx,ny,i+1,j+1,k) ];
224 elem->set_node(3) = nodes[
idx(type,nx,ny,i,j+1,k) ];
225 elem->set_node(4) = nodes[
idx(type,nx,ny,i,j,k+1) ];
226 elem->set_node(5) = nodes[
idx(type,nx,ny,i+1,j,k+1) ];
227 elem->set_node(6) = nodes[
idx(type,nx,ny,i+1,j+1,k+1)];
228 elem->set_node(7) = nodes[
idx(type,nx,ny,i,j+1,k+1) ];
231 boundary_info.add_side(elem, 0, 0);
234 boundary_info.add_side(elem, 5, 5);
237 boundary_info.add_side(elem, 1, 1);
240 boundary_info.add_side(elem, 3, 3);
243 boundary_info.add_side(elem, 4, 4);
246 boundary_info.add_side(elem, 2, 2);
248 if (i==nx*3/10 && j<ny*6/10)
249 boundary_info.add_side(elem, 2, 6);
251 if (j==ny*6/10 && i>nx*3/10)
252 boundary_info.add_side(elem, 1, 7);
259 case libMesh::HEX27: {
261 for (
uint_t k=0; k<(2*nz); k += 2)
262 for (
uint_t j=0; j<(2*ny); j += 2)
263 for (
uint_t i=0; i<(2*nx); i += 2) {
264 if (i < 2*nx*4/10 || j>=2*ny*6/10) {
268 elem->set_id(elem_id++);
271 elem->set_node(0) = nodes[
idx(type,nx,ny,i, j, k) ];
272 elem->set_node(1) = nodes[
idx(type,nx,ny,i+2,j, k) ];
273 elem->set_node(2) = nodes[
idx(type,nx,ny,i+2,j+2,k) ];
274 elem->set_node(3) = nodes[
idx(type,nx,ny,i, j+2,k) ];
275 elem->set_node(4) = nodes[
idx(type,nx,ny,i, j, k+2)];
276 elem->set_node(5) = nodes[
idx(type,nx,ny,i+2,j, k+2)];
277 elem->set_node(6) = nodes[
idx(type,nx,ny,i+2,j+2,k+2)];
278 elem->set_node(7) = nodes[
idx(type,nx,ny,i, j+2,k+2)];
279 elem->set_node(8) = nodes[
idx(type,nx,ny,i+1,j, k) ];
280 elem->set_node(9) = nodes[
idx(type,nx,ny,i+2,j+1,k) ];
281 elem->set_node(10) = nodes[
idx(type,nx,ny,i+1,j+2,k) ];
282 elem->set_node(11) = nodes[
idx(type,nx,ny,i, j+1,k) ];
283 elem->set_node(12) = nodes[
idx(type,nx,ny,i, j, k+1)];
284 elem->set_node(13) = nodes[
idx(type,nx,ny,i+2,j, k+1)];
285 elem->set_node(14) = nodes[
idx(type,nx,ny,i+2,j+2,k+1)];
286 elem->set_node(15) = nodes[
idx(type,nx,ny,i, j+2,k+1)];
287 elem->set_node(16) = nodes[
idx(type,nx,ny,i+1,j, k+2)];
288 elem->set_node(17) = nodes[
idx(type,nx,ny,i+2,j+1,k+2)];
289 elem->set_node(18) = nodes[
idx(type,nx,ny,i+1,j+2,k+2)];
290 elem->set_node(19) = nodes[
idx(type,nx,ny,i, j+1,k+2)];
292 elem->set_node(20) = nodes[
idx(type,nx,ny,i+1,j+1,k) ];
293 elem->set_node(21) = nodes[
idx(type,nx,ny,i+1,j, k+1)];
294 elem->set_node(22) = nodes[
idx(type,nx,ny,i+2,j+1,k+1)];
295 elem->set_node(23) = nodes[
idx(type,nx,ny,i+1,j+2,k+1)];
296 elem->set_node(24) = nodes[
idx(type,nx,ny,i, j+1,k+1)];
297 elem->set_node(25) = nodes[
idx(type,nx,ny,i+1,j+1,k+2)];
298 elem->set_node(26) = nodes[
idx(type,nx,ny,i+1,j+1,k+1)];
301 boundary_info.add_side(elem, 0, 0);
304 boundary_info.add_side(elem, 5, 5);
307 boundary_info.add_side(elem, 1, 1);
310 boundary_info.add_side(elem, 3, 3);
313 boundary_info.add_side(elem, 4, 4);
316 boundary_info.add_side(elem, 2, 2);
318 if (i==2*nx*3/10 && j<2*ny*6/10)
319 boundary_info.add_side(elem, 2, 6);
321 if (j==2*ny*6/10 && i>2*nx*3/10)
322 boundary_info.add_side(elem, 1, 7);
329 Assert0(
false,
"ERROR: Unrecognized 3D element type.");
333 boundary_info.sideset_name(0) =
"back";
334 boundary_info.sideset_name(1) =
"bottom";
335 boundary_info.sideset_name(2) =
"right";
336 boundary_info.sideset_name(3) =
"top";
337 boundary_info.sideset_name(4) =
"left";
338 boundary_info.sideset_name(5) =
"front";
339 boundary_info.sideset_name(6) =
"facing_right";
340 boundary_info.sideset_name(7) =
"facing_down";
343 boundary_info.nodeset_name(0) =
"back";
344 boundary_info.nodeset_name(1) =
"bottom";
345 boundary_info.nodeset_name(2) =
"right";
346 boundary_info.nodeset_name(3) =
"top";
347 boundary_info.nodeset_name(4) =
"left";
348 boundary_info.nodeset_name(5) =
"front";
351 mesh.prepare_for_use ();
356 template <
typename Context>
359 libMesh::UnstructuredMesh& mesh) {
362 length = c.input(
"length",
"length of domain along x-axis", 0.3),
363 height = c.input(
"height",
"length of domain along y-axis", 0.3),
364 width = c.input(
"width",
"length of domain along z-axis", 0.06);
367 nx_divs = c.input(
"nx_divs",
"number of elements along x-axis", 10),
368 ny_divs = c.input(
"ny_divs",
"number of elements along y-axis", 10),
369 nz_divs = c.input(
"nz_divs",
"number of elements along z-axis", 2),
370 n_refine= c.input(
"n_uniform_refinement",
"number of times the mesh is uniformly refined", 0);
372 if (nx_divs%10 != 0 || ny_divs%10 != 0)
373 Error(
false,
"number of divisions in x and y must be multiples of 10");
376 t = c.input(
"elem_type",
"type of geometric element in the mesh",
"hex8");
379 e_type = libMesh::Utility::string_to_enum<libMesh::ElemType>(t);
385 if (c.sol_fe_order > 1 && e_type == libMesh::HEX8)
386 e_type = libMesh::HEX27;
387 else if (c.sol_fe_order > 1 && e_type == libMesh::TET4)
388 e_type = libMesh::TET10;
394 nx_divs, ny_divs, nz_divs,
403 libMesh::MeshRefinement(mesh).uniformly_refine(n_refine);
404 libMesh::MeshTools::Modification::flatten(mesh);
410 template <
typename Context>
414 c.sys->get_dof_map().add_dirichlet_boundary
415 (libMesh::DirichletBoundary({1}, {0, 1, 2}, libMesh::ZeroFunction<real_t>()));
420 template <
typename ScalarType,
typename InitType>
421 std::unique_ptr<pressure_t<ScalarType>>
425 length = c.input(
"length",
"length of domain along x-axis", 0.3),
426 frac = c.input(
"loadlength_fraction",
"fraction of boundary length on which pressure will act", 0.125),
427 p_val = c.input(
"pressure",
"pressure on side of domain", 5.e7);
430 std::unique_ptr<pressure_t<ScalarType>>
438 template <
typename ScalarType,
typename Context>
447 Assert2(c.rho_fe_family == libMesh::LAGRANGE,
448 c.rho_fe_family, libMesh::LAGRANGE,
449 "Method assumes Lagrange interpolation function for density");
450 Assert2(c.rho_fe_order == libMesh::FIRST,
451 c.rho_fe_order, libMesh::FIRST,
452 "Method assumes Lagrange interpolation function for density");
456 rho_min = c.input(
"rho_min",
"lower limit on density variable", 0.),
457 vf = c.input(
"volume_fraction",
"upper limit for the volume fraction", 0.2);
460 sys_num = c.rho_sys->number(),
461 first_dof = c.rho_sys->get_dof_map().first_dof(c.rho_sys->comm().rank()),
462 end_dof = c.rho_sys->get_dof_map().end_dof(c.rho_sys->comm().rank()),
468 libMesh::MeshBase::const_element_iterator
469 e_it = c.mesh->active_local_elements_begin(),
470 e_end = c.mesh->active_local_elements_end();
472 std::set<const libMesh::Node*> nodes;
474 for ( ; e_it != e_end; e_it++) {
476 const libMesh::Elem* e = *e_it;
478 Assert0(e->type() == libMesh::HEX8 ||
479 e->type() == libMesh::HEX27,
480 "Method requires Hex8/Hex27 element");
483 for (
uint_t i=0; i<8; i++) {
485 const libMesh::Node& n = *e->node_ptr(i);
496 dof_id = n.dof_number(sys_num, 0, 0);
502 if (dof_id >= first_dof &&
511 c.rho_sys->solution->close();
520 #endif // __mast_mesh_generation_bracket_3d_h__
void init_simp_dvs(Context &c, MAST::Optimization::DesignParameterVector< ScalarType > &dvs)
MAST::Base::ParameterData & add_ghosted_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
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)
void init_analysis_dirichlet_conditions(Context &c)
ScalarType value(ContextType &c) const
void init_analysis_mesh(Context &c, libMesh::UnstructuredMesh &mesh)
MAST::Base::ParameterData & add_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
ScalarType derivative(ContextType &c, const ScalarFieldType &f) const
#define Assert0(cond, msg)
Pressure(real_t p, real_t l1, real_t frac)
#define Assert2(cond, v1, v2, msg)
void set_point(real_t x, real_t y=0., real_t z=0.)
std::unique_ptr< pressure_t< ScalarType > > build_pressure_load(InitType &c)
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 libMesh::ElemType type)
void synchronize(const libMesh::DofMap &dof_map)
std::unique_ptr< ValType > build(const libMesh::System &sys)
real_t reference_volume(Context &c)