83 for (
int k=0; k<max_its; k++)
88 MPI_SUM, MPI_COMM_WORLD);
94 MPI_SUM, MPI_COMM_WORLD);
98 if (abs(dc) < tol) { done =
true;
break; }
102 mfem_warning(
"Projection reached maximum iteration without converging. "
103 "Result may not be accurate.");
106 real_t material_volume = int_sigmoid_psi.
Sum();
107 MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1,
109 return material_volume;
184int main(
int argc,
char *argv[])
197 real_t vol_fraction = 0.5;
204 bool glvis_visualization =
true;
205 bool paraview_output =
false;
208 args.
AddOption(&ref_levels,
"-r",
"--refine",
209 "Number of times to refine the mesh uniformly.");
211 "Order (degree) of the finite elements.");
213 "Step length for gradient descent.");
215 "Length scale for ρ.");
216 args.
AddOption(&max_it,
"-mi",
"--max-it",
217 "Maximum number of gradient descent iterations.");
218 args.
AddOption(&ntol,
"-ntol",
"--rel-tol",
219 "Normalized exit tolerance.");
220 args.
AddOption(&itol,
"-itol",
"--abs-tol",
221 "Increment exit tolerance.");
222 args.
AddOption(&vol_fraction,
"-vf",
"--volume-fraction",
223 "Volume fraction for the material density.");
224 args.
AddOption(&lambda,
"-lambda",
"--lambda",
228 args.
AddOption(&rho_min,
"-rmin",
"--psi-min",
229 "Minimum of density coefficient.");
230 args.
AddOption(&glvis_visualization,
"-vis",
"--visualization",
"-no-vis",
231 "--no-visualization",
232 "Enable or disable GLVis visualization.");
233 args.
AddOption(¶view_output,
"-pv",
"--paraview",
"-no-pv",
235 "Enable or disable ParaView output.");
248 mfem::out << num_procs <<
" number of process created.\n";
257 for (
int i = 0; i<mesh.
GetNBE(); i++)
267 center(0) = 0.5*(coords1[0] + coords2[0]);
268 center(1) = 0.5*(coords1[1] + coords2[1]);
270 if (abs(center(0) - 0.0) < 1e-10)
284 for (
int lev = 0; lev < ref_levels; lev++)
289 ParMesh pmesh(MPI_COMM_WORLD, mesh);
306 cout <<
"Number of state unknowns: " << state_size << endl;
307 cout <<
"Number of filter unknowns: " << filter_size << endl;
308 cout <<
"Number of control unknowns: " << control_size << endl;
317 rho_filter = vol_fraction;
337 ElasticitySolver->
SetMesh(&pmesh);
340 Vector center(2); center(0) = 2.9; center(1) = 0.5;
341 Vector force(2); force(0) = 0.0; force(1) = -1.0;
383 real_t domain_volume = vol_form(onegf);
384 const real_t target_volume = domain_volume * vol_fraction;
390 if (glvis_visualization)
413 for (
int k = 1; k <= max_it; k++)
419 cout <<
"\nStep = " << k << endl;
425 FilterSolver->
Solve();
434 ElasticitySolver->
Solve();
442 FilterSolver->
Solve();
455 const real_t material_volume =
proj(psi, target_volume);
459 real_t norm_reduced_gradient = norm_increment/
alpha;
464 MPI_SUM, MPI_COMM_WORLD);
467 mfem::out <<
"norm of the reduced gradient = " << norm_reduced_gradient << endl;
468 mfem::out <<
"norm of the increment = " << norm_increment << endl;
469 mfem::out <<
"compliance = " << compliance << endl;
470 mfem::out <<
"volume fraction = " << material_volume / domain_volume << endl;
473 if (glvis_visualization)
477 sout_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
478 sout_r <<
"solution\n" << pmesh << r_gf
479 <<
"window_title 'Design density r(ρ̃)'" << flush;
490 if (norm_reduced_gradient < ntol && norm_increment < itol)
496 delete ElasticitySolver;
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
@ GaussLobatto
Closed type.
A coefficient that is constant across space and time.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetTime(real_t t)
Set physical time (for time-dependent simulations)
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
Returns f(u(x)) - f(v(x)) where u, v are scalar GridFunctions and f:R → R.
Class for solving Poisson's equation:
void SetDiffusionCoefficient(Coefficient *diffcf_)
void SetRHSCoefficient(Coefficient *rhscf_)
void SetOrder(int order_)
void SetMesh(Mesh *mesh_)
void SetMassCoefficient(Coefficient *masscf_)
GridFunction * GetFEMSolution()
void SetEssentialBoundary(const Array< int > &ess_bdr_)
Class for domain integration .
Abstract data type element.
virtual void GetVertices(Array< int > &v) const =0
Get the indices defining the vertices.
void SetAttribute(const int attr)
Set element's attribute.
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
Arbitrary order H1-conforming (continuous) finite elements.
Wrapper for hypre's ParCSR matrix class.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, real_t alpha=1.0, real_t beta=0.0) const
Computes y = alpha * A * x + beta * y.
static void Init()
Initialize hypre by calling HYPRE_Init() and set default options. After calling Hypre::Init(),...
Integrator that inverts the matrix assembled by another integrator.
Arbitrary order "L2-conforming" discontinuous finite elements.
Class for solving linear elasticity:
GridFunction * GetFEMSolution()
void SetEssentialBoundary(const Array< int > &ess_bdr_)
void SetRHSCoefficient(VectorCoefficient *rhs_cf_)
void SetMesh(Mesh *mesh_)
LinearForm * GetLinearForm()
void SetOrder(int order_)
void SetLameCoefficients(Coefficient *lambda_cf_, Coefficient *mu_cf_)
Returns f(u(x)) where u is a scalar GridFunction and f:R → R.
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
void Clear()
Clear the contents of the Mesh.
int Dimension() const
Dimension of the reference space used within the elements.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
int GetNBE() const
Returns number of boundary elements.
static Mesh MakeCartesian2D(int nx, int ny, Element::Type type, bool generate_edges=false, real_t sx=1.0, real_t sy=1.0, bool sfc_ordering=true)
Creates mesh for the rectangle [0,sx]x[0,sy], divided into nx*ny quadrilaterals if type = QUADRILATER...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
const real_t * GetVertex(int i) const
Return pointer to vertex i's coordinates.
static int WorldRank()
Return the MPI rank in MPI_COMM_WORLD.
static int WorldSize()
Return the size of MPI_COMM_WORLD.
static void Init(int &argc, char **&argv, int required=default_thread_required, int *provided=nullptr)
Singleton creation with Mpi::Init(argc, argv).
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void PrintUsage(std::ostream &out) const
Print the usage message.
void PrintOptions(std::ostream &out) const
Print the options.
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
HYPRE_BigInt GlobalTrueVSize() const
Class for parallel grid function.
real_t ComputeL1Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const override
ParFiniteElementSpace * ParFESpace() const
void ProjectCoefficient(Coefficient &coeff) override
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
Class for parallel meshes.
Helper class for ParaView visualization data.
void SetHighOrderOutput(bool high_order_output_)
void SetLevelsOfDetail(int levels_of_detail_)
virtual void Save() override
void SetDataFormat(VTKFormat fmt)
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Solid isotropic material penalization (SIMP) coefficient.
Strain energy density coefficient.
real_t Sum() const
Return the sum of the vector entries.
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
Volumetric force for linear elasticity.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
real_t proj(ParGridFunction &psi, real_t target_volume, real_t tol=1e-12, int max_its=10)
Bregman projection of ρ = sigmoid(ψ) onto the subspace ∫_Ω ρ dx = θ vol(Ω) as follows:
real_t sigmoid(real_t x)
Sigmoid function.
real_t u(const Vector &xvec)
void mfem_warning(const char *msg)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
real_t inv_sigmoid(real_t x)
Inverse sigmoid function.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t der_sigmoid(real_t x)
Derivative of sigmoid function.
Helper struct to convert a C++ type to an MPI type.