libMesh
Loading...
Searching...
No Matches
adjoints_ex1.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20// <h1>Adjoints Example 1 - Laplace Equation in the L-Shaped Domain with Adjoint based mesh refinement</h1>
21// \author Roy Stogner
22// \date 2011
23//
24// This example solves the Laplace equation on the classic "L-shaped"
25// domain with adaptive mesh refinement. The exact
26// solution is u(r,\theta) = r^{2/3} * \sin ( (2/3) * \theta). The kelly and
27// adjoint residual error estimators are used to develop error indicators and
28// guide mesh adaptation. Since we use the adjoint capabilities of libMesh in
29// this example, we use the DiffSystem framework. This file (adjoints_ex1.C)
30// contains the declaration of mesh and equation system objects, L-shaped.C
31// contains the assembly of the system, element_qoi_derivative.C and
32// side_qoi_derivative.C contain the RHS for the adjoint systems.
33// Postprocessing to compute the QoIs is done in element_postprocess.C and
34// side_postprocess.C.
35
36// The initial mesh contains three QUAD9 elements which represent the
37// standard quadrants I, II, and III of the domain [-1,1]x[-1,1],
38// i.e.
39// Element 0: [-1,0]x[ 0,1]
40// Element 1: [ 0,1]x[ 0,1]
41// Element 2: [-1,0]x[-1,0]
42// The mesh is provided in the standard libMesh ASCII format file
43// named "lshaped.xda". In addition, an input file named "general.in"
44// is provided which allows the user to set several parameters for
45// the solution so that the problem can be re-run without a
46// re-compile. The solution technique employed is to have a
47// refinement loop with a linear (forward and adjoint) solve inside followed by a
48// refinement of the grid and projection of the solution to the new grid
49// In the final loop iteration, there is no additional
50// refinement after the solve. In the input file "general.in", the variable
51// "max_adaptivesteps" controls the number of refinement steps, and
52// "refine_fraction" / "coarsen_fraction" determine the number of
53// elements which will be refined / coarsened at each step.
54
55// C++ includes
56#include <iostream>
57#include <iomanip>
58#include <memory>
59
60// General libMesh includes
61#include "libmesh/equation_systems.h"
62#include "libmesh/error_vector.h"
63#include "libmesh/factory.h"
64#include "libmesh/linear_solver.h"
65#include "libmesh/mesh.h"
66#include "libmesh/mesh_refinement.h"
67#include "libmesh/newton_solver.h"
68#include "libmesh/numeric_vector.h"
69#include "libmesh/partitioner.h"
70#include "libmesh/petsc_diff_solver.h"
71#include "libmesh/steady_solver.h"
72#include "libmesh/system_norm.h"
73#include "libmesh/enum_solver_package.h"
74
75// Error Estimator includes
76#include "libmesh/kelly_error_estimator.h"
77#include "libmesh/patch_recovery_error_estimator.h"
78
79// Adjoint Related includes
80#include "libmesh/adjoint_residual_error_estimator.h"
81#include "libmesh/qoi_set.h"
82
83// libMesh I/O includes
84#include "libmesh/getpot.h"
85#include "libmesh/gmv_io.h"
86#include "libmesh/exodusII_io.h"
87
88// Local includes
89#include "femparameters.h"
90#include "L-shaped.h"
91
92// Bring in everything from the libMesh namespace
93using namespace libMesh;
94
95// Local function declarations
96
97// Number output files, the files are give a prefix of primal or adjoint_i depending on
98// whether the output is the primal solution or the dual solution for the ith QoI
99
100// Write gmv output
101
103 unsigned int a_step, // The adaptive step count
104 std::string solution_type, // primal or adjoint solve
105 FEMParameters & param)
106{
107 // Ignore parameters when there are no output formats available.
108 libmesh_ignore(es, a_step, solution_type, param);
109
110#ifdef LIBMESH_HAVE_GMV
111 if (param.output_gmv)
112 {
113 MeshBase & mesh = es.get_mesh();
114
115 std::ostringstream file_name_gmv;
116 file_name_gmv << solution_type
117 << ".out.gmv."
118 << std::setw(2)
119 << std::setfill('0')
120 << std::right
121 << a_step;
122
124 (file_name_gmv.str(), es);
125 }
126#endif
127
128#ifdef LIBMESH_HAVE_EXODUS_API
129 if (param.output_exodus)
130 {
131 MeshBase & mesh = es.get_mesh();
132
133 // We write out one file per adaptive step. The files are named in
134 // the following way:
135 // foo.e
136 // foo.e-s002
137 // foo.e-s003
138 // ...
139 // so that, if you open the first one with Paraview, it actually
140 // opens the entire sequence of adapted files.
141 std::ostringstream file_name_exodus;
142
143 file_name_exodus << solution_type << ".e";
144 if (a_step > 0)
145 file_name_exodus << "-s"
146 << std::setw(3)
147 << std::setfill('0')
148 << std::right
149 << a_step + 1;
150
151 // We write each adaptive step as a pseudo "time" step, where the
152 // time simply matches the (1-based) adaptive step we are on.
153 ExodusII_IO(mesh).write_timestep(file_name_exodus.str(),
154 es,
155 1,
156 /*time=*/a_step + 1);
157 }
158#endif
159}
160
161// Set the parameters for the nonlinear and linear solvers to be used during the simulation
162
164 FEMParameters & param)
165{
166 // Use analytical jacobians?
167 system.analytic_jacobians() = param.analytic_jacobians;
168
169 // Verify analytic jacobians against numerical ones?
171
172 // Use the prescribed FE type
173 system.fe_family() = param.fe_family[0];
174 system.fe_order() = param.fe_order[0];
175
176 // More desperate debugging options
178 system.print_solutions = param.print_solutions;
180 system.print_residuals = param.print_residuals;
182 system.print_jacobians = param.print_jacobians;
183
184 // No transient time solver
185 system.time_solver = std::make_unique<SteadySolver>(system);
186
187 // Nonlinear solver options
188 if (param.use_petsc_snes)
189 {
190#ifdef LIBMESH_HAVE_PETSC
191 system.time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(system);
192#else
193 libmesh_error_msg("This example requires libMesh to be compiled with PETSc support.");
194#endif
195 }
196 else
197 {
198 system.time_solver->diff_solver() = std::make_unique<NewtonSolver>(system);
199 auto solver = cast_ptr<NewtonSolver*>(system.time_solver->diff_solver().get());
200
201 solver->quiet = param.solver_quiet;
202 solver->verbose = param.solver_verbose;
203 solver->max_nonlinear_iterations = param.max_nonlinear_iterations;
204 solver->minsteplength = param.min_step_length;
205 solver->relative_step_tolerance = param.relative_step_tolerance;
206 solver->relative_residual_tolerance = param.relative_residual_tolerance;
207 solver->require_residual_reduction = param.require_residual_reduction;
208 solver->linear_tolerance_multiplier = param.linear_tolerance_multiplier;
209 if (system.time_solver->reduce_deltat_on_diffsolver_failure)
210 {
211 solver->continue_after_max_iterations = true;
212 solver->continue_after_backtrack_failure = true;
213 }
215
216 // And the linear solver options
217 solver->max_linear_iterations = param.max_linear_iterations;
218 solver->initial_linear_tolerance = param.initial_linear_tolerance;
219 solver->minimum_linear_tolerance = param.minimum_linear_tolerance;
220 }
221}
222
223// Build the mesh refinement object and set parameters for refining/coarsening etc
224
225#ifdef LIBMESH_ENABLE_AMR
226
227std::unique_ptr<MeshRefinement> build_mesh_refinement(MeshBase & mesh,
228 const FEMParameters & param)
229{
230 auto mesh_refinement = std::make_unique<MeshRefinement>(mesh);
231 mesh_refinement->coarsen_by_parents() = true;
232 mesh_refinement->absolute_global_tolerance() = param.global_tolerance;
233 mesh_refinement->nelem_target() = param.nelem_target;
234 mesh_refinement->refine_fraction() = param.refine_fraction;
235 mesh_refinement->coarsen_fraction() = param.coarsen_fraction;
236 mesh_refinement->coarsen_threshold() = param.coarsen_threshold;
237
238 return mesh_refinement;
239}
240
241#endif // LIBMESH_ENABLE_AMR
242
243// This is where we declare the error estimators to be built and used for
244// mesh refinement. The adjoint residual estimator needs two estimators.
245// One for the forward component of the estimate and one for the adjoint
246// weighting factor. Here we use the Patch Recovery indicator to estimate both the
247// forward and adjoint weights. The H1 seminorm component of the error is used
248// as dictated by the weak form the Laplace equation.
249
250std::unique_ptr<ErrorEstimator> build_error_estimator(const FEMParameters & param,
251 const QoISet & qois)
252{
253 if (param.indicator_type == "kelly")
254 {
255 libMesh::out << "Using Kelly Error Estimator" << std::endl;
256
257 return std::make_unique<KellyErrorEstimator>();
258 }
259 else if (param.indicator_type == "adjoint_residual")
260 {
261 libMesh::out << "Using Adjoint Residual Error Estimator with Patch Recovery Weights" << std::endl;
262
263 auto adjoint_residual_estimator = std::make_unique<AdjointResidualErrorEstimator>();
264
265 adjoint_residual_estimator->qoi_set() = qois;
266 adjoint_residual_estimator->error_plot_suffix = "error.gmv";
267
268 adjoint_residual_estimator->primal_error_estimator() = std::make_unique<PatchRecoveryErrorEstimator>();
269 auto p1 = cast_ptr<PatchRecoveryErrorEstimator *>(adjoint_residual_estimator->primal_error_estimator().get());
270 p1->error_norm.set_type(0, H1_SEMINORM);
271 p1->set_patch_reuse(param.patch_reuse);
272
273 adjoint_residual_estimator->dual_error_estimator() = std::make_unique<PatchRecoveryErrorEstimator>();
274 auto p2 = cast_ptr<PatchRecoveryErrorEstimator *>(adjoint_residual_estimator->dual_error_estimator().get());
275 p2->error_norm.set_type(0, H1_SEMINORM);
276 p2->set_patch_reuse(param.patch_reuse);
277
278 return adjoint_residual_estimator;
279 }
280 else
281 libmesh_error_msg("Unknown indicator_type = " << param.indicator_type);
282}
283
284// The main program.
285int main (int argc, char ** argv)
286{
287 // Initialize libMesh.
288 LibMeshInit init (argc, argv);
289
290 // This example requires a linear solver package.
291 libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
292 "--enable-petsc, --enable-trilinos, or --enable-eigen");
293
294 // This example relies on exceptions to control which Partitioner gets built.
295#ifndef LIBMESH_ENABLE_EXCEPTIONS
296 libmesh_example_requires(false, "--enable-exceptions");
297#endif
298
299 // Skip adaptive examples on a non-adaptive libMesh build
300#ifndef LIBMESH_ENABLE_AMR
301 libmesh_example_requires(false, "--enable-amr");
302#else
303
304 libMesh::out << "Started " << argv[0] << std::endl;
305
306 // Make sure the general input file exists, and parse it
307 {
308 std::ifstream i("general.in");
309 libmesh_error_msg_if(!i, '[' << init.comm().rank() << "] Can't find general.in; exiting early.");
310 }
311
312 // Read in parameters from the input file
313 GetPot infile("general.in");
314
315 // But allow the command line to override it.
316 infile.parse_command_line(argc, argv);
317
318 FEMParameters param(init.comm());
319 param.read(infile);
320
321 // Skip this default-2D example if libMesh was compiled as 1D-only.
322 libmesh_example_requires(2 <= LIBMESH_DIM, "2D support");
323
324 // Create a mesh, with dimension to be overridden later, distributed
325 // across the default MPI communicator.
326 Mesh mesh(init.comm());
327
328 // Give the mesh a non-default partitioner if we can try to do so
329 // safely
330 if (param.mesh_partitioner_type != "Default")
331 {
332#if !defined(LIBMESH_HAVE_RTTI) || !defined(LIBMESH_ENABLE_EXCEPTIONS)
333 libmesh_example_requires(false, "RTTI + exceptions support");
334#else
335 // Factory failures are *verbose* in parallel; let's silence
336 // cerr temporarily.
337 auto oldbuf = libMesh::err.rdbuf();
338 libMesh::err.rdbuf(nullptr);
339 try
340 {
341 // Many partitioners won't work on a distributed Mesh, and
342 // even a currently serialized DistributedMesh won't stay
343 // that way through AMR/C
344 if (!mesh.is_replicated() &&
345 (param.mesh_partitioner_type == "Centroid" ||
346 param.mesh_partitioner_type == "Hilbert" ||
347 param.mesh_partitioner_type == "Morton" ||
348 param.mesh_partitioner_type == "SFCurves" ||
349 param.mesh_partitioner_type == "Metis"))
350 libmesh_example_requires(false, "--disable-parmesh");
351
352 mesh.partitioner() =
354 }
355 catch (...)
356 {
357 libmesh_example_requires(false, param.mesh_partitioner_type + " partitioner support");
358 }
359 libMesh::err.rdbuf(oldbuf);
360#endif // LIBMESH_HAVE_RTTI, LIBMESH_ENABLE_EXCEPTIONS
361 }
362
363 // And an object to refine it
364 std::unique_ptr<MeshRefinement> mesh_refinement =
366
367 // And an EquationSystems to run on it
368 EquationSystems equation_systems (mesh);
369
370 libMesh::out << "Reading in and building the mesh" << std::endl;
371
372 // Read in the mesh
373 mesh.read(param.domainfile.c_str());
374 // Make all the elements of the mesh second order so we can compute
375 // with a higher order basis
377
378 // Create a mesh refinement object to do the initial uniform refinements
379 // on the coarse grid read in from lshaped.xda
380 MeshRefinement initial_uniform_refinements(mesh);
381 initial_uniform_refinements.uniformly_refine(param.coarserefinements);
382
383 libMesh::out << "Building system" << std::endl;
384
385 // Build the FEMSystem
386 LaplaceSystem & system = equation_systems.add_system<LaplaceSystem> ("LaplaceSystem");
387
388 // Set its parameters
389 set_system_parameters(system, param);
390
391 libMesh::out << "Initializing systems" << std::endl;
392
393 equation_systems.init ();
394
395 // Print information about the mesh and system to the screen.
397 equation_systems.print_info();
398 LinearSolver<Number> * linear_solver = system.get_linear_solver();
399
400 {
401 // Adaptively solve the timestep
402 unsigned int a_step = 0;
403 for (; a_step != param.max_adaptivesteps; ++a_step)
404 {
405 // We can't adapt to both a tolerance and a
406 // target mesh size
407 if (param.global_tolerance != 0.)
408 libmesh_assert_equal_to (param.nelem_target, 0);
409 // If we aren't adapting to a tolerance we need a
410 // target mesh size
411 else
412 libmesh_assert_greater (param.nelem_target, 0);
413
414 linear_solver->reuse_preconditioner(false);
415
416 // Solve the forward problem
417 system.solve();
418
419 // Write out the computed primal solution
420 write_output(equation_systems, a_step, "primal", param);
421
422 // Get a pointer to the primal solution vector
423 NumericVector<Number> & primal_solution = *system.solution;
424
425 // Declare a QoISet object, we need this object to set weights for our QoI error contributions
426 QoISet qois;
427
428 // Each index will correspond to a QoI
429 qois.add_indices({0,1});
430
431 // Set weights for each index, these will weight the contribution of each QoI in the final error
432 // estimate to be used for flagging elements for refinement
433 qois.set_weight(0, 0.5);
434 qois.set_weight(1, 0.5);
435
436 // Make sure we get the contributions to the adjoint RHS from the sides
437 system.assemble_qoi_sides = true;
438
439 // We are about to solve the adjoint system, but before we do this we see the same preconditioner
440 // flag to reuse the preconditioner from the forward solver
441 linear_solver->reuse_preconditioner(param.reuse_preconditioner);
442
443 // Solve the adjoint system. This takes the transpose of the stiffness matrix and then
444 // solves the resulting system
445 system.adjoint_solve();
446
447 // Now that we have solved the adjoint, set the adjoint_already_solved boolean to true, so we dont solve unnecessarily in the error estimator
448 system.set_adjoint_already_solved(true);
449
450 // Get a pointer to the solution vector of the adjoint problem for QoI 0
451 NumericVector<Number> & dual_solution_0 = system.get_adjoint_solution(0);
452
453 // Swap the primal and dual solutions so we can write out the adjoint solution
454 primal_solution.swap(dual_solution_0);
455 write_output(equation_systems, a_step, "adjoint_0", param);
456
457 // Swap back
458 primal_solution.swap(dual_solution_0);
459
460 // Get a pointer to the solution vector of the adjoint problem for QoI 0
461 NumericVector<Number> & dual_solution_1 = system.get_adjoint_solution(1);
462
463 // Swap again
464 primal_solution.swap(dual_solution_1);
465 write_output(equation_systems, a_step, "adjoint_1", param);
466
467 // Swap back again
468 primal_solution.swap(dual_solution_1);
469
470 libMesh::out << "Adaptive step "
471 << a_step
472 << ", we have "
474 << " active elements and "
475 << equation_systems.n_active_dofs()
476 << " active dofs."
477 << std::endl;
478
479 // Postprocess, compute the approximate QoIs and write them out to the console
480 libMesh::out << "Postprocessing: " << std::endl;
481 system.postprocess_sides = true;
482 system.postprocess();
483 Number QoI_0_computed = system.get_QoI_value("computed", 0);
484 Number QoI_0_exact = system.get_QoI_value("exact", 0);
485 Number QoI_1_computed = system.get_QoI_value("computed", 1);
486 Number QoI_1_exact = system.get_QoI_value("exact", 1);
487
488 libMesh::out << "The relative error in QoI 0 is "
489 << std::setprecision(17)
490 << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
491 << std::endl;
492
493 libMesh::out << "The relative error in QoI 1 is "
494 << std::setprecision(17)
495 << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
496 << std::endl
497 << std::endl;
498
499 // Now we construct the data structures for the mesh refinement process
500 ErrorVector error;
501
502 // Build an error estimator object
503 std::unique_ptr<ErrorEstimator> error_estimator =
504 build_error_estimator(param, qois);
505
506 // Estimate the error in each element using the Adjoint Residual or Kelly error estimator
507 error_estimator->estimate_error(system, error);
508
509 // We have to refine either based on reaching an error tolerance or
510 // a number of elements target, which should be verified above
511 // Otherwise we flag elements by error tolerance or nelem target
512
513 // Uniform refinement
514 if (param.refine_uniformly)
515 {
516 mesh_refinement->uniformly_refine(1);
517 }
518 // Adaptively refine based on reaching an error tolerance
519 else if (param.global_tolerance >= 0. && param.nelem_target == 0.)
520 {
521 mesh_refinement->flag_elements_by_error_tolerance (error);
522
523 mesh_refinement->refine_and_coarsen_elements();
524 }
525 // Adaptively refine based on reaching a target number of elements
526 else
527 {
528 if (mesh.n_active_elem() >= param.nelem_target)
529 {
530 libMesh::out << "We reached the target number of elements." << std::endl << std::endl;
531 break;
532 }
533
534 mesh_refinement->flag_elements_by_nelem_target (error);
535
536 mesh_refinement->refine_and_coarsen_elements();
537 }
538
539 // Dont forget to reinit the system after each adaptive refinement !
540 equation_systems.reinit();
541
542 libMesh::out << "Refined mesh to "
544 << " active elements and "
545 << equation_systems.n_active_dofs()
546 << " active dofs."
547 << std::endl;
548 }
549
550 // Do one last solve if necessary
551 if (a_step == param.max_adaptivesteps)
552 {
553 linear_solver->reuse_preconditioner(false);
554 system.solve();
555
556 write_output(equation_systems, a_step, "primal", param);
557
558 NumericVector<Number> & primal_solution = *system.solution;
559
560 QoISet qois;
561 std::vector<unsigned int> qoi_indices;
562
563 qoi_indices.push_back(0);
564 qoi_indices.push_back(1);
565 qois.add_indices(qoi_indices);
566
567 qois.set_weight(0, 0.5);
568 qois.set_weight(1, 0.5);
569
570 system.assemble_qoi_sides = true;
571 linear_solver->reuse_preconditioner(param.reuse_preconditioner);
572 system.adjoint_solve();
573
574 // Now that we have solved the adjoint, set the adjoint_already_solved boolean to true, so we dont solve unnecessarily in the error estimator
575 system.set_adjoint_already_solved(true);
576
577 NumericVector<Number> & dual_solution_0 = system.get_adjoint_solution(0);
578
579 primal_solution.swap(dual_solution_0);
580 write_output(equation_systems, a_step, "adjoint_0", param);
581
582 primal_solution.swap(dual_solution_0);
583
584 NumericVector<Number> & dual_solution_1 = system.get_adjoint_solution(1);
585
586 primal_solution.swap(dual_solution_1);
587 write_output(equation_systems, a_step, "adjoint_1", param);
588
589 primal_solution.swap(dual_solution_1);
590
591 libMesh::out << "Adaptive step "
592 << a_step
593 << ", we have "
595 << " active elements and "
596 << equation_systems.n_active_dofs()
597 << " active dofs."
598 << std::endl;
599
600 libMesh::out << "Postprocessing: " << std::endl;
601 system.postprocess_sides = true;
602 system.postprocess();
603
604 Number QoI_0_computed = system.get_QoI_value("computed", 0);
605 Number QoI_0_exact = system.get_QoI_value("exact", 0);
606 Number QoI_1_computed = system.get_QoI_value("computed", 1);
607 Number QoI_1_exact = system.get_QoI_value("exact", 1);
608
609 libMesh::out << "The relative error in QoI 0 is "
610 << std::setprecision(17)
611 << std::abs(QoI_0_computed - QoI_0_exact) / std::abs(QoI_0_exact)
612 << std::endl;
613
614 libMesh::out << "The relative error in QoI 1 is "
615 << std::setprecision(17)
616 << std::abs(QoI_1_computed - QoI_1_exact) / std::abs(QoI_1_exact)
617 << std::endl
618 << std::endl;
619
620 // Hard coded asserts to ensure that the actual numbers we are getting are what they should be
621 if (param.max_adaptivesteps > 5 && param.coarserefinements > 2)
622 {
623 libmesh_assert_less(std::abs(QoI_0_computed - QoI_0_exact)/std::abs(QoI_0_exact), 4.e-5);
624 libmesh_assert_less(std::abs(QoI_1_computed - QoI_1_exact)/std::abs(QoI_1_exact), 1.e-4);
625 }
626 else
627 {
628 // This seems to be loose enough for the case of 2 coarse
629 // refinements, 4 adaptive steps
630 libmesh_assert_less(std::abs(QoI_0_computed - QoI_0_exact)/std::abs(QoI_0_exact), 4.e-4);
631 libmesh_assert_less(std::abs(QoI_1_computed - QoI_1_exact)/std::abs(QoI_1_exact), 2.e-3);
632 }
633 }
634 }
635
636 libMesh::err << '[' << mesh.processor_id()
637 << "] Completing output."
638 << std::endl;
639
640#endif // #ifndef LIBMESH_ENABLE_AMR
641
642 // All done.
643 return 0;
644}
void write_output(EquationSystems &es, unsigned int a_step, std::string solution_type, FEMParameters &param)
void set_system_parameters(LaplaceSystem &system, FEMParameters &param)
std::unique_ptr< MeshRefinement > build_mesh_refinement(MeshBase &mesh, const FEMParameters &param)
std::unique_ptr< ErrorEstimator > build_error_estimator(const FEMParameters &param, const QoISet &qois)
double minimum_linear_tolerance
double initial_linear_tolerance
unsigned int max_adaptivesteps
double linear_tolerance_multiplier
libMesh::Real refine_fraction
unsigned int coarserefinements
libMesh::Real verify_analytic_jacobians
unsigned int max_nonlinear_iterations
std::string domainfile
libMesh::Real global_tolerance
std::string mesh_partitioner_type
std::string indicator_type
libMesh::Real min_step_length
std::vector< std::string > fe_family
libMesh::Real relative_residual_tolerance
bool print_residual_norms
bool print_jacobian_norms
void read(GetPot &input, const std::vector< std::string > *other_variable_names=nullptr)
libMesh::Real relative_step_tolerance
unsigned int max_linear_iterations
bool require_residual_reduction
libMesh::Real coarsen_fraction
unsigned int nelem_target
std::vector< unsigned int > fe_order
libMesh::Real coarsen_threshold
bool print_solution_norms
bool reuse_preconditioner
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides.
Definition L-shaped.C:168
std::string & fe_family()
Definition L-shaped.h:24
Number & get_QoI_value(std::string type, unsigned int QoI_index)
Definition L-shaped.h:32
unsigned int & fe_order()
Definition L-shaped.h:25
bool & analytic_jacobians()
Definition L-shaped.h:26
streambufT * rdbuf() const
Get the associated stream buffer.
bool assemble_qoi_sides
If assemble_qoi_sides is true (it is false by default), the assembly loop for a quantity of interest ...
Definition diff_qoi.h:85
bool print_jacobians
Set print_jacobians to true to print J whenever it is assembled.
bool postprocess_sides
If postprocess_sides is true (it is false by default), the postprocessing loop will loop over all sid...
bool print_residuals
Set print_residuals to true to print F whenever it is assembled.
virtual void set_constrain_in_solver(bool enable)
set_constrain_in_solver to false to apply constraints only via residual terms in the systems to be so...
bool print_solution_norms
Set print_residual_norms to true to print |U| whenever it is used in an assembly() call.
virtual LinearSolver< Number > * get_linear_solver() const override
bool print_solutions
Set print_solutions to true to print U whenever it is used in an assembly() call.
bool print_residual_norms
Set print_residual_norms to true to print |F| whenever it is assembled.
virtual std::pair< unsigned int, Real > adjoint_solve(const QoISet &qoi_indices=QoISet()) override
This function sets the _is_adjoint boolean member of TimeSolver to true and then calls the adjoint_so...
bool print_jacobian_norms
Set print_jacobian_norms to true to print |J| whenever it is assembled.
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
This is the EquationSystems class.
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
std::size_t n_active_dofs() const
const MeshBase & get_mesh() const
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition exodusII_io.h:53
void write_timestep(const std::string &fname, const EquationSystems &es, const int timestep, const Real time, const std::set< std::string > *system_names=nullptr)
Writes out the solution at a specific timestep.
virtual void solve() override
Invokes the solver associated with the system.
Real verify_analytic_jacobians
If verify_analytic_jacobian is equal to zero (as it is by default), no numeric jacobians will be calc...
Definition fem_system.h:215
static std::unique_ptr< Base > build(const std::string &name)
Builds an object of type Base identified by name.
Definition factory.h:129
This class implements writing meshes in the GMV format.
Definition gmv_io.h:48
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition libmesh.h:92
This base class can be inherited from to provide interfaces to linear solvers from different packages...
virtual void reuse_preconditioner(bool)
Set the same_preconditioner flag, which indicates if we reuse the same preconditioner for subsequent ...
This is the MeshBase class.
Definition mesh_base.h:81
virtual std::unique_ptr< Partitioner > & partitioner()
A partitioner to use at each partitioning.
Definition mesh_base.h:165
virtual bool is_replicated() const
Definition mesh_base.h:379
void all_second_order(const bool full_ordered=true)
Calls the range-based version of this function with a range consisting of all elements in the mesh.
Definition mesh_base.C:1803
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false, bool skip_detect_interior_parents=false)=0
Interfaces for reading/writing a mesh to/from a file.
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition mesh_base.C:1755
virtual dof_id_type n_active_elem() const =0
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
Definition mesh_output.C:31
Implements (adaptive) mesh refinement algorithms for a MeshBase.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition mesh.h:51
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
processor_id_type processor_id() const
Data structure for specifying which Quantities of Interest should be calculated in an adjoint or a pa...
Definition qoi_set.h:46
void add_indices(const std::vector< unsigned int > &indices)
Add this indices to the set to be calculated.
Definition qoi_set.C:46
void set_weight(std::size_t, Real)
Set the weight for this index.
Definition qoi_set.h:232
void set_adjoint_already_solved(bool setting)
Setter for the adjoint_already_solved boolean.
Definition system.h:417
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
Definition system.C:1232
MeshBase & mesh
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
void libmesh_ignore(const Args &...)
SolverPackage default_solver_package()
Definition libmesh.C:1064
OStreamProxy out
int main()