20 #ifndef __mast_mesh_generation_bracket_2d_h__ 21 #define __mast_mesh_generation_bracket_2d_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> 45 namespace Generation {
50 template <
typename ScalarType>
60 template <
typename ContextType>
61 inline ScalarType
value(ContextType& c)
const {
62 ScalarType v=(c.qp_location(0)>=
_l1*(1.-
_frac))?
_p:0.;
66 template <
typename ContextType,
typename ScalarFieldType>
68 const ScalarFieldType& f)
const {
77 template <
typename ScalarType>
80 template <
typename Context>
85 length = c.input(
"length",
"length of domain along x-axis", 0.3),
86 height = c.input(
"height",
"length of domain along y-axis", 0.3);
88 return length * height;
106 return i + (2*nx+1)*j;
110 Error(
false,
"Invalid element type");
113 return libMesh::invalid_uint;
123 const libMesh::ElemType type) {
125 Assert0(type == libMesh::QUAD4 || type == libMesh::QUAD9,
126 "Method only implemented for Quad4/Quad9");
131 libMesh::BoundaryInfo & boundary_info = mesh.get_boundary_info();
133 mesh.set_mesh_dimension(3);
134 mesh.set_spatial_dimension(3);
135 mesh.reserve_elem(nx*ny);
137 if (type == libMesh::QUAD4)
138 mesh.reserve_nodes( (nx+1)*(ny+1));
139 else if (type == libMesh::QUAD9)
140 mesh.reserve_nodes( (2*nx+1)*(2*ny+1));
147 std::map<uint_t, libMesh::Node*> nodes;
155 case libMesh::QUAD4: {
157 for (
uint_t j=0; j<=ny; j++)
158 for (
uint_t i=0; i<=nx; i++) {
159 if ( i<=nx/10*4 || j>=ny/10*6) {
161 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(nx)*length,
162 static_cast<real_t>(j)/static_cast<real_t>(ny)*height,
173 case libMesh::QUAD9: {
175 for (
uint_t j=0; j<=(2*ny); j++)
176 for (
uint_t i=0; i<=(2*nx); i++) {
177 if ( i<=2*nx/10*4 || j>=2*ny/10*6) {
179 mesh.add_point(libMesh::Point(static_cast<real_t>(i)/static_cast<real_t>(2*nx)*length,
180 static_cast<real_t>(j)/static_cast<real_t>(2*ny)*height,
192 Assert0(
false,
"ERROR: Unrecognized 2D element type.");
200 case libMesh::QUAD4: {
202 for (
uint_t j=0; j<ny; j++)
203 for (
uint_t i=0; i<nx; i++) {
204 if (i < nx*4/10 || j>=ny*6/10) {
208 elem->set_id(elem_id++);
211 elem->set_node(0) = nodes[
idx(type,nx,i,j) ];
212 elem->set_node(1) = nodes[
idx(type,nx,i+1,j) ];
213 elem->set_node(2) = nodes[
idx(type,nx,i+1,j+1) ];
214 elem->set_node(3) = nodes[
idx(type,nx,i,j+1) ];
217 boundary_info.add_side(elem, 0, 0);
220 boundary_info.add_side(elem, 2, 2);
223 boundary_info.add_side(elem, 3, 3);
226 boundary_info.add_side(elem, 1, 1);
228 if (i==nx*3/10 && j<ny*6/10)
229 boundary_info.add_side(elem, 1, 4);
231 if (j==ny*6/10 && i>nx*3/10)
232 boundary_info.add_side(elem, 0, 5);
239 case libMesh::QUAD9: {
241 for (
uint_t j=0; j<(2*ny); j += 2)
242 for (
uint_t i=0; i<(2*nx); i += 2) {
243 if (i < 2*nx*4/10 || j>= 2*ny*6/10) {
247 elem->set_id(elem_id++);
250 elem->set_node(0) = nodes[
idx(type,nx,i, j) ];
251 elem->set_node(1) = nodes[
idx(type,nx,i+2,j) ];
252 elem->set_node(2) = nodes[
idx(type,nx,i+2,j+2) ];
253 elem->set_node(3) = nodes[
idx(type,nx,i, j+2) ];
254 elem->set_node(4) = nodes[
idx(type,nx,i+1,j) ];
255 elem->set_node(5) = nodes[
idx(type,nx,i+2,j+1) ];
256 elem->set_node(6) = nodes[
idx(type,nx,i+1,j+2) ];
257 elem->set_node(7) = nodes[
idx(type,nx,i, j+1) ];
258 elem->set_node(8) = nodes[
idx(type,nx,i+1,j+1) ];
261 boundary_info.add_side(elem, 0, 0);
264 boundary_info.add_side(elem, 2, 2);
267 boundary_info.add_side(elem, 3, 3);
270 boundary_info.add_side(elem, 1, 1);
272 if (i==2*nx*3/10 && j<2*ny*6/10)
273 boundary_info.add_side(elem, 1, 4);
275 if (j==2*ny*6/10 && i>2*nx*3/10)
276 boundary_info.add_side(elem, 0, 5);
283 Assert0(
false,
"ERROR: Unrecognized 2D element type.");
287 boundary_info.sideset_name(0) =
"bottom";
288 boundary_info.sideset_name(1) =
"right";
289 boundary_info.sideset_name(2) =
"top";
290 boundary_info.sideset_name(3) =
"left";
291 boundary_info.sideset_name(4) =
"facing_right";
292 boundary_info.sideset_name(5) =
"facing_down";
295 boundary_info.nodeset_name(0) =
"bottom";
296 boundary_info.nodeset_name(1) =
"right";
297 boundary_info.nodeset_name(2) =
"top";
298 boundary_info.nodeset_name(3) =
"left";
301 mesh.prepare_for_use ();
305 template <
typename Context>
308 libMesh::UnstructuredMesh& mesh) {
311 length = c.input(
"length",
"length of domain along x-axis", 0.3),
312 height = c.input(
"height",
"length of domain along y-axis", 0.3);
315 nx_divs = c.input(
"nx_divs",
"number of elements along x-axis", 20),
316 ny_divs = c.input(
"ny_divs",
"number of elements along y-axis", 20);
318 if (nx_divs%10 != 0 || ny_divs%10 != 0) libmesh_error();
321 t = c.input(
"elem_type",
"type of geometric element in the mesh",
"quad4");
324 e_type = libMesh::Utility::string_to_enum<libMesh::ElemType>(t);
330 if (c.sol_fe_order > 1 && e_type == libMesh::QUAD4)
331 e_type = libMesh::QUAD9;
374 template <
typename Context>
378 c.sys->get_dof_map().add_dirichlet_boundary
379 (libMesh::DirichletBoundary({0}, {0, 1}, libMesh::ZeroFunction<real_t>()));
384 template <
typename ScalarType,
typename InitType>
385 std::unique_ptr<pressure_t<ScalarType>>
389 length = c.input(
"length",
"length of domain along x-axis", 0.3),
390 frac = c.input(
"loadlength_fraction",
"fraction of boundary length on which pressure will act", 0.125),
391 p_val = c.input(
"pressure",
"pressure on side of domain", 5.e7);
394 std::unique_ptr<pressure_t<ScalarType>>
506 template <
typename ScalarType,
typename Context>
515 Assert2(c.rho_fe_family == libMesh::LAGRANGE,
516 c.rho_fe_family, libMesh::LAGRANGE,
517 "Method assumes Lagrange interpolation function for density");
518 Assert2(c.rho_fe_order == libMesh::FIRST,
519 c.rho_fe_order, libMesh::FIRST,
520 "Method assumes Lagrange interpolation function for density");
524 length = c.input(
"length",
"length of domain along x-axis", 0.3),
525 height = c.input(
"height",
"length of domain along y-axis", 0.3),
526 rho_min = c.input(
"rho_min",
"lower limit on density variable", 0.),
527 vf = c.input(
"volume_fraction",
528 "upper limit for the volume fraction", 0.2);
531 sys_num = c.rho_sys->number(),
532 first_dof = c.rho_sys->get_dof_map().first_dof(c.rho_sys->comm().rank()),
533 end_dof = c.rho_sys->get_dof_map().end_dof(c.rho_sys->comm().rank()),
539 libMesh::MeshBase::const_element_iterator
540 e_it = c.mesh->active_local_elements_begin(),
541 e_end = c.mesh->active_local_elements_end();
543 std::set<const libMesh::Node*> nodes;
545 for ( ; e_it != e_end; e_it++) {
547 const libMesh::Elem* e = *e_it;
549 Assert0(e->type() == libMesh::QUAD4 ||
550 e->type() == libMesh::QUAD9,
551 "Method requires Quad4/Quad9 element");
554 for (
uint_t i=0; i<4; i++) {
556 const libMesh::Node& n = *e->node_ptr(i);
567 dof_id = n.dof_number(sys_num, 0, 0);
573 if (dof_id >= first_dof &&
582 c.rho_sys->solution->close();
635 #endif // __mast_mesh_generation_bracket_2d_h__
MAST::Base::ParameterData & add_ghosted_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
Pressure(real_t p, real_t l1, real_t frac)
real_t reference_volume(Context &c)
uint_t idx(const libMesh::ElemType type, const uint_t nx, const uint_t i, const uint_t j)
ScalarType value(ContextType &c) const
MAST::Base::ParameterData & add_topology_parameter(MAST::Optimization::DesignParameter< ScalarType > &p, const uint_t id)
void build_mesh(libMesh::UnstructuredMesh &mesh, const uint_t nx, const uint_t ny, const real_t length, const real_t height, const libMesh::ElemType type)
void init_analysis_mesh(Context &c, libMesh::UnstructuredMesh &mesh)
void init_analysis_dirichlet_conditions(Context &c)
#define Assert0(cond, msg)
#define Assert2(cond, v1, v2, msg)
void init_simp_dvs(Context &c, MAST::Optimization::DesignParameterVector< ScalarType > &dvs)
void set_point(real_t x, real_t y=0., real_t z=0.)
void synchronize(const libMesh::DofMap &dof_map)
std::unique_ptr< ValType > build(const libMesh::System &sys)
ScalarType derivative(ContextType &c, const ScalarFieldType &f) const
std::unique_ptr< pressure_t< ScalarType > > build_pressure_load(InitType &c)