83 for (
int k=0; k<max_its; k++)
85 int_sigmoid_psi.Assemble();
86 double f = int_sigmoid_psi.Sum();
87 MPI_Allreduce(MPI_IN_PLACE, &
f, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
90 int_der_sigmoid_psi.Assemble();
91 double df = int_der_sigmoid_psi.Sum();
92 MPI_Allreduce(MPI_IN_PLACE, &df, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
94 const double dc = -
f/df;
96 if (abs(dc) < tol) { done =
true;
break; }
100 mfem_warning(
"Projection reached maximum iteration without converging. " 101 "Result may not be accurate.");
103 int_sigmoid_psi.Assemble();
104 double material_volume = int_sigmoid_psi.Sum();
105 MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1, MPI_DOUBLE, MPI_SUM,
107 return material_volume;
182 int main(
int argc,
char *argv[])
186 int num_procs = Mpi::WorldSize();
187 int myid = Mpi::WorldRank();
195 double vol_fraction = 0.5;
199 double rho_min = 1e-6;
202 bool glvis_visualization =
true;
203 bool paraview_output =
false;
206 args.
AddOption(&ref_levels,
"-r",
"--refine",
207 "Number of times to refine the mesh uniformly.");
209 "Order (degree) of the finite elements.");
211 "Step length for gradient descent.");
213 "Length scale for ρ.");
214 args.
AddOption(&max_it,
"-mi",
"--max-it",
215 "Maximum number of gradient descent iterations.");
216 args.
AddOption(&ntol,
"-ntol",
"--rel-tol",
217 "Normalized exit tolerance.");
218 args.
AddOption(&itol,
"-itol",
"--abs-tol",
219 "Increment exit tolerance.");
220 args.
AddOption(&vol_fraction,
"-vf",
"--volume-fraction",
221 "Volume fraction for the material density.");
222 args.
AddOption(&lambda,
"-lambda",
"--lambda",
226 args.
AddOption(&rho_min,
"-rmin",
"--psi-min",
227 "Minimum of density coefficient.");
228 args.
AddOption(&glvis_visualization,
"-vis",
"--visualization",
"-no-vis",
229 "--no-visualization",
230 "Enable or disable GLVis visualization.");
231 args.
AddOption(¶view_output,
"-pv",
"--paraview",
"-no-pv",
233 "Enable or disable ParaView output.");
246 mfem::out << num_procs <<
" number of process created.\n";
250 Mesh mesh = Mesh::MakeCartesian2D(3, 1, mfem::Element::Type::QUADRILATERAL,
255 for (
int i = 0; i<mesh.
GetNBE(); i++)
261 double * coords1 = mesh.
GetVertex(vertices[0]);
262 double * coords2 = mesh.
GetVertex(vertices[1]);
265 center(0) = 0.5*(coords1[0] + coords2[0]);
266 center(1) = 0.5*(coords1[1] + coords2[1]);
268 if (abs(center(0) - 0.0) < 1e-10)
282 for (
int lev = 0; lev < ref_levels; lev++)
287 ParMesh pmesh(MPI_COMM_WORLD, mesh);
294 BasisType::GaussLobatto);
304 cout <<
"Number of state unknowns: " << state_size << endl;
305 cout <<
"Number of filter unknowns: " << filter_size << endl;
306 cout <<
"Number of control unknowns: " << control_size << endl;
315 rho_filter = vol_fraction;
335 ElasticitySolver->
SetMesh(&pmesh);
338 Vector center(2); center(0) = 2.9; center(1) = 0.5;
339 Vector force(2); force(0) = 0.0; force(1) = -1.0;
381 double domain_volume = vol_form(onegf);
382 const double target_volume = domain_volume * vol_fraction;
388 if (glvis_visualization)
411 for (
int k = 1; k <= max_it; k++)
413 if (k > 1) {
alpha *= ((double) k) / ((double) k-1); }
417 cout <<
"\nStep = " << k << endl;
423 FilterSolver->
Solve();
432 ElasticitySolver->
Solve();
440 FilterSolver->
Solve();
453 const double material_volume =
proj(psi, target_volume);
457 double norm_reduced_gradient = norm_increment/
alpha;
461 MPI_Allreduce(MPI_IN_PLACE,&compliance,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
464 mfem::out <<
"norm of the reduced gradient = " << norm_reduced_gradient << endl;
465 mfem::out <<
"norm of the increment = " << norm_increment << endl;
466 mfem::out <<
"compliance = " << compliance << endl;
467 mfem::out <<
"volume fraction = " << material_volume / domain_volume << endl;
470 if (glvis_visualization)
474 sout_r <<
"parallel " << num_procs <<
" " << myid <<
"\n";
475 sout_r <<
"solution\n" << pmesh << r_gf
476 <<
"window_title 'Design density r(ρ̃)'" << flush;
483 paraview_dc.
SetTime((
double)k);
487 if (norm_reduced_gradient < ntol && norm_increment < itol)
493 delete ElasticitySolver;
Class for domain integration L(v) := (f, v)
GridFunction * GetFEMSolution()
void SetCycle(int c)
Set time cycle (for time-dependent simulations)
void SetDataFormat(VTKFormat fmt)
A coefficient that is constant across space and time.
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void PrintOptions(std::ostream &out) const
Print the options.
LinearForm * GetLinearForm()
int Dimension() const
Dimension of the reference space used within the elements.
Helper class for ParaView visualization data.
void PrintUsage(std::ostream &out) const
Print the usage message.
void SetEssentialBoundary(const Array< int > &ess_bdr_)
int GetOrder() const
Return the order (polynomial degree) of the FE collection, corresponding to the order/degree returned...
Scalar coefficient defined as the product of two scalar coefficients or a scalar and a scalar coeffic...
Coefficient defined by a GridFunction. This coefficient is mesh dependent.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
bool Good() const
Return true if the command line options were parsed successfully.
Abstract parallel finite element space.
virtual void ProjectCoefficient(Coefficient &coeff)
Project coeff Coefficient to this GridFunction. The projection computation depends on the choice of t...
virtual double ComputeL1Error(Coefficient *exsol[], const IntegrationRule *irs[]=NULL) const
int GetNBE() const
Returns number of boundary elements.
double inv_sigmoid(double x)
Inverse sigmoid function.
double der_sigmoid(double x)
Derivative of sigmoid function.
Integrator that inverts the matrix assembled by another integrator.
void SetEssentialBoundary(const Array< int > &ess_bdr_)
Returns f(u(x)) where u is a scalar GridFunction and f:R → R.
Returns f(u(x)) - f(v(x)) where u, v are scalar GridFunctions and f:R → R.
virtual void RegisterField(const std::string &field_name, GridFunction *gf)
Add a grid function to the collection.
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
virtual void SetAttributes()
Determine the sets of unique attribute values in domain and boundary elements.
Class for solving linear elasticity:
double proj(ParGridFunction &psi, double target_volume, double tol=1e-12, int max_its=10)
Bregman projection of ρ = sigmoid(ψ) onto the subspace ∫_Ω ρ dx = θ vol(Ω) as follows: ...
Strain energy density coefficient.
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
void SetRHSCoefficient(Coefficient *rhscf_)
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
double sigmoid(double x)
Sigmoid function.
void SetHighOrderOutput(bool high_order_output_)
void SetTime(double t)
Set physical time (for time-dependent simulations)
HYPRE_BigInt GlobalTrueVSize() const
GridFunction * GetFEMSolution()
Array< int > bdr_attributes
A list of all unique boundary attributes used by the Mesh.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
ParFiniteElementSpace * ParFESpace() const
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...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void SetMesh(Mesh *mesh_)
void SetDiffusionCoefficient(Coefficient *diffcf_)
Solid isotropic material penalization (SIMP) coefficient.
void SetOrder(int order_)
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
void mfem_warning(const char *msg)
Function called by the macro MFEM_WARNING.
void SetMassCoefficient(Coefficient *masscf_)
void SetOrder(int order_)
Class for solving Poisson's equation:
void SetAttribute(const int attr)
Set element's attribute.
int open(const char hostname[], int port)
Open the socket stream on 'port' at 'hostname'.
int Size() const
Return the logical size of the array.
void SetLevelsOfDetail(int levels_of_detail_)
void Clear()
Clear the contents of the Mesh.
void SetLameCoefficients(Coefficient *lambda_cf_, Coefficient *mu_cf_)
Arbitrary order H1-conforming (continuous) finite elements.
virtual void Save() override
double u(const Vector &xvec)
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
Class for parallel grid function.
void SetMesh(Mesh *mesh_)
Wrapper for hypre's ParCSR matrix class.
Class for parallel meshes.
Abstract data type element.
Volumetric force for linear elasticity.
HYPRE_Int Mult(HypreParVector &x, HypreParVector &y, double alpha=1.0, double beta=0.0) const
Computes y = alpha * A * x + beta * y.
void SetPrefixPath(const std::string &prefix)
Set the path where the DataCollection will be saved.
void SetRHSCoefficient(VectorCoefficient *rhs_cf_)
Arbitrary order "L2-conforming" discontinuous finite elements.
double f(const Vector &p)
int main(int argc, char *argv[])