From 87b0064947cabd9c384a78d377236bdbba7714a9 Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 7 Jan 2025 22:46:20 -0500 Subject: [PATCH 01/23] temp init commit --- .gitignore | 1 + applications/multigrid_test/CMakeLists.txt | 157 +++++ applications/multigrid_test/main.cc | 36 + include/core/fields.h | 2 +- include/core/matrixFreePDE.h | 99 --- include/core/matrix_free_operator.h | 274 +++++++ include/core/model_variables.h | 27 +- include/core/temp_test.h | 359 ++++++++++ include/core/typeDefs.h | 50 -- include/core/{varTypeEnums.h => typeEnums.h} | 12 +- include/core/userInputParameters.h | 14 +- include/core/variableAttributeLoader.h | 6 +- include/core/variableAttributes.h | 2 +- include/core/variableContainer.h | 165 ++--- .../initial_conditions/initialConditions.cc | 2 +- src/core/outputResults.cc | 7 +- src/core/postprocessing/postprocessor.cc | 87 --- src/core/solvers/computeLHS.cc | 110 --- src/core/solvers/computeRHS.cc | 136 ---- .../solvers/setNonlinearEqInitialGuess.cc | 220 ------ src/core/solvers/solve.cc | 8 +- src/core/solvers/solveIncrement.cc | 22 +- src/core/userInputParameters.cc | 41 +- src/core/variableContainer.cc | 667 +++++------------- 24 files changed, 1139 insertions(+), 1365 deletions(-) create mode 100644 applications/multigrid_test/CMakeLists.txt create mode 100644 applications/multigrid_test/main.cc create mode 100644 include/core/matrix_free_operator.h create mode 100644 include/core/temp_test.h delete mode 100644 include/core/typeDefs.h rename include/core/{varTypeEnums.h => typeEnums.h} (56%) delete mode 100644 src/core/postprocessing/postprocessor.cc delete mode 100644 src/core/solvers/computeLHS.cc delete mode 100644 src/core/solvers/computeRHS.cc delete mode 100644 src/core/solvers/setNonlinearEqInitialGuess.cc diff --git a/.gitignore b/.gitignore index 33d26c1c..231a8aca 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ main #Output files applications/*/*.vtk *.vtu +*.pvtu *.vts *.frt integratedFields.txt diff --git a/applications/multigrid_test/CMakeLists.txt b/applications/multigrid_test/CMakeLists.txt new file mode 100644 index 00000000..dc0a2d4b --- /dev/null +++ b/applications/multigrid_test/CMakeLists.txt @@ -0,0 +1,157 @@ +## +# CMake script for the PRISMS-PF applications +# Adapted from the ASPECT CMake file +## + +cmake_minimum_required(VERSION 3.3.0) + +project(myapp) + +message(STATUS "") +message(STATUS "=========================================================") +message(STATUS "Configuring PRISMS-PF application") +message(STATUS "=========================================================") +message(STATUS "") + +# Setup the build type (debug, release, debugrelease) +if("${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE "DebugRelease" + CACHE STRING + "Choose the type of build, options are: Debug, Release and DebugRelease." + FORCE) +endif() + +# Convert build type into the debug and release builds, which may or may +# not be built. +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR + "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR + "${CMAKE_BUILD_TYPE}" STREQUAL "DebugRelease" ) + message(STATUS "Setting up PRISMS-PF application for ${CMAKE_BUILD_TYPE} mode.") +else() + message(FATAL_ERROR + "CMAKE_BUILD_TYPE must either be 'Release', 'Debug', or 'DebugRelease', but is set to '${CMAKE_BUILD_TYPE}'.") +endif() + +if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR + "${CMAKE_BUILD_TYPE}" STREQUAL "DebugRelease") + set(PRISMS_PF_BUILD_DEBUG "ON") +else() + set(PRISMS_PF_BUILD_DEBUG "OFF") +endif() + +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR + "${CMAKE_BUILD_TYPE}" STREQUAL "DebugRelease") + set(PRISMS_PF_BUILD_RELEASE "ON") +else() + set(PRISMS_PF_BUILD_RELEASE "OFF") +endif() + +# Find deal.II installation +find_package(deal.II 9.6.0 QUIET + HINTS ${DEAL_II_DIR} $ENV{DEAL_II_DIR} + ) +if(NOT ${deal.II_FOUND}) + message(FATAL_ERROR "\n*** Could not find a recent version of deal.II. ***\n" + "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake " + "or set an environment variable \"DEAL_II_DIR\" that contains a path to a " + "recent version of deal.II." + ) +endif() + +message(STATUS "Found deal.II version ${DEAL_II_PACKAGE_VERSION} at '${deal.II_DIR}'") + +set(DEALII_INSTALL_VALID ON) + +if(NOT DEAL_II_WITH_P4EST) + message(SEND_ERROR + "\n**deal.II was built without support for p4est!\n" + ) + set(DEALII_INSTALL_VALID OFF) +endif() + +if(NOT DEALII_INSTALL_VALID) + message(FATAL_ERROR + "\nPRISMS-PF requires a deal.II installation with certain features enabled!\n" + ) +endif() + +deal_ii_initialize_cached_variables() + +# Make and ninja build options +if(CMAKE_GENERATOR MATCHES "Ninja") + set(_make_command "$ ninja") +else() + set(_make_command " $ make") +endif() + +# Debug and release targets +if(${DEAL_II_BUILD_TYPE} MATCHES "DebugRelease") + add_custom_target(release + COMMAND ${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=Release . + COMMAND ${CMAKE_COMMAND} -E echo "***" + COMMAND ${CMAKE_COMMAND} -E echo "*** Switched to Release mode. Now recompile with: ${_make_command}" + COMMAND ${CMAKE_COMMAND} -E echo "***" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM + COMMENT "switching to RELEASE mode..." + ) + + add_custom_target(debug + COMMAND ${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=Debug . + COMMAND ${CMAKE_COMMAND} -E echo "***" + COMMAND ${CMAKE_COMMAND} -E echo "*** Switched to Debug mode. Now recompile with: ${_make_command}" + COMMAND ${CMAKE_COMMAND} -E echo "***" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM + COMMENT "switching to DEBUG mode..." + ) + + add_custom_target(debugrelease + COMMAND ${CMAKE_COMMAND} -D CMAKE_BUILD_TYPE=DebugRelease . + COMMAND ${CMAKE_COMMAND} -E echo "***" + COMMAND ${CMAKE_COMMAND} -E echo "*** Switched to Debug and Release mode. Now recompile with: ${_make_command}" + COMMAND ${CMAKE_COMMAND} -E echo "***" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM + COMMENT "switching to DEBUG/RELEASE mode..." + ) +endif() + +# Add distclean target to clean build +add_custom_target(distclean + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target clean + COMMAND ${CMAKE_COMMAND} -E remove_directory CMakeFiles + COMMAND ${CMAKE_COMMAND} -E remove + CMakeCache.txt cmake_install.cmake Makefile + build.ninja rules.ninja .ninja_deps .ninja_log + COMMENT "distclean invoked" + ) + +# Set location of files +include_directories(${CMAKE_SOURCE_DIR}/../../include) +include_directories(${CMAKE_SOURCE_DIR}/../../src) +include_directories(${CMAKE_SOURCE_DIR}) + +# Set the location of the main.cc file +set(TARGET_SRC "${CMAKE_SOURCE_DIR}/main.cc") + +# Check if there has been updates to main library +set(dir ${PROJECT_SOURCE_DIR}/../..) +EXECUTE_PROCESS(COMMAND "rm" "CMakeCache.txt" WORKING_DIRECTORY ${dir}) +EXECUTE_PROCESS(COMMAND "cmake" "CMakeLists.txt" WORKING_DIRECTORY ${dir}) +EXECUTE_PROCESS(COMMAND "make" WORKING_DIRECTORY ${dir}) + +# Set targets & link libraries for the build type +if(${PRISMS_PF_BUILD_DEBUG} STREQUAL "ON") + add_executable(main_debug ${TARGET_SRC}) + set_property(TARGET main_debug PROPERTY OUTPUT_NAME main-debug) + deal_ii_setup_target(main_debug DEBUG) + target_link_libraries(main_debug ${CMAKE_SOURCE_DIR}/../../libprisms-pf-debug.a) +endif() + +if(${PRISMS_PF_BUILD_RELEASE} STREQUAL "ON") + add_executable(main_release ${TARGET_SRC}) + set_property(TARGET main_release PROPERTY OUTPUT_NAME main) + deal_ii_setup_target(main_release RELEASE) + target_link_libraries(main_release ${CMAKE_SOURCE_DIR}/../../libprisms-pf-release.a) +endif() \ No newline at end of file diff --git a/applications/multigrid_test/main.cc b/applications/multigrid_test/main.cc new file mode 100644 index 00000000..bc73f53a --- /dev/null +++ b/applications/multigrid_test/main.cc @@ -0,0 +1,36 @@ +#include + +int +main(int argc, char *argv[]) +{ + try + { + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + LaplaceProblem laplace_problem; + laplace_problem.run(); + } + catch (std::exception &exc) + { + std::cerr << std::endl + << std::endl + << "----------------------------------------------------" << std::endl; + std::cerr << "Exception on processing: " << std::endl + << exc.what() << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" << std::endl; + return 1; + } + catch (...) + { + std::cerr << std::endl + << std::endl + << "----------------------------------------------------" << std::endl; + std::cerr << "Unknown exception!" << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" << std::endl; + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/include/core/fields.h b/include/core/fields.h index 9a2cf8a0..b2335b0a 100644 --- a/include/core/fields.h +++ b/include/core/fields.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include #include diff --git a/include/core/matrixFreePDE.h b/include/core/matrixFreePDE.h index bdc070cb..ff2b744b 100644 --- a/include/core/matrixFreePDE.h +++ b/include/core/matrixFreePDE.h @@ -97,18 +97,6 @@ class MatrixFreePDE : public Subscriptor void solve(); - /** - * \brief This method essentially converts the MatrixFreePDE object into a matrix object - * which can be used with matrix free iterative solvers. Provides the A*x functionality - * for solving the system of equations Ax=b. - * - * \param dst The destination vector. - * \param src The source vector. - */ - void - vmult(dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src) const; - /** * \brief Vector of all the physical fields in the problem. Fields are identified by * dimentionality (SCALAR/VECTOR), the kind of PDE (ELLIPTIC/PARABOLIC) used to compute @@ -304,93 +292,6 @@ class MatrixFreePDE : public Subscriptor */ dealii::AlignedVector> element_volume; - /*Method to compute the right hand side (RHS) residual vectors*/ - void - computeExplicitRHS(); - void - computeNonexplicitRHS(); - - // virtual methods to be implemented in the derived class - /*Method to calculate LHS(implicit solve)*/ - void - getLHS(const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const; - - bool generatingInitialGuess; - void - getLaplaceLHS(const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const; - - void - setNonlinearEqInitialGuess(); - void - computeLaplaceRHS(unsigned int fieldIndex); - void - getLaplaceRHS(const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const; - - /*Method to calculate RHS (implicit/explicit). This is an abstract method, so - * every model which inherits MatrixFreePDE has to implement this - * method.*/ - void - getExplicitRHS( - const MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range) const; - - void - getNonexplicitRHS( - const MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range) const; - - virtual void - explicitEquationRHS( - [[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] const Point> q_point_loc, - [[maybe_unused]] const VectorizedArray element_volume) const = 0; - - virtual void - nonExplicitEquationRHS( - [[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] const Point> q_point_loc, - [[maybe_unused]] const VectorizedArray element_volume) const = 0; - - virtual void - equationLHS([[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] const Point> q_point_loc, - [[maybe_unused]] const VectorizedArray element_volume) const = 0; - - virtual void - postProcessedFields( - [[maybe_unused]] const variableContainer> - &variable_list, - [[maybe_unused]] variableContainer> - &pp_variable_list, - [[maybe_unused]] const Point> q_point_loc, - [[maybe_unused]] const VectorizedArray element_volume) const {}; - void - computePostProcessedFields( - std::vector *> &postProcessedSet); - - void - getPostProcessedFields( - const MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range); - // methods to apply dirichlet BC's /*Map of degrees of freedom to the corresponding Dirichlet boundary * conditions, if any.*/ diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h new file mode 100644 index 00000000..cd2c8a6e --- /dev/null +++ b/include/core/matrix_free_operator.h @@ -0,0 +1,274 @@ +#ifndef MATRIX_FREE_OPERATOR_H_ +#define MATRIX_FREE_OPERATOR_H_ + +#include +#include +#include + +#include + +using namespace dealii; + +template +class Coefficient : public Function +{ +public: + virtual double + value(const Point &p, const unsigned int component = 0) const override; + + template + number + value(const Point &p, const unsigned int component = 0) const; +}; + +template +template +number +Coefficient::value(const Point &p, + const unsigned int /*component*/) const +{ + return 1.0 / (0.05 + 2.0 * p.square()); +} + +template +double +Coefficient::value(const Point &p, const unsigned int component) const +{ + return value(p, component); +} + +/** + * \brief This is the abstract base class for the matrix free implementation of some PDE. + * + * \tparam dim The number of dimensions in the problem. + * \tparam degree The polynomial degree of the shape functions. + * \tparam number Datatype to use for `LinearAlgebra::distributed::Vector`. Either + * double or float. + */ +template +class matrixFreeOperator + : public MatrixFreeOperators::Base> +{ +public: + using scalarValue = VectorizedArray; + using scalarGrad = Tensor<1, dim, VectorizedArray>; + using scalarHess = Tensor<2, dim, VectorizedArray>; + using vectorValue = Tensor<1, dim, VectorizedArray>; + using vectorGrad = Tensor<2, dim, VectorizedArray>; + using vectorHess = Tensor<3, dim, VectorizedArray>; + + /** + * \brief Constructor. + */ + matrixFreeOperator(); + + /** + * \brief Release all memory and return to state like having called the default + * constructor. + */ + void + clear() override; + + void + evaluate_coefficient(const Coefficient &coefficient_function); + + /** + * \brief Compute the diagonal of this operator. + */ + void + compute_diagonal() override; + +protected: + /** + * \brief User-implemented PDE. TODO + */ + void + nonexplicit_RHS(variableContainer &variable_list, + const Point> &q_point_loc) const; + +private: + /** + * \brief Apply operator to src and add result in dst. + */ + void + apply_add(LinearAlgebra::distributed::Vector &dst, + const LinearAlgebra::distributed::Vector &src) const override; + + /** + * \brief Local application of the operator. + */ + void + local_apply(const MatrixFree &data, + LinearAlgebra::distributed::Vector &dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const; + + /** + * \brief Local computation of the diagonal of the operator. + */ + void + local_compute_diagonal(const MatrixFree &data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &dummy, + const std::pair &cell_range) const; + + Table<2, VectorizedArray> coefficient; +}; + +template +matrixFreeOperator::matrixFreeOperator() + : MatrixFreeOperators::Base>() +{} + +template +void +matrixFreeOperator::clear() +{ + coefficient.reinit(0, 0); + MatrixFreeOperators::Base>::clear(); +} + +template +void +matrixFreeOperator::evaluate_coefficient( + const Coefficient &coefficient_function) +{ + const unsigned int n_cells = this->data->n_cell_batches(); + FEEvaluation phi(*this->data); + + coefficient.reinit(n_cells, phi.n_q_points); + for (unsigned int cell = 0; cell < n_cells; ++cell) + { + phi.reinit(cell); + for (const unsigned int q : phi.quadrature_point_indices()) + { + coefficient(cell, q) = coefficient_function.value(phi.quadrature_point(q)); + } + } +} + +template +void +matrixFreeOperator::local_apply( + const MatrixFree &data, + LinearAlgebra::distributed::Vector &dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const +{ + // Constructor for FEEvaluation objects + variableContainer variable_list(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + // Initialize, read DOFs, and set evaulation flags for each variable + variable_list.reinit_and_eval(src, cell); + + // Number of quadrature points + unsigned int n_q_points = variable_list.get_num_q_points(); + + for (unsigned int q = 0; q < n_q_points; ++q) + { + // Set the quadrature point + variable_list.q_point = q; + + // Grab the quadrature point location + Point> q_point_loc = + variable_list.get_q_point_location(); + + // Calculate the residuals + nonexplicit_RHS(variable_list, q_point_loc); + } + + // Integrate and add to global vector dst + variable_list.integrate_and_distribute(dst); + } +} + +template +void +matrixFreeOperator::nonexplicit_RHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{ + scalarGrad phi = variable_list.get_scalar_gradient(0); + + scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); + + variable_list.set_scalar_gradient_term(0, phi * coefficient); +} + +template +void +matrixFreeOperator::apply_add( + LinearAlgebra::distributed::Vector &dst, + const LinearAlgebra::distributed::Vector &src) const +{ + this->data->cell_loop(&matrixFreeOperator::local_apply, this, dst, src); +} + +template +void +matrixFreeOperator::compute_diagonal() +{ + this->inverse_diagonal_entries.reset( + new DiagonalMatrix>()); + LinearAlgebra::distributed::Vector &inverse_diagonal = + this->inverse_diagonal_entries->get_vector(); + this->data->initialize_dof_vector(inverse_diagonal); + unsigned int dummy = 0; + this->data->cell_loop(&matrixFreeOperator::local_compute_diagonal, + this, + inverse_diagonal, + dummy); + + this->set_constrained_entries_to_one(inverse_diagonal); + + for (unsigned int i = 0; i < inverse_diagonal.locally_owned_size(); ++i) + { + Assert(inverse_diagonal.local_element(i) > 0.0, + ExcMessage( + "No diagonal entry in a positive definite operator should be zero")); + inverse_diagonal.local_element(i) = 1.0 / inverse_diagonal.local_element(i); + } +} + +template +void +matrixFreeOperator::local_compute_diagonal( + const MatrixFree &data, + LinearAlgebra::distributed::Vector &dst, + [[maybe_unused]] const unsigned int &dummy, + const std::pair &cell_range) const +{ + FEEvaluation phi(data); + + AlignedVector> diagonal(phi.dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + { + phi.submit_dof_value(VectorizedArray(), j); + } + phi.submit_dof_value(make_vectorized_array(1.), i); + + phi.evaluate(EvaluationFlags::gradients); + for (const unsigned int q : phi.quadrature_point_indices()) + { + phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), q); + } + phi.integrate(EvaluationFlags::gradients); + diagonal[i] = phi.get_dof_value(i); + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + phi.submit_dof_value(diagonal[i], i); + } + phi.distribute_local_to_global(dst); + } +} + +#endif \ No newline at end of file diff --git a/include/core/model_variables.h b/include/core/model_variables.h index 24aed755..983ca225 100644 --- a/include/core/model_variables.h +++ b/include/core/model_variables.h @@ -1,22 +1,33 @@ -// Model Variables Class - #ifndef INCLUDE_MODELVARIABLE_H_ #define INCLUDE_MODELVARIABLE_H_ -#include -#include #include -struct variable_info +#include + +struct variableInfo { + /** + * \brief Global field index. + */ unsigned int global_var_index = 0; - bool is_scalar = true; - bool var_needed = false; + /** + * \brief Variable field type (SCALAR/VECTOR). + */ + fieldType var_type = UNDEFINED_FIELD; + + /** + * \brief Evaluation flags. + */ dealii::EvaluationFlags::EvaluationFlags evaluation_flags = dealii::EvaluationFlags::nothing; + + /** + * \brief Residual evaluation flags. + */ dealii::EvaluationFlags::EvaluationFlags residual_flags = dealii::EvaluationFlags::nothing; }; -#endif /* INCLUDE_MODELVARIABLE_H_ */ +#endif diff --git a/include/core/temp_test.h b/include/core/temp_test.h new file mode 100644 index 00000000..04396626 --- /dev/null +++ b/include/core/temp_test.h @@ -0,0 +1,359 @@ +#ifndef TEMP_TEST_H_ +#define TEMP_TEST_H_ + +// Just some random code to help test the implementation of step-37 into PRISMS-PF as I +// refactor major portions of code. The necessity and size of this should decrease in time +// as I figure out stuff. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const unsigned int degree_finite_element = 2; +const unsigned int dimension = 3; + +template +class LaplaceProblem +{ +public: + LaplaceProblem(); + void + run(); + +private: + void + setup_system(); + void + assemble_rhs(); + void + solve(); + void + output_results(unsigned int cycle) const; + + parallel::distributed::Triangulation triangulation; + + const FE_Q fe; + DoFHandler dof_handler; + + MappingQ1 mapping; + + AffineConstraints constraints; + using SystemMatrixType = matrixFreeOperator; + SystemMatrixType system_matrix; + + MGConstrainedDoFs mg_constrained_dofs; + using LevelMatrixType = matrixFreeOperator; + MGLevelObject mg_matrices; + + LinearAlgebra::distributed::Vector solution; + LinearAlgebra::distributed::Vector system_rhs; + + double setup_time {}; + ConditionalOStream pcout; + ConditionalOStream time_details; +}; + +template +LaplaceProblem::LaplaceProblem() + : triangulation( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy) + , fe(degree_finite_element) + , dof_handler(triangulation) + , pcout(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) + , time_details(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) +{} + +template +void +LaplaceProblem::setup_system() +{ + Timer time; + setup_time = 0; + { + system_matrix.clear(); + mg_matrices.clear_elements(); + + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + pcout << "Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; + + constraints.clear(); + constraints.reinit(dof_handler.locally_owned_dofs(), + DoFTools::extract_locally_relevant_dofs(dof_handler)); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + VectorTools::interpolate_boundary_values(mapping, + dof_handler, + 0, + Functions::ZeroFunction(), + constraints); + constraints.close(); + } + setup_time += time.wall_time(); + time_details << "Distribute DoFs & B.C. (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << 's' << std::endl; + time.restart(); + { + { + typename MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + std::shared_ptr> system_mf_storage( + new MatrixFree()); + system_mf_storage->reinit(mapping, + dof_handler, + constraints, + QGauss<1>(fe.degree + 1), + additional_data); + system_matrix.initialize(system_mf_storage); + } + + system_matrix.evaluate_coefficient(Coefficient()); + + system_matrix.initialize_dof_vector(solution); + system_matrix.initialize_dof_vector(system_rhs); + } + setup_time += time.wall_time(); + time_details << "Setup matrix-free system (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << 's' << std::endl; + time.restart(); + + { + const unsigned int nlevels = triangulation.n_global_levels(); + mg_matrices.resize(0, nlevels - 1); + + const std::set dirichlet_boundary_ids = {0}; + mg_constrained_dofs.initialize(dof_handler); + mg_constrained_dofs.make_zero_boundary_constraints(dof_handler, + dirichlet_boundary_ids); + + for (unsigned int level = 0; level < nlevels; ++level) + { + AffineConstraints level_constraints( + dof_handler.locally_owned_mg_dofs(level), + DoFTools::extract_locally_relevant_level_dofs(dof_handler, level)); + for (const types::global_dof_index dof_index : + mg_constrained_dofs.get_boundary_indices(level)) + { + level_constraints.constrain_dof_to_zero(dof_index); + } + level_constraints.close(); + + typename MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + additional_data.mg_level = level; + std::shared_ptr> mg_mf_storage_level = + std::make_shared>(); + mg_mf_storage_level->reinit(mapping, + dof_handler, + level_constraints, + QGauss<1>(fe.degree + 1), + additional_data); + + mg_matrices[level].initialize(mg_mf_storage_level, mg_constrained_dofs, level); + mg_matrices[level].evaluate_coefficient(Coefficient()); + } + } + setup_time += time.wall_time(); + time_details << "Setup matrix-free levels (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << 's' << std::endl; +} + +template +void +LaplaceProblem::assemble_rhs() +{ + Timer time; + + system_rhs = 0; + FEEvaluation phi(*system_matrix.get_matrix_free()); + for (unsigned int cell = 0; cell < system_matrix.get_matrix_free()->n_cell_batches(); + ++cell) + { + phi.reinit(cell); + for (const unsigned int q : phi.quadrature_point_indices()) + { + phi.submit_value(make_vectorized_array(1.0), q); + } + phi.integrate(EvaluationFlags::values); + phi.distribute_local_to_global(system_rhs); + } + system_rhs.compress(VectorOperation::add); + + setup_time += time.wall_time(); + time_details << "Assemble right hand side (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << 's' << std::endl; +} + +template +void +LaplaceProblem::solve() +{ + Timer time; + MGTransferMatrixFree mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof_handler); + setup_time += time.wall_time(); + time_details << "MG build transfer time (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << "s\n"; + time.restart(); + + using SmootherType = + PreconditionChebyshev>; + mg::SmootherRelaxation> + mg_smoother; + MGLevelObject smoother_data; + smoother_data.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); ++level) + { + if (level > 0) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 10; + } + else + { + smoother_data[0].smoothing_range = 1e-3; + smoother_data[0].degree = numbers::invalid_unsigned_int; + smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m(); + } + mg_matrices[level].compute_diagonal(); + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + MGCoarseGridApplySmoother> mg_coarse; + mg_coarse.initialize(mg_smoother); + + mg::Matrix> mg_matrix(mg_matrices); + + MGLevelObject> + mg_interface_matrices; + mg_interface_matrices.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); ++level) + { + mg_interface_matrices[level].initialize(mg_matrices[level]); + } + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg(mg_matrix, + mg_coarse, + mg_transfer, + mg_smoother, + mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + + PreconditionMG, + MGTransferMatrixFree> + preconditioner(dof_handler, mg, mg_transfer); + + SolverControl solver_control(100, 1e-12 * system_rhs.l2_norm()); + SolverCG> cg(solver_control); + setup_time += time.wall_time(); + time_details << "MG build smoother time (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << "s\n"; + pcout << "Total setup time (wall) " << setup_time << "s\n"; + + time.reset(); + time.start(); + constraints.set_zero(solution); + cg.solve(system_matrix, solution, system_rhs, preconditioner); + + constraints.distribute(solution); + + pcout << "Time solve (" << solver_control.last_step() << " iterations)" + << (solver_control.last_step() < 10 ? " " : " ") << "(CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << "s\n"; +} + +template +void +LaplaceProblem::output_results(unsigned int cycle) const +{ + Timer time; + if (triangulation.n_global_active_cells() > 1000000) + { + return; + } + + DataOut data_out; + + solution.update_ghost_values(); + data_out.attach_dof_handler(dof_handler); + data_out.add_data_vector(solution, "solution"); + data_out.build_patches(mapping); + + DataOutBase::VtkFlags flags; + flags.compression_level = DataOutBase::CompressionLevel::best_speed; + data_out.set_flags(flags); + data_out.write_vtu_with_pvtu_record("./", "solution", cycle, MPI_COMM_WORLD, 3); + + time_details << "Time write output (CPU/wall) " << time.cpu_time() << "s/" + << time.wall_time() << "s\n"; +} + +template +void +LaplaceProblem::run() +{ + { + const unsigned int n_vect_doubles = VectorizedArray::size(); + const unsigned int n_vect_bits = 8 * sizeof(double) * n_vect_doubles; + + pcout << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits + << " bits (" << Utilities::System::get_current_vectorization_level() << ')' + << std::endl; + } + + for (unsigned int cycle = 0; cycle < 9 - dim; ++cycle) + { + pcout << "Cycle " << cycle << std::endl; + + if (cycle == 0) + { + GridGenerator::hyper_cube(triangulation, 0., 1.); + triangulation.refine_global(3 - dim); + } + triangulation.refine_global(1); + setup_system(); + assemble_rhs(); + solve(); + output_results(cycle); + pcout << std::endl; + }; +} + +#endif \ No newline at end of file diff --git a/include/core/typeDefs.h b/include/core/typeDefs.h deleted file mode 100644 index 73211048..00000000 --- a/include/core/typeDefs.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * typeDefs.h - * - * Created on: Feb 24, 2017 - * Author: stephendewitt - */ - -// #ifndef INCLUDE_TYPEDEFS_H_ -// #define INCLUDE_TYPEDEFS_H_ - -// define FE system types -#ifndef typeScalar -using typeScalar = dealii::FEEvaluation; -#endif -#ifndef typeVector -using typeVector = dealii::FEEvaluation; -#endif -// define data value types -#ifndef scalarvalueType -using scalarvalueType = dealii::VectorizedArray; -#endif -#ifndef vectorvalueType -using vectorvalueType = dealii::Tensor<1, dim, dealii::VectorizedArray>; -#endif -#if problemDIM == 1 -# ifndef scalargradType -using scalargradType = dealii::VectorizedArray; -# endif -# ifndef vectorgradType -using vectorgradType = dealii::VectorizedArray; -# endif -# ifndef vectorhessType -using vectorhessType = dealii::VectorizedArray; -# endif -#else -# ifndef scalargradType -using scalargradType = dealii::Tensor<1, dim, dealii::VectorizedArray>; -# endif -# ifndef scalarhessType -using scalarhessType = dealii::Tensor<2, dim, dealii::VectorizedArray>; -# endif -# ifndef vectorgradType -using vectorgradType = dealii::Tensor<2, dim, dealii::VectorizedArray>; -# endif -# ifndef vectorhessType -using vectorhessType = dealii::Tensor<3, dim, dealii::VectorizedArray>; -# endif -#endif - -// #endif /* INCLUDE_TYPEDEFS_H_ */ diff --git a/include/core/varTypeEnums.h b/include/core/typeEnums.h similarity index 56% rename from include/core/varTypeEnums.h rename to include/core/typeEnums.h index 6bf238cc..8452b832 100644 --- a/include/core/varTypeEnums.h +++ b/include/core/typeEnums.h @@ -1,5 +1,5 @@ -#ifndef INCLUDE_VARTYPEENUMS_H_ -#define INCLUDE_VARTYPEENUMS_H_ +#ifndef INCLUDE_TYPEENUMS_H_ +#define INCLUDE_TYPEENUMS_H_ enum fieldType { @@ -17,4 +17,12 @@ enum PDEType AUXILIARY }; +enum solveType +{ + EXPLICIT_RHS, + NONEXPLICIT_RHS, + NONEXPLICIT_LHS, + POSTPROCESS +}; + #endif diff --git a/include/core/userInputParameters.h b/include/core/userInputParameters.h index 5a988658..0d76b339 100644 --- a/include/core/userInputParameters.h +++ b/include/core/userInputParameters.h @@ -264,13 +264,13 @@ class userInputParameters const AttributesList &pp_attributes; // Variables needed to calculate the RHS - unsigned int num_var_explicit_RHS, num_var_nonexplicit_RHS; - std::vector varInfoListExplicitRHS, varInfoListNonexplicitRHS; + unsigned int num_var_explicit_RHS, num_var_nonexplicit_RHS; + std::vector varInfoListExplicitRHS, varInfoListNonexplicitRHS; // Variables needed to calculate the LHS - unsigned int num_var_LHS; - std::vector varInfoListLHS; - std::vector varChangeInfoListLHS; + unsigned int num_var_LHS; + std::vector varInfoListLHS; + std::vector varChangeInfoListLHS; // Variables for loading in initial conditions std::vector load_ICs; @@ -288,8 +288,8 @@ class userInputParameters std::vector integrated_field_indices; // Variable and residual info - std::vector pp_varInfoList; - std::vector pp_baseVarInfoList; + std::vector pp_varInfoList; + std::vector pp_baseVarInfoList; // List of boundary conditions std::vector> BC_list; diff --git a/include/core/variableAttributeLoader.h b/include/core/variableAttributeLoader.h index 926ca033..8dc291d3 100644 --- a/include/core/variableAttributeLoader.h +++ b/include/core/variableAttributeLoader.h @@ -1,19 +1,19 @@ #ifndef VARIABLEATTRIBUTELOADER_H #define VARIABLEATTRIBUTELOADER_H -#include +#include #include #include #include -using EvalFlags = dealii::EvaluationFlags::EvaluationFlags; - /** * \brief Class to manage the variable attributes that the user specifies. */ class variableAttributeLoader { public: + using EvalFlags = dealii::EvaluationFlags::EvaluationFlags; + /** * \brief Constructor. */ diff --git a/include/core/variableAttributes.h b/include/core/variableAttributes.h index 5ebd93c3..8eab0889 100644 --- a/include/core/variableAttributes.h +++ b/include/core/variableAttributes.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include #include diff --git a/include/core/variableContainer.h b/include/core/variableContainer.h index f7f311d6..ad1efe87 100644 --- a/include/core/variableContainer.h +++ b/include/core/variableContainer.h @@ -1,5 +1,3 @@ -// This class permits the access of a subset of indexed fields and gives an -// error if any non-allowed fields are requested #ifndef VARIBLECONTAINER_H #define VARIBLECONTAINER_H @@ -8,140 +6,117 @@ #include #include -#include - #include - -template +#include + +/** + * \brief This class permits the access of a subset of indexed fields and gives an error + * if any non-allowed fields are requested. + * + * \tparam dim The number of dimensions in the problem. + * \tparam degree The polynomial degree of the shape functions. + * \tparam number Datatype to use for `dealii::VectorizedArray`. Either + * double or float. + */ +template class variableContainer { public: -#include - // Constructors - - // Standard contructor, used for most situations - variableContainer(const dealii::MatrixFree &data, - const std::vector &_varInfoList, - const std::vector &_varChangeInfoList); - - variableContainer(const dealii::MatrixFree &data, - const std::vector &_varInfoList); - // Nonstandard constructor, used when only one index of "data" should be used, - // use with care! - variableContainer(const dealii::MatrixFree &data, - const std::vector &_varInfoList, - const unsigned int &fixed_index); - - // Methods to get the value/grad/hess in the residual method (this is how the - // user gets these values in equations.h) - T + using EvalFlags = dealii::EvaluationFlags::EvaluationFlags; + + /** + * \brief Constructor. + */ + variableContainer(const dealii::MatrixFree &data); + + // Methods to get the value/grad/hess in the residual method + dealii::VectorizedArray get_scalar_value(unsigned int global_variable_index) const; - dealii::Tensor<1, dim, T> + dealii::Tensor<1, dim, dealii::VectorizedArray> get_scalar_gradient(unsigned int global_variable_index) const; - dealii::Tensor<2, dim, T> + dealii::Tensor<2, dim, dealii::VectorizedArray> get_scalar_hessian(unsigned int global_variable_index) const; - dealii::Tensor<1, dim, T> + dealii::Tensor<1, dim, dealii::VectorizedArray> get_vector_value(unsigned int global_variable_index) const; - dealii::Tensor<2, dim, T> + dealii::Tensor<2, dim, dealii::VectorizedArray> get_vector_gradient(unsigned int global_variable_index) const; - dealii::Tensor<3, dim, T> + dealii::Tensor<3, dim, dealii::VectorizedArray> get_vector_hessian(unsigned int global_variable_index) const; - T - get_change_in_scalar_value(unsigned int global_variable_index) const; - dealii::Tensor<1, dim, T> - get_change_in_scalar_gradient(unsigned int global_variable_index) const; - dealii::Tensor<2, dim, T> - get_change_in_scalar_hessian(unsigned int global_variable_index) const; - dealii::Tensor<1, dim, T> - get_change_in_vector_value(unsigned int global_variable_index) const; - dealii::Tensor<2, dim, T> - get_change_in_vector_gradient(unsigned int global_variable_index) const; - dealii::Tensor<3, dim, T> - get_change_in_vector_hessian(unsigned int global_variable_index) const; - - // Methods to set the value residual and the gradient residual (this is how - // the user sets these values in equations.h) + // Methods to set the value residual and the gradient residual void - set_scalar_value_term_RHS(unsigned int global_variable_index, T val); + set_scalar_value_term(unsigned int global_variable_index, + dealii::VectorizedArray val); void - set_scalar_gradient_term_RHS(unsigned int global_variable_index, - dealii::Tensor<1, dim, T> grad); + set_scalar_gradient_term(unsigned int global_variable_index, + dealii::Tensor<1, dim, dealii::VectorizedArray> grad); void - set_vector_value_term_RHS(unsigned int global_variable_index, - dealii::Tensor<1, dim, T> val); + set_vector_value_term(unsigned int global_variable_index, + dealii::Tensor<1, dim, dealii::VectorizedArray> val); void - set_vector_gradient_term_RHS(unsigned int global_variable_index, - dealii::Tensor<2, dim, T> grad); + set_vector_gradient_term(unsigned int global_variable_index, + dealii::Tensor<2, dim, dealii::VectorizedArray> grad); + /** + * \brief Initialize, read DOFs, and set evaulation flags for each variable. + */ void - set_scalar_value_term_LHS(unsigned int global_variable_index, T val); - void - set_scalar_gradient_term_LHS(unsigned int global_variable_index, - dealii::Tensor<1, dim, T> grad); - void - set_vector_value_term_LHS(unsigned int global_variable_index, - dealii::Tensor<1, dim, T> val); - void - set_vector_gradient_term_LHS(unsigned int global_variable_index, - dealii::Tensor<2, dim, T> grad); + reinit_and_eval(const dealii::LinearAlgebra::distributed::Vector &src, + unsigned int cell); - // Initialize, read DOFs, and set evaulation flags for each variable + /** + * \brief Integrate the residuals and distribute from local to global. + */ void - reinit_and_eval( - const std::vector *> &src, - unsigned int cell); - void - reinit_and_eval_change_in_solution( - const dealii::LinearAlgebra::distributed::Vector &src, - unsigned int cell, - unsigned int var_being_solved); + integrate_and_distribute(dealii::LinearAlgebra::distributed::Vector &dst); - // Only initialize the FEEvaluation object for each variable (used for - // post-processing) + /** + * \brief Initialize the `AlignedVector` for the diagonal based on the dofs per cell. + */ void - reinit(unsigned int cell); + init_diagonal(); - // Integrate the residuals and distribute from local to global - void - integrate_and_distribute( - std::vector *> &dst); + /** + * \brief Initialize the operation ptr to the cell . + */ void - integrate_and_distribute_change_in_solution_LHS( - dealii::LinearAlgebra::distributed::Vector &dst, - const unsigned int var_being_solved); + reinit_cell(unsigned int cell); // The quadrature point index, a method to get the number of quadrature points // per cell, and a method to get the xyz coordinates for the quadrature point - unsigned int q_point; + unsigned int q_point = 0; - unsigned int + [[nodiscard]] unsigned int get_num_q_points() const; - dealii::Point + [[nodiscard]] dealii::Point> get_q_point_location() const; private: + /** + * \brief Check that a variable value/gradient/hessians was marked as needed and thus + * properly initialized. + */ + void + access_valid(const unsigned int &global_variable_index, const EvalFlags &flag) const; + // Vectors of the actual FEEvaluation objects for each active variable, split // into scalar variables and vector variables for type reasons - using scalar_FEEval = dealii::FEEvaluation; - using vector_FEEval = dealii::FEEvaluation; - - boost::unordered_map> scalar_vars_map; - boost::unordered_map> vector_vars_map; + using scalar_FEEval = dealii::FEEvaluation; + using vector_FEEval = dealii::FEEvaluation; - boost::unordered_map> - scalar_change_in_vars_map; - boost::unordered_map> - vector_change_in_vars_map; + std::unordered_map> scalar_vars_map; + std::unordered_map> vector_vars_map; // Object containing some information about each variable (indices, whether // the val/grad/hess is needed, etc) - std::vector varInfoList; - std::vector varChangeInfoList; + std::vector varInfoList; // The number of variables unsigned int num_var; + + // Diagonal + std::unique_ptr>> diagonal; }; #endif diff --git a/src/core/initial_conditions/initialConditions.cc b/src/core/initial_conditions/initialConditions.cc index 923e72b3..8a898159 100644 --- a/src/core/initial_conditions/initialConditions.cc +++ b/src/core/initial_conditions/initialConditions.cc @@ -255,7 +255,7 @@ MatrixFreePDE::applyInitialConditions() { // Calculates the Laplace RHS and stores the information // in residualSet - computeLaplaceRHS(fieldIndex); + // computeLaplaceRHS(fieldIndex); if (fields[fieldIndex].type == SCALAR) { unsigned int invM_size = invMscalar.locally_owned_size(); diff --git a/src/core/outputResults.cc b/src/core/outputResults.cc index 68d1d9ed..3ae485dd 100644 --- a/src/core/outputResults.cc +++ b/src/core/outputResults.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -42,7 +43,7 @@ MatrixFreePDE::outputResults() if (userInputs.postProcessingRequired) { std::vector *> postProcessedSet; - computePostProcessedFields(postProcessedSet); + // computePostProcessedFields(postProcessedSet); unsigned int invM_size = invMscalar.locally_owned_size(); for (auto &field : postProcessedSet) { @@ -103,7 +104,7 @@ MatrixFreePDE::outputResults() { // mark field as scalar/vector unsigned int components = 0; - if (userInputs.pp_varInfoList[fieldIndex].is_scalar) + if (userInputs.pp_varInfoList[fieldIndex].var_type == fieldType::SCALAR) { components = 1; std::vector @@ -115,7 +116,7 @@ MatrixFreePDE::outputResults() solutionNames, dataType); } - else + else if (userInputs.pp_varInfoList[fieldIndex].var_type == fieldType::VECTOR) { components = dim; std::vector diff --git a/src/core/postprocessing/postprocessor.cc b/src/core/postprocessing/postprocessor.cc deleted file mode 100644 index 2f477573..00000000 --- a/src/core/postprocessing/postprocessor.cc +++ /dev/null @@ -1,87 +0,0 @@ -#include - -template -void -MatrixFreePDE::computePostProcessedFields( - std::vector *> &postProcessedSet) -{ - // Initialize the postProcessedSet - for (unsigned int fieldIndex = 0; fieldIndex < pp_attributes.size(); fieldIndex++) - { - dealii::LinearAlgebra::distributed::Vector *U = nullptr; - U = new dealii::LinearAlgebra::distributed::Vector; - postProcessedSet.push_back(U); - matrixFreeObject.initialize_dof_vector(*U, 0); - } - - // call to integrate and assemble - matrixFreeObject.cell_loop(&MatrixFreePDE::getPostProcessedFields, - this, - postProcessedSet, - solutionSet, - true); -} - -template -void -MatrixFreePDE::getPostProcessedFields( - const dealii::MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range) -{ - // initialize FEEvaulation objects - variableContainer> variable_list( - data, - userInputs.pp_baseVarInfoList); - variableContainer> - pp_variable_list(data, userInputs.pp_varInfoList, 0); - - // loop over cells - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - // Initialize, read DOFs, and set evaulation flags for each variable - variable_list.reinit_and_eval(src, cell); - pp_variable_list.reinit(cell); - - unsigned int num_q_points = variable_list.get_num_q_points(); - - dealii::VectorizedArray local_element_volume = element_volume[cell]; - - // loop over quadrature points - for (unsigned int q = 0; q < num_q_points; ++q) - { - variable_list.q_point = q; - pp_variable_list.q_point = q; - - dealii::Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - postProcessedFields(variable_list, - pp_variable_list, - q_point_loc, - local_element_volume); - } - - pp_variable_list.integrate_and_distribute(dst); - } -} - -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file diff --git a/src/core/solvers/computeLHS.cc b/src/core/solvers/computeLHS.cc deleted file mode 100644 index b8b30ca1..00000000 --- a/src/core/solvers/computeLHS.cc +++ /dev/null @@ -1,110 +0,0 @@ -// vmult() and getLHS() method for MatrixFreePDE class - -#include - -// vmult operation for LHS -template - -void -MatrixFreePDE::vmult( - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src) const -{ - // log time - computing_timer.enter_subsection("matrixFreePDE: computeLHS"); - - // create temporary copy of src vector as src2, as vector src is marked const - // and cannot be changed - dealii::LinearAlgebra::distributed::Vector src2; - matrixFreeObject.initialize_dof_vector(src2, currentFieldIndex); - src2 = src; - - // call cell_loop - if (!generatingInitialGuess) - { - matrixFreeObject.cell_loop(&MatrixFreePDE::getLHS, - this, - dst, - src2, - true); - } - else - { - matrixFreeObject.cell_loop(&MatrixFreePDE::getLaplaceLHS, - this, - dst, - src2, - true); - } - - // Account for Dirichlet BC's (essentially copy dirichlet DOF values present in src to - // dst, although it is unclear why the constraints can't just be distributed here) - for (auto &it : *valuesDirichletSet[currentFieldIndex]) - { - if (dst.in_local_range(it.first)) - { - dst(it.first) = src(it.first); //*jacobianDiagonal(it->first); - } - } - - // end log - computing_timer.leave_subsection("matrixFreePDE: computeLHS"); -} - -template -void -MatrixFreePDE::getLHS( - const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const -{ - variableContainer> - variable_list(data, userInputs.varInfoListLHS, userInputs.varChangeInfoListLHS); - - // loop over cells - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - // Initialize, read DOFs, and set evaulation flags for each variable - variable_list.reinit_and_eval(solutionSet, cell); - variable_list.reinit_and_eval_change_in_solution(src, cell, currentFieldIndex); - - unsigned int num_q_points = variable_list.get_num_q_points(); - - dealii::VectorizedArray local_element_volume = element_volume[cell]; - - // loop over quadrature points - for (unsigned int q = 0; q < num_q_points; ++q) - { - variable_list.q_point = q; - - dealii::Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - equationLHS(variable_list, q_point_loc, local_element_volume); - } - - // Integrate the residuals and distribute from local to global - variable_list.integrate_and_distribute_change_in_solution_LHS(dst, - currentFieldIndex); - } -} - -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file diff --git a/src/core/solvers/computeRHS.cc b/src/core/solvers/computeRHS.cc deleted file mode 100644 index e69b071a..00000000 --- a/src/core/solvers/computeRHS.cc +++ /dev/null @@ -1,136 +0,0 @@ -// computeRHS() method for MatrixFreePDE class - -#include -#include - -// update RHS of each field -template -void -MatrixFreePDE::computeExplicitRHS() -{ - // log time - computing_timer.enter_subsection("matrixFreePDE: computeRHS"); - - // call to integrate and assemble while clearing residual vecotrs - matrixFreeObject.cell_loop(&MatrixFreePDE::getExplicitRHS, - this, - residualSet, - solutionSet, - true); - - // end log - computing_timer.leave_subsection("matrixFreePDE: computeRHS"); -} - -template -void -MatrixFreePDE::getExplicitRHS( - const MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range) const -{ - variableContainer> variable_list( - data, - userInputs.varInfoListExplicitRHS); - - // loop over cells - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - // Initialize, read DOFs, and set evaulation flags for each variable - variable_list.reinit_and_eval(src, cell); - - unsigned int num_q_points = variable_list.get_num_q_points(); - - dealii::VectorizedArray local_element_volume = element_volume[cell]; - - // loop over quadrature points - for (unsigned int q = 0; q < num_q_points; ++q) - { - variable_list.q_point = q; - - dealii::Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - explicitEquationRHS(variable_list, q_point_loc, local_element_volume); - } - - variable_list.integrate_and_distribute(dst); - } -} - -// update RHS of each field -template -void -MatrixFreePDE::computeNonexplicitRHS() -{ - // log time - computing_timer.enter_subsection("matrixFreePDE: computeRHS"); - - // call to integrate and assemble while clearing residual vecotrs - matrixFreeObject.cell_loop(&MatrixFreePDE::getNonexplicitRHS, - this, - residualSet, - solutionSet, - true); - - // end log - computing_timer.leave_subsection("matrixFreePDE: computeRHS"); -} - -template -void -MatrixFreePDE::getNonexplicitRHS( - const MatrixFree &data, - std::vector *> &dst, - const std::vector *> &src, - const std::pair &cell_range) const -{ - variableContainer> variable_list( - data, - userInputs.varInfoListNonexplicitRHS); - - // loop over cells - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - // Initialize, read DOFs, and set evaulation flags for each variable - variable_list.reinit_and_eval(src, cell); - - unsigned int num_q_points = variable_list.get_num_q_points(); - - dealii::VectorizedArray local_element_volume = element_volume[cell]; - - // loop over quadrature points - for (unsigned int q = 0; q < num_q_points; ++q) - { - variable_list.q_point = q; - - dealii::Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - nonExplicitEquationRHS(variable_list, q_point_loc, local_element_volume); - } - - variable_list.integrate_and_distribute(dst); - } -} - -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file diff --git a/src/core/solvers/setNonlinearEqInitialGuess.cc b/src/core/solvers/setNonlinearEqInitialGuess.cc deleted file mode 100644 index 17e52f16..00000000 --- a/src/core/solvers/setNonlinearEqInitialGuess.cc +++ /dev/null @@ -1,220 +0,0 @@ -// setNonlinearEqInitialGuess() method for MatrixFreePDE class -#include -#include - -#include -#include - -// solve each time increment -template -void -MatrixFreePDE::setNonlinearEqInitialGuess() -{ - // log time - computing_timer.enter_subsection("matrixFreePDE: setNonlinearEqInitialGuess"); - Timer time; - time.start(); - char buffer[200]; - - for (const auto &[fieldIndex, variable] : var_attributes) - { - if ((variable.eq_type == TIME_INDEPENDENT) && variable.is_nonlinear && - userInputs.nonlinear_solver_parameters.getLaplaceInitializationFlag(fieldIndex)) - { - currentFieldIndex = fieldIndex; // Used in computeLaplaceLHS() - - computeLaplaceRHS(fieldIndex); - - for (const auto &it : *valuesDirichletSet[fieldIndex]) - { - if (residualSet[fieldIndex]->in_local_range(it.first)) - { - (*residualSet[fieldIndex])(it.first) = 0.0; - } - } - - // solver controls - double tol_value = NAN; - if (userInputs.linear_solver_parameters.getToleranceType(fieldIndex) == - ABSOLUTE_RESIDUAL) - { - tol_value = - userInputs.linear_solver_parameters.getToleranceValue(fieldIndex); - } - else - { - tol_value = - userInputs.linear_solver_parameters.getToleranceValue(fieldIndex) * - residualSet[fieldIndex]->l2_norm(); - } - - SolverControl solver_control( - userInputs.linear_solver_parameters.getMaxIterations(fieldIndex), - tol_value); - - // Currently the only allowed solver is SolverCG, the SolverType input - // variable is a dummy - SolverCG> solver( - solver_control); - - // solve - try - { - if (fields[fieldIndex].type == SCALAR) - { - dU_scalar = 0.0; - solver.solve(*this, - dU_scalar, - *residualSet[fieldIndex], - IdentityMatrix(solutionSet[fieldIndex]->size())); - } - else - { - dU_vector = 0.0; - solver.solve(*this, - dU_vector, - *residualSet[fieldIndex], - IdentityMatrix(solutionSet[fieldIndex]->size())); - } - } - catch (...) - { - pcout << "\nWarning: implicit solver did not converge as per set " - "tolerances. consider increasing maxSolverIterations or " - "decreasing solverTolerance.\n"; - } - - if (fields[fieldIndex].type == SCALAR) - { - *solutionSet[fieldIndex] += dU_scalar; - } - else - { - *solutionSet[fieldIndex] += dU_vector; - } - - if (currentIncrement % userInputs.skip_print_steps == 0) - { - double dU_norm = NAN; - if (fields[fieldIndex].type == SCALAR) - { - dU_norm = dU_scalar.l2_norm(); - } - else - { - dU_norm = dU_vector.l2_norm(); - } - snprintf(buffer, - sizeof(buffer), - "field '%2s' [laplace solve for initial guess]: initial " - "residual:%12.6e, current residual:%12.6e, nsteps:%u, " - "tolerance criterion:%12.6e, solution: %12.6e, dU: %12.6e\n", - fields[fieldIndex].name.c_str(), - residualSet[fieldIndex]->l2_norm(), - solver_control.last_value(), - solver_control.last_step(), - solver_control.tolerance(), - solutionSet[fieldIndex]->l2_norm(), - dU_norm); - pcout << buffer << "\n"; - } - } - } - - if (currentIncrement % userInputs.skip_print_steps == 0) - { - pcout << "wall time: " << time.wall_time() << "s\n"; - } - // log time - computing_timer.leave_subsection("matrixFreePDE: setNonlinearEqInitialGuess"); -} - -template -void -MatrixFreePDE::computeLaplaceRHS(unsigned int fieldIndex) -{ - // log time - computing_timer.enter_subsection("matrixFreePDE: computeLaplaceRHS"); - - // call to integrate and assemble while clearing residual vecotrs - matrixFreeObject.cell_loop(&MatrixFreePDE::getLaplaceRHS, - this, - *residualSet[fieldIndex], - *solutionSet[fieldIndex], - true); - - // end log - computing_timer.leave_subsection("matrixFreePDE: computeLaplaceRHS"); -} - -template -void -MatrixFreePDE::getLaplaceRHS( - const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const -{ - FEEvaluation mat(data); - - dealii::EvaluationFlags::EvaluationFlags laplace_flags = - dealii::EvaluationFlags::gradients; - // loop over all "cells" - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - mat.reinit(cell); - mat.read_dof_values(src); - mat.evaluate(laplace_flags); - for (unsigned int q = 0; q < mat.n_q_points; ++q) - { - mat.submit_gradient(mat.get_gradient(q), q); - } - mat.integrate(laplace_flags); - mat.distribute_local_to_global(dst); - } -} - -template -void -MatrixFreePDE::getLaplaceLHS( - const MatrixFree &data, - dealii::LinearAlgebra::distributed::Vector &dst, - const dealii::LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const -{ - FEEvaluation mat(data); - - dealii::EvaluationFlags::EvaluationFlags laplace_flags = - dealii::EvaluationFlags::gradients; - // loop over all "cells" - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) - { - mat.reinit(cell); - mat.read_dof_values(src); - mat.evaluate(laplace_flags); - for (unsigned int q = 0; q < mat.n_q_points; ++q) - { - mat.submit_gradient(-mat.get_gradient(q), q); - } - mat.integrate(laplace_flags); - mat.distribute_local_to_global(dst); - } -} - -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file diff --git a/src/core/solvers/solve.cc b/src/core/solvers/solve.cc index 48a083e3..3684c835 100644 --- a/src/core/solvers/solve.cc +++ b/src/core/solvers/solve.cc @@ -24,9 +24,9 @@ MatrixFreePDE::solve() // For any nonlinear equation, set the initial guess as the solution to // Laplace's equations - generatingInitialGuess = true; - setNonlinearEqInitialGuess(); - generatingInitialGuess = false; + // generatingInitialGuess = true; + // setNonlinearEqInitialGuess(); + // generatingInitialGuess = false; // Do an initial solve to set the elliptic fields solveIncrement(true); @@ -140,7 +140,7 @@ MatrixFreePDE::solve() // time independent BVP else { - generatingInitialGuess = false; + // generatingInitialGuess = false; // solve solveIncrement(false); diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index 58d91399..8f45354b 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -17,7 +17,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) // Get the RHS of the explicit equations if (hasExplicitEquation && !skip_time_dependent) { - computeExplicitRHS(); + // computeExplicitRHS(); } // solve for each field @@ -73,7 +73,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) nonlinear_iteration_converged = true; // Update residualSet for the non-explicitly updated variables - computeNonexplicitRHS(); + // computeNonexplicitRHS(); for (const auto &[fieldIndex, variable] : var_attributes) { @@ -326,18 +326,18 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, if (fields[fieldIndex].type == SCALAR) { dU_scalar = 0.0; - solver.solve(*this, - dU_scalar, - *residualSet[fieldIndex], - IdentityMatrix(solutionSet[fieldIndex]->size())); + // solver.solve(*this, + // dU_scalar, + // *residualSet[fieldIndex], + // IdentityMatrix(solutionSet[fieldIndex]->size())); } else { dU_vector = 0.0; - solver.solve(*this, - dU_vector, - *residualSet[fieldIndex], - IdentityMatrix(solutionSet[fieldIndex]->size())); + // solver.solve(*this, + // dU_vector, + // *residualSet[fieldIndex], + // IdentityMatrix(solutionSet[fieldIndex]->size())); } } catch (...) @@ -373,7 +373,7 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, solutionSet[fieldIndex]->sadd(1.0, damping_coefficient, dU_vector); } - computeNonexplicitRHS(); + // computeNonexplicitRHS(); for (const auto &it : *valuesDirichletSet[fieldIndex]) { diff --git a/src/core/userInputParameters.cc b/src/core/userInputParameters.cc index 10e50357..0f7fdaf8 100644 --- a/src/core/userInputParameters.cc +++ b/src/core/userInputParameters.cc @@ -75,7 +75,7 @@ userInputParameters::loadVariableAttributes() varInfoListExplicitRHS.reserve(num_var_explicit_RHS); for (const auto &[index, variable] : var_attributes) { - variable_info varInfo {}; + variableInfo varInfo {}; varInfo.evaluation_flags = variable.eval_flags_explicit_RHS; @@ -83,10 +83,7 @@ userInputParameters::loadVariableAttributes() varInfo.global_var_index = index; - varInfo.var_needed = - !static_cast(varInfo.evaluation_flags & dealii::EvaluationFlags::nothing); - - varInfo.is_scalar = variable.var_type == SCALAR; + varInfo.var_type = variable.var_type; varInfoListExplicitRHS.push_back(varInfo); } @@ -104,7 +101,7 @@ userInputParameters::loadVariableAttributes() varInfoListNonexplicitRHS.reserve(num_var_nonexplicit_RHS); for (const auto &[index, variable] : var_attributes) { - variable_info varInfo {}; + variableInfo varInfo {}; varInfo.evaluation_flags = variable.eval_flags_nonexplicit_RHS; @@ -112,10 +109,7 @@ userInputParameters::loadVariableAttributes() varInfo.global_var_index = index; - varInfo.var_needed = - !static_cast(varInfo.evaluation_flags & dealii::EvaluationFlags::nothing); - - varInfo.is_scalar = variable.var_type == SCALAR; + varInfo.var_type = variable.var_type; varInfoListNonexplicitRHS.push_back(varInfo); } @@ -134,7 +128,7 @@ userInputParameters::loadVariableAttributes() varInfoListLHS.reserve(num_var_LHS); for (const auto &[index, variable] : var_attributes) { - variable_info varInfo {}; + variableInfo varInfo {}; varInfo.evaluation_flags = variable.eval_flags_nonexplicit_LHS; @@ -142,10 +136,7 @@ userInputParameters::loadVariableAttributes() varInfo.global_var_index = index; - varInfo.var_needed = - !static_cast(varInfo.evaluation_flags & dealii::EvaluationFlags::nothing); - - varInfo.is_scalar = variable.var_type == SCALAR; + varInfo.var_type = variable.var_type; varInfoListLHS.push_back(varInfo); } @@ -153,7 +144,7 @@ userInputParameters::loadVariableAttributes() varChangeInfoListLHS.reserve(num_var_LHS); for (const auto &[index, variable] : var_attributes) { - variable_info varInfo {}; + variableInfo varInfo {}; varInfo.evaluation_flags = variable.eval_flags_change_nonexplicit_LHS; @@ -162,10 +153,7 @@ userInputParameters::loadVariableAttributes() varInfo.global_var_index = index; - varInfo.var_needed = - !static_cast(varInfo.evaluation_flags & dealii::EvaluationFlags::nothing); - - varInfo.is_scalar = variable.var_type == SCALAR; + varInfo.var_type = variable.var_type; varChangeInfoListLHS.push_back(varInfo); } @@ -175,16 +163,13 @@ userInputParameters::loadVariableAttributes() pp_baseVarInfoList.reserve(var_attributes.size()); for (const auto &[index, variable] : var_attributes) { - variable_info varInfo {}; + variableInfo varInfo {}; varInfo.evaluation_flags = variable.eval_flags_postprocess; varInfo.global_var_index = index; - varInfo.var_needed = - !static_cast(varInfo.evaluation_flags & dealii::EvaluationFlags::nothing); - - varInfo.is_scalar = variable.var_type == SCALAR; + varInfo.var_type = variable.var_type; pp_baseVarInfoList.push_back(varInfo); } @@ -208,15 +193,13 @@ userInputParameters::loadVariableAttributes() pp_varInfoList.reserve(pp_attributes.size()); for (const auto &[pp_index, pp_variable] : pp_attributes) { - variable_info varInfo {}; - - varInfo.var_needed = true; + variableInfo varInfo {}; varInfo.residual_flags = pp_variable.eval_flags_residual_postprocess; varInfo.global_var_index = pp_index; - varInfo.is_scalar = pp_variable.var_type == SCALAR; + varInfo.var_type = pp_variable.var_type; pp_varInfoList.push_back(varInfo); } diff --git a/src/core/variableContainer.cc b/src/core/variableContainer.cc index 7d5bcf45..40fd09d5 100644 --- a/src/core/variableContainer.cc +++ b/src/core/variableContainer.cc @@ -1,120 +1,59 @@ +#include +#include + #include +#include #include +#include +#include -template -variableContainer::variableContainer( - const dealii::MatrixFree &data, - const std::vector &_varInfoList, - const std::vector &_varChangeInfoList) - : varInfoList(_varInfoList) - , varChangeInfoList(_varChangeInfoList) - , num_var(varInfoList.size()) -{ - for (unsigned int i = 0; i < num_var; i++) - { - const auto &var_info = varInfoList[i]; - const auto &var_change_info = varChangeInfoList[i]; +template +variableContainer::variableContainer( + const dealii::MatrixFree &data) - if (var_info.var_needed) - { - const unsigned int var_index = var_info.global_var_index; - - if (var_info.is_scalar) - { - scalar_vars_map.emplace(var_index, - std::make_unique(data, i)); - } - else - { - vector_vars_map.emplace(var_index, - std::make_unique(data, i)); - } - } +{ + // Set all flags here for testing purposes. Also only one scalar field + variableInfo var_info {0, + fieldType::SCALAR, + dealii::EvaluationFlags::gradients, + dealii::EvaluationFlags::gradients}; - if (var_change_info.var_needed) - { - const unsigned int var_index = var_change_info.global_var_index; - - if (var_change_info.is_scalar) - { - scalar_change_in_vars_map.emplace(var_index, - std::make_unique(data, i)); - } - else - { - vector_change_in_vars_map.emplace(var_index, - std::make_unique(data, i)); - } - } - } -} + varInfoList.emplace_back(var_info); + num_var = varInfoList.size(); -template -variableContainer::variableContainer( - const dealii::MatrixFree &data, - const std::vector &_varInfoList) - : varInfoList(_varInfoList) - , num_var(varInfoList.size()) -{ for (unsigned int i = 0; i < num_var; i++) { const auto &var_info = varInfoList[i]; - if (!var_info.var_needed) - { - continue; - } - const unsigned int var_index = var_info.global_var_index; - if (var_info.is_scalar) + if (var_info.var_type == fieldType::SCALAR) { scalar_vars_map.emplace(var_index, std::make_unique(data, i)); } - else + else if (var_info.var_type == fieldType::VECTOR) { vector_vars_map.emplace(var_index, std::make_unique(data, i)); } } } -// Variant of the constructor where it reads from a fixed index of "data", used -// for post-processing -template -variableContainer::variableContainer( - const dealii::MatrixFree &data, - const std::vector &_varInfoList, - const unsigned int &fixed_index) - : varInfoList(_varInfoList) - , num_var(varInfoList.size()) +template +void +variableContainer::access_valid( + [[maybe_unused]] const unsigned int &global_variable_index, + [[maybe_unused]] const EvalFlags &flag) const { - for (unsigned int i = 0; i < num_var; i++) - { - const auto &var_info = varInfoList[i]; - - if (!var_info.var_needed) - { - continue; - } - - const unsigned int var_index = var_info.global_var_index; - - if (var_info.is_scalar) - { - scalar_vars_map.emplace(var_index, - std::make_unique(data, fixed_index)); - } - else - { - vector_vars_map.emplace(var_index, - std::make_unique(data, fixed_index)); - } - } + Assert(varInfoList.at(global_variable_index).evaluation_flags & flag, + dealii::ExcMessage("PRISMS-PF Error: Attempted access of a variable that was " + "not marked as needed in 'equations.cc'. The attempted " + "access was for variable with index " + + std::to_string(global_variable_index) + ".")); } -template +template unsigned int -variableContainer::get_num_q_points() const +variableContainer::get_num_q_points() const { if (!scalar_vars_map.empty()) { @@ -124,26 +63,17 @@ variableContainer::get_num_q_points() const { return vector_vars_map.begin()->second->n_q_points; } - else if (!scalar_change_in_vars_map.empty()) - { - return scalar_change_in_vars_map.begin()->second->n_q_points; - } - else if (!vector_change_in_vars_map.empty()) - { - return vector_change_in_vars_map.begin()->second->n_q_points; - } - else - { - AssertThrow(false, - dealii::ExcMessage( - "PRISMS-PF Error: When trying to access the number of quadrature " - "points, all FEEvaluation object containers were empty.")); - } + + AssertThrow(false, + dealii::ExcMessage( + "PRISMS-PF Error: When trying to access the number of quadrature " + "points, all FEEvaluation object containers were empty.")); + return 0; } -template -dealii::Point -variableContainer::get_q_point_location() const +template +dealii::Point> +variableContainer::get_q_point_location() const { if (!scalar_vars_map.empty()) { @@ -153,493 +83,234 @@ variableContainer::get_q_point_location() const { return vector_vars_map.begin()->second->quadrature_point(q_point); } - else if (!scalar_change_in_vars_map.empty()) - { - return scalar_change_in_vars_map.begin()->second->quadrature_point(q_point); - } - else if (!vector_change_in_vars_map.empty()) - { - return vector_change_in_vars_map.begin()->second->quadrature_point(q_point); - } - else - { - AssertThrow(false, - dealii::ExcMessage( - "PRISMS-PF Error: When trying to access the quadrature point " - "location, all FEEvaluation object containers were empty.")); - } + + AssertThrow(false, + dealii::ExcMessage( + "PRISMS-PF Error: When trying to access the quadrature point " + "location, all FEEvaluation object containers were empty.")); + return dealii::Point>(); } -template +template void -variableContainer::reinit_and_eval( - const std::vector *> &src, - unsigned int cell) +variableContainer::reinit_and_eval( + const dealii::LinearAlgebra::distributed::Vector &src, + unsigned int cell) { for (unsigned int i = 0; i < num_var; i++) { - const auto &var_info = varInfoList[i]; - - if (!var_info.var_needed) - { - continue; - } - + const auto &var_info = varInfoList[i]; const unsigned int var_index = var_info.global_var_index; - if (var_info.is_scalar) + if (var_info.var_type == fieldType::SCALAR) { - auto *scalar_FEEval_ptr = scalar_vars_map[var_index].get(); + auto *scalar_FEEval_ptr = scalar_vars_map.at(var_index).get(); scalar_FEEval_ptr->reinit(cell); - scalar_FEEval_ptr->read_dof_values(*src[i]); + scalar_FEEval_ptr->read_dof_values(src); scalar_FEEval_ptr->evaluate(var_info.evaluation_flags); } - else + else if (var_info.var_type == fieldType::VECTOR) { - auto *vector_FEEval_ptr = vector_vars_map[var_index].get(); + auto *vector_FEEval_ptr = vector_vars_map.at(var_index).get(); vector_FEEval_ptr->reinit(cell); - vector_FEEval_ptr->read_dof_values(*src[i]); + vector_FEEval_ptr->read_dof_values(src); vector_FEEval_ptr->evaluate(var_info.evaluation_flags); } } } -/** - * This is specialized for the LHS where a change in solution is needed. The RHS method - * takes the src as a vector of dealii::LinearAlgebra::distributed::Vectors. - */ -template -void -variableContainer::reinit_and_eval_change_in_solution( - const dealii::LinearAlgebra::distributed::Vector &src, - unsigned int cell, - unsigned int var_being_solved) -{ - if (varChangeInfoList[var_being_solved].is_scalar) - { - auto *scalar_FEEval_ptr = scalar_change_in_vars_map[var_being_solved].get(); - scalar_FEEval_ptr->reinit(cell); - scalar_FEEval_ptr->read_dof_values(src); - scalar_FEEval_ptr->evaluate(varChangeInfoList[var_being_solved].evaluation_flags); - } - else - { - auto *vector_FEEval_ptr = vector_change_in_vars_map[var_being_solved].get(); - vector_FEEval_ptr->reinit(cell); - vector_FEEval_ptr->read_dof_values(src); - vector_FEEval_ptr->evaluate(varChangeInfoList[var_being_solved].evaluation_flags); - } -} - -template +template void -variableContainer::reinit(unsigned int cell) +variableContainer::integrate_and_distribute( + dealii::LinearAlgebra::distributed::Vector &dst) { for (unsigned int i = 0; i < num_var; i++) { const auto &var_info = varInfoList[i]; - if (!var_info.var_needed) - { - continue; - } - const unsigned int var_index = var_info.global_var_index; - if (var_info.is_scalar) + if (var_info.var_type == fieldType::SCALAR) { - scalar_vars_map[var_index]->reinit(cell); + auto *scalar_FEEval_ptr = scalar_vars_map.at(var_index).get(); + scalar_FEEval_ptr->integrate_scatter(var_info.residual_flags, dst); } - else + else if (var_info.var_type == fieldType::VECTOR) { - vector_vars_map[var_index]->reinit(cell); + auto *vector_FEEval_ptr = vector_vars_map.at(var_index).get(); + vector_FEEval_ptr->integrate_scatter(var_info.residual_flags, dst); } } } -template +template void -variableContainer::integrate_and_distribute( - std::vector *> &dst) +variableContainer::init_diagonal() { for (unsigned int i = 0; i < num_var; i++) { const auto &var_info = varInfoList[i]; - if (var_info.residual_flags & dealii::EvaluationFlags::nothing) - { - continue; - } - const unsigned int var_index = var_info.global_var_index; - if (var_info.is_scalar) + if (var_info.var_type == fieldType::SCALAR) { - auto *scalar_FEEval_ptr = scalar_vars_map[var_index].get(); - scalar_FEEval_ptr->integrate(var_info.residual_flags); - scalar_FEEval_ptr->distribute_local_to_global(*dst[i]); + diagonal = + std::make_unique>>( + scalar_vars_map.at(var_index)->dofs_per_cell); } - else + else if (var_info.var_type == fieldType::VECTOR) { - auto *vector_FEEval_ptr = vector_vars_map[var_index].get(); - vector_FEEval_ptr->integrate(var_info.residual_flags); - vector_FEEval_ptr->distribute_local_to_global(*dst[i]); + diagonal = + std::make_unique>>( + vector_vars_map.at(var_index)->dofs_per_cell); } } } -template +template void -variableContainer::integrate_and_distribute_change_in_solution_LHS( - dealii::LinearAlgebra::distributed::Vector &dst, - const unsigned int var_being_solved) -{ - // integrate - if (varChangeInfoList[var_being_solved].is_scalar) - { - auto *scalar_FEEval_ptr = scalar_change_in_vars_map[var_being_solved].get(); - scalar_FEEval_ptr->integrate(varChangeInfoList[var_being_solved].residual_flags); - scalar_FEEval_ptr->distribute_local_to_global(dst); - } - else - { - auto *vector_FEEval_ptr = vector_change_in_vars_map[var_being_solved].get(); - vector_FEEval_ptr->integrate(varChangeInfoList[var_being_solved].residual_flags); - vector_FEEval_ptr->distribute_local_to_global(dst); - } -} - -// Need to add index checking to these functions so that an error is thrown if -// the index wasn't set -template -T -variableContainer::get_scalar_value( - unsigned int global_variable_index) const +variableContainer::reinit_cell(unsigned int cell) { - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::values) - { - return scalar_vars_map.at(global_variable_index)->get_value(q_point); - } - else + for (unsigned int i = 0; i < num_var; i++) { - std::cerr << "PRISMS-PF Error: Attempted access of a variable value that " - "was not marked as needed in 'equations.cc'. The attempted " - "access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + const auto &var_info = varInfoList[i]; -template -dealii::Tensor<1, dim, T> -variableContainer::get_scalar_gradient( - unsigned int global_variable_index) const -{ - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::gradients) - { - return scalar_vars_map.at(global_variable_index)->get_gradient(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a variable gradient " - "that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + const unsigned int var_index = var_info.global_var_index; -template -dealii::Tensor<2, dim, T> -variableContainer::get_scalar_hessian( - unsigned int global_variable_index) const -{ - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::hessians) - { - return scalar_vars_map.at(global_variable_index)->get_hessian(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a variable hessian " - "that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); + if (var_info.var_type == fieldType::SCALAR) + { + scalar_vars_map.at(var_index).get()->reinit(cell); + } + else if (var_info.var_type == fieldType::VECTOR) + { + vector_vars_map.at(var_index).get()->reinit(cell); + } } } -template -dealii::Tensor<1, dim, T> -variableContainer::get_vector_value( +template +dealii::VectorizedArray +variableContainer::get_scalar_value( unsigned int global_variable_index) const { - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::values) - { - return vector_vars_map.at(global_variable_index)->get_value(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a variable value that " - "was not marked as needed in 'equations.cc'. The attempted " - "access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + access_valid(global_variable_index, EvalFlags::values); -template -dealii::Tensor<2, dim, T> -variableContainer::get_vector_gradient( - unsigned int global_variable_index) const -{ - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::gradients) - { - return vector_vars_map.at(global_variable_index)->get_gradient(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a variable gradient " - "that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } + return scalar_vars_map.at(global_variable_index)->get_value(q_point); } -template -dealii::Tensor<3, dim, T> -variableContainer::get_vector_hessian( +template +dealii::Tensor<1, dim, dealii::VectorizedArray> +variableContainer::get_scalar_gradient( unsigned int global_variable_index) const { - if (varInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::hessians) - { - return vector_vars_map.at(global_variable_index)->get_hessian(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a variable hessian " - "that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + access_valid(global_variable_index, EvalFlags::gradients); -// Need to add index checking to these functions so that an error is thrown if -// the index wasn't set -template -T -variableContainer::get_change_in_scalar_value( - unsigned int global_variable_index) const -{ - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::values) - { - return scalar_change_in_vars_map.at(global_variable_index)->get_value(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "value that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } + return scalar_vars_map.at(global_variable_index)->get_gradient(q_point); } -template -dealii::Tensor<1, dim, T> -variableContainer::get_change_in_scalar_gradient( +template +dealii::Tensor<2, dim, dealii::VectorizedArray> +variableContainer::get_scalar_hessian( unsigned int global_variable_index) const { - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::gradients) - { - return scalar_change_in_vars_map.at(global_variable_index)->get_gradient(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "gradient that was not marked as needed in 'equations.cc'. " - "The attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + access_valid(global_variable_index, EvalFlags::hessians); -template -dealii::Tensor<2, dim, T> -variableContainer::get_change_in_scalar_hessian( - unsigned int global_variable_index) const -{ - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::hessians) - { - return scalar_change_in_vars_map.at(global_variable_index)->get_hessian(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "hessian that was not marked as needed in 'equations.cc'. " - "The attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } + return scalar_vars_map.at(global_variable_index)->get_hessian(q_point); } -template -dealii::Tensor<1, dim, T> -variableContainer::get_change_in_vector_value( +template +dealii::Tensor<1, dim, dealii::VectorizedArray> +variableContainer::get_vector_value( unsigned int global_variable_index) const { - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::values) - { - return vector_change_in_vars_map.at(global_variable_index)->get_value(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "value that was not marked as needed in 'equations.cc'. The " - "attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} + access_valid(global_variable_index, EvalFlags::values); -template -dealii::Tensor<2, dim, T> -variableContainer::get_change_in_vector_gradient( - unsigned int global_variable_index) const -{ - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::gradients) - { - return vector_change_in_vars_map.at(global_variable_index)->get_gradient(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "gradient that was not marked as needed in 'equations.cc'. " - "The attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } + return vector_vars_map.at(global_variable_index)->get_value(q_point); } -template -dealii::Tensor<3, dim, T> -variableContainer::get_change_in_vector_hessian( +template +dealii::Tensor<2, dim, dealii::VectorizedArray> +variableContainer::get_vector_gradient( unsigned int global_variable_index) const { - if (varChangeInfoList[global_variable_index].evaluation_flags & - dealii::EvaluationFlags::hessians) - { - return vector_change_in_vars_map.at(global_variable_index)->get_hessian(q_point); - } - else - { - std::cerr << "PRISMS-PF Error: Attempted access of a change in variable " - "hessian that was not marked as needed in 'equations.cc'. " - "The attempted access was for variable with index " - << global_variable_index << " .\n"; - abort(); - } -} - -// The methods to set the residual terms -template -void -variableContainer::set_scalar_value_term_RHS( - unsigned int global_variable_index, - T val) -{ - scalar_vars_map[global_variable_index]->submit_value(val, q_point); -} + access_valid(global_variable_index, EvalFlags::gradients); -template -void -variableContainer::set_scalar_gradient_term_RHS( - unsigned int global_variable_index, - dealii::Tensor<1, dim, T> grad) -{ - scalar_vars_map[global_variable_index]->submit_gradient(grad, q_point); + return vector_vars_map.at(global_variable_index)->get_gradient(q_point); } -template -void -variableContainer::set_vector_value_term_RHS( - unsigned int global_variable_index, - dealii::Tensor<1, dim, T> val) +template +dealii::Tensor<3, dim, dealii::VectorizedArray> +variableContainer::get_vector_hessian( + unsigned int global_variable_index) const { - vector_vars_map[global_variable_index]->submit_value(val, q_point); -} + access_valid(global_variable_index, EvalFlags::hessians); -template -void -variableContainer::set_vector_gradient_term_RHS( - unsigned int global_variable_index, - dealii::Tensor<2, dim, T> grad) -{ - vector_vars_map[global_variable_index]->submit_gradient(grad, q_point); + return vector_vars_map.at(global_variable_index)->get_hessian(q_point); } -template +template void -variableContainer::set_scalar_value_term_LHS( - unsigned int global_variable_index, - T val) +variableContainer::set_scalar_value_term( + unsigned int global_variable_index, + dealii::VectorizedArray val) { - scalar_change_in_vars_map[global_variable_index]->submit_value(val, q_point); + scalar_vars_map.at(global_variable_index)->submit_value(val, q_point); } -template +template void -variableContainer::set_scalar_gradient_term_LHS( - unsigned int global_variable_index, - dealii::Tensor<1, dim, T> grad) +variableContainer::set_scalar_gradient_term( + unsigned int global_variable_index, + dealii::Tensor<1, dim, dealii::VectorizedArray> grad) { - scalar_change_in_vars_map[global_variable_index]->submit_gradient(grad, q_point); + scalar_vars_map.at(global_variable_index)->submit_gradient(grad, q_point); } -template +template void -variableContainer::set_vector_value_term_LHS( - unsigned int global_variable_index, - dealii::Tensor<1, dim, T> val) +variableContainer::set_vector_value_term( + unsigned int global_variable_index, + dealii::Tensor<1, dim, dealii::VectorizedArray> val) { - vector_change_in_vars_map[global_variable_index]->submit_value(val, q_point); + vector_vars_map.at(global_variable_index)->submit_value(val, q_point); } -template +template void -variableContainer::set_vector_gradient_term_LHS( - unsigned int global_variable_index, - dealii::Tensor<2, dim, T> grad) +variableContainer::set_vector_gradient_term( + unsigned int global_variable_index, + dealii::Tensor<2, dim, dealii::VectorizedArray> grad) { - vector_change_in_vars_map[global_variable_index]->submit_gradient(grad, q_point); + vector_vars_map.at(global_variable_index)->submit_gradient(grad, q_point); } -template class variableContainer<2, 1, dealii::VectorizedArray>; -template class variableContainer<3, 1, dealii::VectorizedArray>; - -template class variableContainer<2, 2, dealii::VectorizedArray>; -template class variableContainer<3, 2, dealii::VectorizedArray>; - -template class variableContainer<2, 3, dealii::VectorizedArray>; -template class variableContainer<3, 3, dealii::VectorizedArray>; - -template class variableContainer<2, 4, dealii::VectorizedArray>; -template class variableContainer<3, 4, dealii::VectorizedArray>; - -template class variableContainer<2, 5, dealii::VectorizedArray>; -template class variableContainer<3, 5, dealii::VectorizedArray>; - -template class variableContainer<2, 6, dealii::VectorizedArray>; -template class variableContainer<3, 6, dealii::VectorizedArray>; \ No newline at end of file +template class variableContainer<2, 1, float>; +template class variableContainer<3, 1, float>; +template class variableContainer<2, 1, double>; +template class variableContainer<3, 1, double>; + +template class variableContainer<2, 2, float>; +template class variableContainer<3, 2, float>; +template class variableContainer<2, 2, double>; +template class variableContainer<3, 2, double>; + +template class variableContainer<2, 3, float>; +template class variableContainer<3, 3, float>; +template class variableContainer<2, 3, double>; +template class variableContainer<3, 3, double>; + +template class variableContainer<2, 4, float>; +template class variableContainer<3, 4, float>; +template class variableContainer<2, 4, double>; +template class variableContainer<3, 4, double>; + +template class variableContainer<2, 5, float>; +template class variableContainer<3, 5, float>; +template class variableContainer<2, 5, double>; +template class variableContainer<3, 5, double>; + +template class variableContainer<2, 6, float>; +template class variableContainer<3, 6, float>; +template class variableContainer<2, 6, double>; +template class variableContainer<3, 6, double>; \ No newline at end of file From fb0cbc5e3a258f1708e4d94c1651078bd438be0f Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 14:44:06 -0500 Subject: [PATCH 02/23] temp disable CI runs --- .github/workflows/clang-tidy.yml | 1 - .github/workflows/linux.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 243e51b9..38500019 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -7,7 +7,6 @@ on: pull_request: branches: - master - - devel types: - opened - reopened diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 48b3b329..cf7bf9d7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -7,7 +7,6 @@ on: pull_request: branches: - master - - devel types: - opened - reopened From dff4074213f3c93d83d9834ab73886d7cd5a1674 Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 15:14:59 -0500 Subject: [PATCH 03/23] janky implementation of diagonal variableContainer stuff --- include/core/matrix_free_operator.h | 46 ++++++++------ include/core/variableContainer.h | 32 ++++++++-- src/core/variableContainer.cc | 99 +++++++++++++++++++++++++---- 3 files changed, 142 insertions(+), 35 deletions(-) diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index cd2c8a6e..7a587431 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -240,34 +240,42 @@ matrixFreeOperator::local_compute_diagonal( [[maybe_unused]] const unsigned int &dummy, const std::pair &cell_range) const { - FEEvaluation phi(data); + // Field index + unsigned int field_index = 0; - AlignedVector> diagonal(phi.dofs_per_cell); + // Constructor for FEEvaluation objects + variableContainer variable_list(data); + + variable_list.init_diagonal(field_index); for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) { - phi.reinit(cell); - for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + variable_list.reinit_cell(cell); + + for (unsigned int i = 0; i < variable_list.n_dofs_per_cell; ++i) { - for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) - { - phi.submit_dof_value(VectorizedArray(), j); - } - phi.submit_dof_value(make_vectorized_array(1.), i); + variable_list.reinit_and_eval_diagonal(field_index, i); - phi.evaluate(EvaluationFlags::gradients); - for (const unsigned int q : phi.quadrature_point_indices()) + // Number of quadrature points + unsigned int n_q_points = variable_list.get_num_q_points(); + + for (unsigned int q = 0; q < n_q_points; ++q) { - phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), q); + // Set the quadrature point + variable_list.q_point = q; + + // Grab the quadrature point location + Point> q_point_loc = + variable_list.get_q_point_location(); + + // Calculate the residuals + nonexplicit_RHS(variable_list, q_point_loc); } - phi.integrate(EvaluationFlags::gradients); - diagonal[i] = phi.get_dof_value(i); - } - for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) - { - phi.submit_dof_value(diagonal[i], i); + + variable_list.integrate_and_assemble_local_diagonal(field_index, i); } - phi.distribute_local_to_global(dst); + + variable_list.distribute_diagonal(dst, field_index); } } diff --git a/include/core/variableContainer.h b/include/core/variableContainer.h index ad1efe87..491edfb7 100644 --- a/include/core/variableContainer.h +++ b/include/core/variableContainer.h @@ -71,21 +71,45 @@ class variableContainer integrate_and_distribute(dealii::LinearAlgebra::distributed::Vector &dst); /** - * \brief Initialize the `AlignedVector` for the diagonal based on the dofs per cell. + * \brief Initialize the `AlignedVector` for the diagonal based on the DoFs per cell. + * Additionally, assign `n_dofs_per_cell` based on the current field index. */ void - init_diagonal(); + init_diagonal(unsigned int global_var_index); /** - * \brief Initialize the operation ptr to the cell . + * \brief Initialize the operation ptr to the cell for all field indices. */ void reinit_cell(unsigned int cell); + /** + * \brief Submit the DoFs for the diagonal identity matrix and evaluate based on the + * evaluation flags. + */ + void + reinit_and_eval_diagonal(unsigned int global_var_index, unsigned int i); + + /** + * \brief Integrate the residuals and assemble the local diagonal + */ + void + integrate_and_assemble_local_diagonal(unsigned int global_var_index, unsigned int i); + + /** + * \brief Distribute the diagonal from local to global. + */ + void + distribute_diagonal(dealii::LinearAlgebra::distributed::Vector &dst, + unsigned int global_var_index); + // The quadrature point index, a method to get the number of quadrature points // per cell, and a method to get the xyz coordinates for the quadrature point unsigned int q_point = 0; + // Number of DoFs per cell + unsigned int n_dofs_per_cell; + [[nodiscard]] unsigned int get_num_q_points() const; @@ -115,7 +139,7 @@ class variableContainer // The number of variables unsigned int num_var; - // Diagonal + // Diagonal matrix that is used for preconditioning std::unique_ptr>> diagonal; }; diff --git a/src/core/variableContainer.cc b/src/core/variableContainer.cc index 40fd09d5..21af241c 100644 --- a/src/core/variableContainer.cc +++ b/src/core/variableContainer.cc @@ -145,7 +145,26 @@ variableContainer::integrate_and_distribute( template void -variableContainer::init_diagonal() +variableContainer::init_diagonal(unsigned int global_var_index) +{ + const auto &var_info = varInfoList[global_var_index]; + + if (var_info.var_type == fieldType::SCALAR) + { + n_dofs_per_cell = scalar_vars_map.at(global_var_index)->dofs_per_cell; + } + else if (var_info.var_type == fieldType::VECTOR) + { + n_dofs_per_cell = vector_vars_map.at(global_var_index)->dofs_per_cell; + } + + diagonal = std::make_unique>>( + n_dofs_per_cell); +} + +template +void +variableContainer::reinit_cell(unsigned int cell) { for (unsigned int i = 0; i < num_var; i++) { @@ -155,40 +174,96 @@ variableContainer::init_diagonal() if (var_info.var_type == fieldType::SCALAR) { - diagonal = - std::make_unique>>( - scalar_vars_map.at(var_index)->dofs_per_cell); + scalar_vars_map.at(var_index).get()->reinit(cell); } else if (var_info.var_type == fieldType::VECTOR) { - diagonal = - std::make_unique>>( - vector_vars_map.at(var_index)->dofs_per_cell); + vector_vars_map.at(var_index).get()->reinit(cell); } } } template void -variableContainer::reinit_cell(unsigned int cell) +variableContainer::reinit_and_eval_diagonal( + unsigned int global_var_index, + unsigned int i) { - for (unsigned int i = 0; i < num_var; i++) + const auto &var_info = varInfoList[global_var_index]; + + if (var_info.var_type == fieldType::SCALAR) { - const auto &var_info = varInfoList[i]; + auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); + for (unsigned int j = 0; j < n_dofs_per_cell; ++j) + { + scalar_FEEval_ptr->submit_dof_value(dealii::VectorizedArray(), j); + } + scalar_FEEval_ptr->submit_dof_value(dealii::make_vectorized_array(1.0), i); + } + else if (var_info.var_type == fieldType::VECTOR) + { + AssertThrow(false, FeatureNotImplemented("Vector multigrid")); + } + for (unsigned int i = 0; i < num_var; i++) + { + const auto &var_info = varInfoList[i]; const unsigned int var_index = var_info.global_var_index; if (var_info.var_type == fieldType::SCALAR) { - scalar_vars_map.at(var_index).get()->reinit(cell); + scalar_vars_map.at(var_index)->evaluate(var_info.evaluation_flags); } else if (var_info.var_type == fieldType::VECTOR) { - vector_vars_map.at(var_index).get()->reinit(cell); + vector_vars_map.at(var_index)->evaluate(var_info.evaluation_flags); } } } +template +void +variableContainer::integrate_and_assemble_local_diagonal( + unsigned int global_var_index, + unsigned int i) +{ + const auto &var_info = varInfoList[global_var_index]; + + if (var_info.var_type == fieldType::SCALAR) + { + auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); + scalar_FEEval_ptr->integrate(var_info.residual_flags); + (*diagonal)[i] = scalar_FEEval_ptr->get_dof_value(i); + } + else if (var_info.var_type == fieldType::VECTOR) + { + AssertThrow(false, FeatureNotImplemented("Vector multigrid")); + } +} + +template +void +variableContainer::distribute_diagonal( + dealii::LinearAlgebra::distributed::Vector &dst, + unsigned int global_var_index) +{ + const auto &var_info = varInfoList[global_var_index]; + + if (var_info.var_type == fieldType::SCALAR) + { + auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); + for (unsigned int i = 0; i < n_dofs_per_cell; ++i) + { + scalar_FEEval_ptr->submit_dof_value((*diagonal)[i], i); + } + scalar_FEEval_ptr->distribute_local_to_global(dst); + } + else if (var_info.var_type == fieldType::VECTOR) + { + AssertThrow(false, FeatureNotImplemented("Vector multigrid")); + } +} + template dealii::VectorizedArray variableContainer::get_scalar_value( From 1559eeff4a7698150f51d0da632aeec21996d405 Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 15:18:53 -0500 Subject: [PATCH 04/23] removing step-37 coefficient class --- include/core/matrix_free_operator.h | 53 ----------------------------- include/core/temp_test.h | 3 -- 2 files changed, 56 deletions(-) diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index 7a587431..9ea72d58 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -9,34 +9,6 @@ using namespace dealii; -template -class Coefficient : public Function -{ -public: - virtual double - value(const Point &p, const unsigned int component = 0) const override; - - template - number - value(const Point &p, const unsigned int component = 0) const; -}; - -template -template -number -Coefficient::value(const Point &p, - const unsigned int /*component*/) const -{ - return 1.0 / (0.05 + 2.0 * p.square()); -} - -template -double -Coefficient::value(const Point &p, const unsigned int component) const -{ - return value(p, component); -} - /** * \brief This is the abstract base class for the matrix free implementation of some PDE. * @@ -69,9 +41,6 @@ class matrixFreeOperator void clear() override; - void - evaluate_coefficient(const Coefficient &coefficient_function); - /** * \brief Compute the diagonal of this operator. */ @@ -111,8 +80,6 @@ class matrixFreeOperator LinearAlgebra::distributed::Vector &dst, const unsigned int &dummy, const std::pair &cell_range) const; - - Table<2, VectorizedArray> coefficient; }; template @@ -124,29 +91,9 @@ template void matrixFreeOperator::clear() { - coefficient.reinit(0, 0); MatrixFreeOperators::Base>::clear(); } -template -void -matrixFreeOperator::evaluate_coefficient( - const Coefficient &coefficient_function) -{ - const unsigned int n_cells = this->data->n_cell_batches(); - FEEvaluation phi(*this->data); - - coefficient.reinit(n_cells, phi.n_q_points); - for (unsigned int cell = 0; cell < n_cells; ++cell) - { - phi.reinit(cell); - for (const unsigned int q : phi.quadrature_point_indices()) - { - coefficient(cell, q) = coefficient_function.value(phi.quadrature_point(q)); - } - } -} - template void matrixFreeOperator::local_apply( diff --git a/include/core/temp_test.h b/include/core/temp_test.h index 04396626..a7da695d 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -135,8 +135,6 @@ LaplaceProblem::setup_system() system_matrix.initialize(system_mf_storage); } - system_matrix.evaluate_coefficient(Coefficient()); - system_matrix.initialize_dof_vector(solution); system_matrix.initialize_dof_vector(system_rhs); } @@ -181,7 +179,6 @@ LaplaceProblem::setup_system() additional_data); mg_matrices[level].initialize(mg_mf_storage_level, mg_constrained_dofs, level); - mg_matrices[level].evaluate_coefficient(Coefficient()); } } setup_time += time.wall_time(); From 34fdb65f09297f466f017474bd4a21c4d77568f2 Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 15:41:36 -0500 Subject: [PATCH 05/23] remove some more stuff from step-37 --- include/core/temp_test.h | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/include/core/temp_test.h b/include/core/temp_test.h index a7da695d..18901736 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -335,22 +335,13 @@ LaplaceProblem::run() << std::endl; } - for (unsigned int cycle = 0; cycle < 9 - dim; ++cycle) - { - pcout << "Cycle " << cycle << std::endl; + GridGenerator::hyper_cube(triangulation, 0.0, 1.0); + triangulation.refine_global(6); - if (cycle == 0) - { - GridGenerator::hyper_cube(triangulation, 0., 1.); - triangulation.refine_global(3 - dim); - } - triangulation.refine_global(1); - setup_system(); - assemble_rhs(); - solve(); - output_results(cycle); - pcout << std::endl; - }; + setup_system(); + assemble_rhs(); + solve(); + output_results(0); } #endif \ No newline at end of file From 298799f6488b7efedda2d5b0711f33b861e9bc82 Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 16:02:19 -0500 Subject: [PATCH 06/23] Basic conditional ostream class --- include/core/conditional_ostreams.h | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 include/core/conditional_ostreams.h diff --git a/include/core/conditional_ostreams.h b/include/core/conditional_ostreams.h new file mode 100644 index 00000000..ed27efbc --- /dev/null +++ b/include/core/conditional_ostreams.h @@ -0,0 +1,47 @@ +#ifndef CONDITIONAL_OSTREAMS_H_ +#define CONDITIONAL_OSTREAMS_H_ + +#include +#include + +#include + +/** + * \brief A class that allows printing to different output streams that are classified + * based on their verbosity. For now, this consists of two stream the release and debug. + * The debug stream provides more information that may be useful when debugging. + */ +class conditionalOStreams +{ +public: + /** + * \brief Constructor. + */ + conditionalOStreams(); + + /** + * \brief Generic parallel output stream. Used for essential information in release and + * debug mode. + */ + static const dealii::ConditionalOStream pout_base; + + /** + * \brief Verbose parallel output stream. Used for additional information in debug mode. + */ + static const dealii::ConditionalOStream pout_verbose; +}; + +// NOLINTBEGIN +const dealii::ConditionalOStream conditionalOStreams::pout_base( + std::cout, + dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0); + +const dealii::ConditionalOStream conditionalOStreams::pout_verbose( + std::cout, +#ifndef DEBUG + false && +#endif + dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0); +// NOLINTEND + +#endif \ No newline at end of file From f0f68f6fa6a1d16fa5502f4363be76cf0627cecc Mon Sep 17 00:00:00 2001 From: landinjm Date: Tue, 14 Jan 2025 17:23:05 -0500 Subject: [PATCH 07/23] Adding std::function to variableContainer --- include/core/matrix_free_operator.h | 71 ++++------------ include/core/variableContainer.h | 122 ++++++++++++++++++++++------ src/core/variableContainer.cc | 121 --------------------------- 3 files changed, 115 insertions(+), 199 deletions(-) diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index 9ea72d58..113915d4 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -105,30 +105,16 @@ matrixFreeOperator::local_apply( // Constructor for FEEvaluation objects variableContainer variable_list(data); - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + // Initialize, evaluate, and submit based on user function. + variable_list.eval_local_operator( + [this](variableContainer &var_list, + const Point> &q_point_loc) { - // Initialize, read DOFs, and set evaulation flags for each variable - variable_list.reinit_and_eval(src, cell); - - // Number of quadrature points - unsigned int n_q_points = variable_list.get_num_q_points(); - - for (unsigned int q = 0; q < n_q_points; ++q) - { - // Set the quadrature point - variable_list.q_point = q; - - // Grab the quadrature point location - Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - nonexplicit_RHS(variable_list, q_point_loc); - } - - // Integrate and add to global vector dst - variable_list.integrate_and_distribute(dst); - } + this->nonexplicit_RHS(var_list, q_point_loc); + }, + dst, + src, + cell_range); } template @@ -193,37 +179,16 @@ matrixFreeOperator::local_compute_diagonal( // Constructor for FEEvaluation objects variableContainer variable_list(data); - variable_list.init_diagonal(field_index); - - for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + // Initialize, evaluate, and submit diagonal based on user function. + variable_list.eval_local_diagonal( + [this](variableContainer &var_list, + const Point> &q_point_loc) { - variable_list.reinit_cell(cell); - - for (unsigned int i = 0; i < variable_list.n_dofs_per_cell; ++i) - { - variable_list.reinit_and_eval_diagonal(field_index, i); - - // Number of quadrature points - unsigned int n_q_points = variable_list.get_num_q_points(); - - for (unsigned int q = 0; q < n_q_points; ++q) - { - // Set the quadrature point - variable_list.q_point = q; - - // Grab the quadrature point location - Point> q_point_loc = - variable_list.get_q_point_location(); - - // Calculate the residuals - nonexplicit_RHS(variable_list, q_point_loc); - } - - variable_list.integrate_and_assemble_local_diagonal(field_index, i); - } - - variable_list.distribute_diagonal(dst, field_index); - } + this->nonexplicit_RHS(var_list, q_point_loc); + }, + dst, + cell_range, + field_index); } #endif \ No newline at end of file diff --git a/include/core/variableContainer.h b/include/core/variableContainer.h index 491edfb7..10d402ce 100644 --- a/include/core/variableContainer.h +++ b/include/core/variableContainer.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -71,37 +72,108 @@ class variableContainer integrate_and_distribute(dealii::LinearAlgebra::distributed::Vector &dst); /** - * \brief Initialize the `AlignedVector` for the diagonal based on the DoFs per cell. - * Additionally, assign `n_dofs_per_cell` based on the current field index. + * \brief TODO: Add comments */ void - init_diagonal(unsigned int global_var_index); + eval_local_operator( + const std::function> &)> + &func, + dealii::LinearAlgebra::distributed::Vector &dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) + { + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + // Initialize, read DOFs, and set evaulation flags for each variable + reinit_and_eval(src, cell); + + // Number of quadrature points + unsigned int n_q_points = get_num_q_points(); + + for (unsigned int q = 0; q < n_q_points; ++q) + { + // Set the quadrature point + q_point = q; + + // Grab the quadrature point location + Point> q_point_loc = get_q_point_location(); + + // Calculate the residuals + func(*this, q_point_loc); + } + + // Integrate and add to global vector dst + integrate_and_distribute(dst); + } + }; /** - * \brief Initialize the operation ptr to the cell for all field indices. + * \brief TODO: Add comments */ void - reinit_cell(unsigned int cell); - - /** - * \brief Submit the DoFs for the diagonal identity matrix and evaluate based on the - * evaluation flags. - */ - void - reinit_and_eval_diagonal(unsigned int global_var_index, unsigned int i); - - /** - * \brief Integrate the residuals and assemble the local diagonal - */ - void - integrate_and_assemble_local_diagonal(unsigned int global_var_index, unsigned int i); - - /** - * \brief Distribute the diagonal from local to global. - */ - void - distribute_diagonal(dealii::LinearAlgebra::distributed::Vector &dst, - unsigned int global_var_index); + eval_local_diagonal( + const std::function> &)> + &func, + dealii::LinearAlgebra::distributed::Vector &dst, + const std::pair &cell_range, + const unsigned int &global_var_index) + { + const auto &var_info = varInfoList[global_var_index]; + + AssertThrow(var_info.var_type != fieldType::VECTOR, + FeatureNotImplemented("Vector multigrid")); + + auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); + + n_dofs_per_cell = scalar_FEEval_ptr->dofs_per_cell; + diagonal = std::make_unique>>( + n_dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + scalar_FEEval_ptr->reinit(cell); + + for (unsigned int i = 0; i < n_dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < n_dofs_per_cell; ++j) + { + scalar_FEEval_ptr->submit_dof_value(dealii::VectorizedArray(), j); + } + scalar_FEEval_ptr->submit_dof_value(dealii::make_vectorized_array( + 1.0), + i); + + scalar_FEEval_ptr->evaluate(var_info.evaluation_flags); + + // Number of quadrature points + unsigned int n_q_points = get_num_q_points(); + + for (unsigned int q = 0; q < n_q_points; ++q) + { + // Set the quadrature point + q_point = q; + + // Grab the quadrature point location + dealii::Point> q_point_loc = + get_q_point_location(); + + // Calculate the residuals + func(*this, q_point_loc); + } + + scalar_FEEval_ptr->integrate(var_info.residual_flags); + (*diagonal)[i] = scalar_FEEval_ptr->get_dof_value(i); + } + + for (unsigned int i = 0; i < n_dofs_per_cell; ++i) + { + scalar_FEEval_ptr->submit_dof_value((*diagonal)[i], i); + } + scalar_FEEval_ptr->distribute_local_to_global(dst); + } + }; // The quadrature point index, a method to get the number of quadrature points // per cell, and a method to get the xyz coordinates for the quadrature point diff --git a/src/core/variableContainer.cc b/src/core/variableContainer.cc index 21af241c..5e2afaa7 100644 --- a/src/core/variableContainer.cc +++ b/src/core/variableContainer.cc @@ -143,127 +143,6 @@ variableContainer::integrate_and_distribute( } } -template -void -variableContainer::init_diagonal(unsigned int global_var_index) -{ - const auto &var_info = varInfoList[global_var_index]; - - if (var_info.var_type == fieldType::SCALAR) - { - n_dofs_per_cell = scalar_vars_map.at(global_var_index)->dofs_per_cell; - } - else if (var_info.var_type == fieldType::VECTOR) - { - n_dofs_per_cell = vector_vars_map.at(global_var_index)->dofs_per_cell; - } - - diagonal = std::make_unique>>( - n_dofs_per_cell); -} - -template -void -variableContainer::reinit_cell(unsigned int cell) -{ - for (unsigned int i = 0; i < num_var; i++) - { - const auto &var_info = varInfoList[i]; - - const unsigned int var_index = var_info.global_var_index; - - if (var_info.var_type == fieldType::SCALAR) - { - scalar_vars_map.at(var_index).get()->reinit(cell); - } - else if (var_info.var_type == fieldType::VECTOR) - { - vector_vars_map.at(var_index).get()->reinit(cell); - } - } -} - -template -void -variableContainer::reinit_and_eval_diagonal( - unsigned int global_var_index, - unsigned int i) -{ - const auto &var_info = varInfoList[global_var_index]; - - if (var_info.var_type == fieldType::SCALAR) - { - auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); - for (unsigned int j = 0; j < n_dofs_per_cell; ++j) - { - scalar_FEEval_ptr->submit_dof_value(dealii::VectorizedArray(), j); - } - scalar_FEEval_ptr->submit_dof_value(dealii::make_vectorized_array(1.0), i); - } - else if (var_info.var_type == fieldType::VECTOR) - { - AssertThrow(false, FeatureNotImplemented("Vector multigrid")); - } - - for (unsigned int i = 0; i < num_var; i++) - { - const auto &var_info = varInfoList[i]; - const unsigned int var_index = var_info.global_var_index; - - if (var_info.var_type == fieldType::SCALAR) - { - scalar_vars_map.at(var_index)->evaluate(var_info.evaluation_flags); - } - else if (var_info.var_type == fieldType::VECTOR) - { - vector_vars_map.at(var_index)->evaluate(var_info.evaluation_flags); - } - } -} - -template -void -variableContainer::integrate_and_assemble_local_diagonal( - unsigned int global_var_index, - unsigned int i) -{ - const auto &var_info = varInfoList[global_var_index]; - - if (var_info.var_type == fieldType::SCALAR) - { - auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); - scalar_FEEval_ptr->integrate(var_info.residual_flags); - (*diagonal)[i] = scalar_FEEval_ptr->get_dof_value(i); - } - else if (var_info.var_type == fieldType::VECTOR) - { - AssertThrow(false, FeatureNotImplemented("Vector multigrid")); - } -} - -template -void -variableContainer::distribute_diagonal( - dealii::LinearAlgebra::distributed::Vector &dst, - unsigned int global_var_index) -{ - const auto &var_info = varInfoList[global_var_index]; - - if (var_info.var_type == fieldType::SCALAR) - { - auto *scalar_FEEval_ptr = scalar_vars_map.at(global_var_index).get(); - for (unsigned int i = 0; i < n_dofs_per_cell; ++i) - { - scalar_FEEval_ptr->submit_dof_value((*diagonal)[i], i); - } - scalar_FEEval_ptr->distribute_local_to_global(dst); - } - else if (var_info.var_type == fieldType::VECTOR) - { - AssertThrow(false, FeatureNotImplemented("Vector multigrid")); - } -} - template dealii::VectorizedArray variableContainer::get_scalar_value( From 7a2e97a3ad9ee580e57695669bbffdf0c8a04595 Mon Sep 17 00:00:00 2001 From: landinjm Date: Wed, 15 Jan 2025 17:25:42 -0500 Subject: [PATCH 08/23] fix cmake --- src/core/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2c8d5b1b..2cebe02d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,11 +5,7 @@ list(APPEND PRISMS_PF_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/boundary_conditions/vectorBCFunction.cc ${CMAKE_CURRENT_SOURCE_DIR}/initial_conditions/initialConditions.cc ${CMAKE_CURRENT_SOURCE_DIR}/postprocessing/computeIntegral.cc - ${CMAKE_CURRENT_SOURCE_DIR}/postprocessing/postprocessor.cc ${CMAKE_CURRENT_SOURCE_DIR}/refinement/AdaptiveRefinement.cc - ${CMAKE_CURRENT_SOURCE_DIR}/solvers/computeLHS.cc - ${CMAKE_CURRENT_SOURCE_DIR}/solvers/computeRHS.cc - ${CMAKE_CURRENT_SOURCE_DIR}/solvers/setNonlinearEqInitialGuess.cc ${CMAKE_CURRENT_SOURCE_DIR}/solvers/solve.cc ${CMAKE_CURRENT_SOURCE_DIR}/solvers/solveIncrement.cc ${CMAKE_CURRENT_SOURCE_DIR}/solvers/SolverParameters.cc From dc3507f5ad9e79d8f874f1be86b21b1e6d13ed52 Mon Sep 17 00:00:00 2001 From: landinjm Date: Wed, 15 Jan 2025 17:55:39 -0500 Subject: [PATCH 09/23] removing most cases of pcout and deleting timer object. The timer object should be its own class like we do for conditional ostreams. There are still somes cases where std::cout should be replaced with the pout_base of an assertion --- include/core/ParseCommandLineOpts.h | 23 ++--- include/core/matrixFreePDE.h | 8 -- include/core/temp_test.h | 59 ++++++------ include/core/userInputParameters.h | 4 +- .../boundary_conditions/boundaryConditions.cc | 6 +- src/core/checkpoint.cc | 7 +- src/core/init.cc | 39 ++++---- .../initial_conditions/initialConditions.cc | 94 +++++++++++-------- src/core/inputFileReader.cc | 10 +- src/core/invM.cc | 12 ++- src/core/matrixFreePDE.cc | 5 +- src/core/outputResults.cc | 20 ++-- src/core/postprocessing/computeIntegral.cc | 4 - src/core/reinit.cc | 16 ++-- src/core/solvers/solve.cc | 30 ++---- src/core/solvers/solveIncrement.cc | 49 +++++----- src/core/userInputParameters.cc | 73 +++++++------- src/grains/SimplifiedGrainRepresentation.cc | 15 ++- src/grains/reassignGrains.cc | 29 +++--- src/nucleation/nucleation.cc | 10 +- src/utilities/utilities.cc | 6 +- 21 files changed, 236 insertions(+), 283 deletions(-) diff --git a/include/core/ParseCommandLineOpts.h b/include/core/ParseCommandLineOpts.h index bd17defe..063edf2b 100644 --- a/include/core/ParseCommandLineOpts.h +++ b/include/core/ParseCommandLineOpts.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -29,11 +30,8 @@ class ParseCommandLineOpts if (cmdOptionExists("-i")) { parameters_filename = getCmdOption("-i"); - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "Using the input parameter file: " << parameters_filename - << std::endl; - } + conditionalOStreams::pout_base + << "Using the input parameter file: " << parameters_filename << std::endl; } else { @@ -52,11 +50,8 @@ class ParseCommandLineOpts throw("The previous extension .in for the parameters file is no " "longer accepted. Please rename parameters.in as " "parameters.prm"); - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "Using the input parameter file: " << parameters_filename - << std::endl; - } + conditionalOStreams::pout_base + << "Using the input parameter file: " << parameters_filename << std::endl; } else { @@ -72,11 +67,9 @@ class ParseCommandLineOpts if (!ifs_prm && ifs_in) throw("The previous extension .in for the parameters file is no longer " "accepted. Please rename parameters.in as parameters.prm"); - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "Using the input parameter file: " << parameters_filename - << std::endl; - } + + conditionalOStreams::pout_base + << "Using the input parameter file: " << parameters_filename << std::endl; } else { diff --git a/include/core/matrixFreePDE.h b/include/core/matrixFreePDE.h index ff2b744b..d0687cd1 100644 --- a/include/core/matrixFreePDE.h +++ b/include/core/matrixFreePDE.h @@ -111,11 +111,6 @@ class MatrixFreePDE : public Subscriptor void buildFields(); - /** - * \brief Parallel message stream. - */ - ConditionalOStream pcout; - /** * \brief Set the initial condition for all fields. This function is overriden in each * application. @@ -421,9 +416,6 @@ class MatrixFreePDE : public Subscriptor unsigned int currentIncrement, currentOutput, currentCheckpoint, current_grain_reassignment; - /*Timer and logging object*/ - mutable TimerOutput computing_timer; - bool first_integrated_var_output_complete; // Methods and variables for integration diff --git a/include/core/temp_test.h b/include/core/temp_test.h index 18901736..ac5995a9 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -71,9 +72,7 @@ class LaplaceProblem LinearAlgebra::distributed::Vector solution; LinearAlgebra::distributed::Vector system_rhs; - double setup_time {}; - ConditionalOStream pcout; - ConditionalOStream time_details; + double setup_time {}; }; template @@ -84,8 +83,6 @@ LaplaceProblem::LaplaceProblem() parallel::distributed::Triangulation::construct_multigrid_hierarchy) , fe(degree_finite_element) , dof_handler(triangulation) - , pcout(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - , time_details(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) {} template @@ -101,7 +98,8 @@ LaplaceProblem::setup_system() dof_handler.distribute_dofs(fe); dof_handler.distribute_mg_dofs(); - pcout << "Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; + conditionalOStreams::pout_base + << "Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; constraints.clear(); constraints.reinit(dof_handler.locally_owned_dofs(), @@ -115,8 +113,9 @@ LaplaceProblem::setup_system() constraints.close(); } setup_time += time.wall_time(); - time_details << "Distribute DoFs & B.C. (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << 's' << std::endl; + conditionalOStreams::pout_base << "Distribute DoFs & B.C. (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << 's' + << std::endl; time.restart(); { { @@ -139,8 +138,9 @@ LaplaceProblem::setup_system() system_matrix.initialize_dof_vector(system_rhs); } setup_time += time.wall_time(); - time_details << "Setup matrix-free system (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << 's' << std::endl; + conditionalOStreams::pout_base << "Setup matrix-free system (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << 's' + << std::endl; time.restart(); { @@ -182,8 +182,9 @@ LaplaceProblem::setup_system() } } setup_time += time.wall_time(); - time_details << "Setup matrix-free levels (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << 's' << std::endl; + conditionalOStreams::pout_base << "Setup matrix-free levels (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << 's' + << std::endl; } template @@ -208,8 +209,9 @@ LaplaceProblem::assemble_rhs() system_rhs.compress(VectorOperation::add); setup_time += time.wall_time(); - time_details << "Assemble right hand side (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << 's' << std::endl; + conditionalOStreams::pout_base << "Assemble right hand side (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << 's' + << std::endl; } template @@ -220,8 +222,8 @@ LaplaceProblem::solve() MGTransferMatrixFree mg_transfer(mg_constrained_dofs); mg_transfer.build(dof_handler); setup_time += time.wall_time(); - time_details << "MG build transfer time (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << "s\n"; + conditionalOStreams::pout_base << "MG build transfer time (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << "s\n"; time.restart(); using SmootherType = @@ -280,9 +282,10 @@ LaplaceProblem::solve() SolverControl solver_control(100, 1e-12 * system_rhs.l2_norm()); SolverCG> cg(solver_control); setup_time += time.wall_time(); - time_details << "MG build smoother time (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << "s\n"; - pcout << "Total setup time (wall) " << setup_time << "s\n"; + conditionalOStreams::pout_base << "MG build smoother time (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << "s\n"; + conditionalOStreams::pout_base << "Total setup time (wall) " << setup_time + << "s\n"; time.reset(); time.start(); @@ -291,9 +294,10 @@ LaplaceProblem::solve() constraints.distribute(solution); - pcout << "Time solve (" << solver_control.last_step() << " iterations)" - << (solver_control.last_step() < 10 ? " " : " ") << "(CPU/wall) " - << time.cpu_time() << "s/" << time.wall_time() << "s\n"; + conditionalOStreams::pout_base + << "Time solve (" << solver_control.last_step() << " iterations)" + << (solver_control.last_step() < 10 ? " " : " ") << "(CPU/wall) " << time.cpu_time() + << "s/" << time.wall_time() << "s\n"; } template @@ -318,8 +322,8 @@ LaplaceProblem::output_results(unsigned int cycle) const data_out.set_flags(flags); data_out.write_vtu_with_pvtu_record("./", "solution", cycle, MPI_COMM_WORLD, 3); - time_details << "Time write output (CPU/wall) " << time.cpu_time() << "s/" - << time.wall_time() << "s\n"; + conditionalOStreams::pout_base << "Time write output (CPU/wall) " + << time.cpu_time() << "s/" << time.wall_time() << "s\n"; } template @@ -330,9 +334,10 @@ LaplaceProblem::run() const unsigned int n_vect_doubles = VectorizedArray::size(); const unsigned int n_vect_bits = 8 * sizeof(double) * n_vect_doubles; - pcout << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits - << " bits (" << Utilities::System::get_current_vectorization_level() << ')' - << std::endl; + conditionalOStreams::pout_base + << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits + << " bits (" << Utilities::System::get_current_vectorization_level() << ')' + << std::endl; } GridGenerator::hyper_cube(triangulation, 0.0, 1.0); diff --git a/include/core/userInputParameters.h b/include/core/userInputParameters.h index 0d76b339..187a07d5 100644 --- a/include/core/userInputParameters.h +++ b/include/core/userInputParameters.h @@ -445,9 +445,7 @@ class userInputParameters const std::string &elastic_const_symmetry) const; dealii::Tensor<2, 2 * dim - 1 + dim / 3> - getCIJMatrix(const elasticityModel model, - const std::vector &constants, - dealii::ConditionalOStream &pcout) const; + getCIJMatrix(const elasticityModel model, const std::vector &constants) const; // Private nucleation variables std::vector> nucleation_parameters_list; diff --git a/src/core/boundary_conditions/boundaryConditions.cc b/src/core/boundary_conditions/boundaryConditions.cc index 90b55028..75548c32 100644 --- a/src/core/boundary_conditions/boundaryConditions.cc +++ b/src/core/boundary_conditions/boundaryConditions.cc @@ -1,8 +1,7 @@ -// methods to apply boundary conditons - #include #include #include +#include #include // ================================================================================= @@ -236,7 +235,8 @@ MatrixFreePDE::setPeriodicity() } triangulation.add_periodicity(periodicity_vector); - pcout << "periodic facepairs: " << periodicity_vector.size() << std::endl; + conditionalOStreams::pout_base << "periodic facepairs: " << periodicity_vector.size() + << std::endl; } // Set constraints to enforce periodic boundary conditions diff --git a/src/core/checkpoint.cc b/src/core/checkpoint.cc index 096b5b45..ce5cd1ac 100644 --- a/src/core/checkpoint.cc +++ b/src/core/checkpoint.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -15,7 +16,6 @@ template void MatrixFreePDE::save_checkpoint() { - computing_timer.enter_subsection("matrixFreePDE: save_checkpoint"); unsigned int my_id = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); if (my_id == 0) @@ -118,8 +118,7 @@ MatrixFreePDE::save_checkpoint() time_info_file.close(); } - pcout << "*** Checkpoint created! ***\n\n"; - computing_timer.leave_subsection("matrixFreePDE: save_checkpoint"); + conditionalOStreams::pout_base << "*** Checkpoint created! ***\n\n"; } // Load from a previously created checkpoint @@ -132,7 +131,7 @@ MatrixFreePDE::load_checkpoint_triangulation() verify_checkpoint_file_exists("restart.mesh"); verify_checkpoint_file_exists("restart.mesh.info"); - pcout << "\n*** Resuming from a checkpoint! ***\n\n"; + conditionalOStreams::pout_base << "\n*** Resuming from a checkpoint! ***\n\n"; try { diff --git a/src/core/init.cc b/src/core/init.cc index f4fe66c8..2b065e30 100644 --- a/src/core/init.cc +++ b/src/core/init.cc @@ -1,8 +1,7 @@ -// init() method for MatrixFreePDE class - #include #include +#include #include // populate with fields and setup matrix free system @@ -10,11 +9,9 @@ template void MatrixFreePDE::init() { - computing_timer.enter_subsection("matrixFreePDE: initialization"); - // creating mesh - pcout << "creating problem mesh...\n"; + conditionalOStreams::pout_base << "creating problem mesh...\n"; // Create the coarse mesh and mark the boundaries create_triangulation(triangulation); @@ -37,18 +34,21 @@ MatrixFreePDE::init() // elements if (dim < 3) { - pcout << "problem dimensions: " << userInputs.domain_size[0] << "x" - << userInputs.domain_size[1] << "\n"; + conditionalOStreams::pout_base + << "problem dimensions: " << userInputs.domain_size[0] << "x" + << userInputs.domain_size[1] << "\n"; } else { - pcout << "problem dimensions: " << userInputs.domain_size[0] << "x" - << userInputs.domain_size[1] << "x" << userInputs.domain_size[2] << "\n"; + conditionalOStreams::pout_base + << "problem dimensions: " << userInputs.domain_size[0] << "x" + << userInputs.domain_size[1] << "x" << userInputs.domain_size[2] << "\n"; } - pcout << "number of elements: " << triangulation.n_global_active_cells() << "\n\n"; + conditionalOStreams::pout_base + << "number of elements: " << triangulation.n_global_active_cells() << "\n\n"; // Setup system - pcout << "initializing matrix free object\n"; + conditionalOStreams::pout_base << "initializing matrix free object\n"; totalDOFs = 0; for (auto &field : fields) { @@ -82,7 +82,7 @@ MatrixFreePDE::init() var_type.c_str(), (field.type == SCALAR ? "SCALAR" : "VECTOR"), field.name.c_str()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; // Check if any time dependent fields present if (field.pdetype == EXPLICIT_TIME_DEPENDENT) @@ -121,7 +121,7 @@ MatrixFreePDE::init() } else { - pcout << "\nmatrixFreePDE.h: unknown field type\n"; + conditionalOStreams::pout_base << "\nmatrixFreePDE.h: unknown field type\n"; exit(-1); } FESet.push_back(fe); @@ -225,9 +225,9 @@ MatrixFreePDE::init() field.name.c_str(), dof_handler->n_dofs(), constraintsDirichlet->n_constraints()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } - pcout << "total DOF : " << totalDOFs << "\n"; + conditionalOStreams::pout_base << "total DOF : " << totalDOFs << "\n"; // Setup the matrix free object typename MatrixFree::AdditionalData additional_data; @@ -247,7 +247,8 @@ MatrixFreePDE::init() bool dU_vector_init = false; // Setup solution vectors - pcout << "initializing parallel::distributed residual and solution vectors\n"; + conditionalOStreams::pout_base + << "initializing parallel::distributed residual and solution vectors\n"; for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) { dealii::LinearAlgebra::distributed::Vector *U = nullptr; @@ -331,8 +332,6 @@ MatrixFreePDE::init() // reinitializes the system with the new mesh if (!userInputs.resume_from_checkpoint && userInputs.h_adaptivity == true) { - computing_timer.enter_subsection("matrixFreePDE: AMR"); - unsigned int numDoF_preremesh = totalDOFs; for (unsigned int remesh_index = 0; remesh_index < @@ -347,8 +346,6 @@ MatrixFreePDE::init() } numDoF_preremesh = totalDOFs; } - - computing_timer.leave_subsection("matrixFreePDE: AMR"); } // If resuming from a checkpoint, load the proper starting increment and time @@ -359,8 +356,6 @@ MatrixFreePDE::init() // Once the initial triangulation has been set, compute element volume compute_element_volume(); - - computing_timer.leave_subsection("matrixFreePDE: initialization"); } template diff --git a/src/core/initial_conditions/initialConditions.cc b/src/core/initial_conditions/initialConditions.cc index 8a898159..0de683eb 100644 --- a/src/core/initial_conditions/initialConditions.cc +++ b/src/core/initial_conditions/initialConditions.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -100,14 +101,15 @@ MatrixFreePDE::applyInitialConditions() } else { - pcout << "Error in vtk file type: Use either UNSTRUCTURED OR RECTILINEAR\n"; + conditionalOStreams::pout_base + << "Error in vtk file type: Use either UNSTRUCTURED OR RECTILINEAR\n"; abort(); } // new section ends ScalarField &id_field = body.find_scalar_field(userInputs.grain_structure_variable_name); - pcout << "Applying PField initial condition...\n"; + conditionalOStreams::pout_base << "Applying PField initial condition...\n"; VectorTools::interpolate(*dofHandlersSet[scalar_field_index], InitialConditionPField(0, id_field), @@ -124,11 +126,11 @@ MatrixFreePDE::applyInitialConditions() QGaussLobatto quadrature2(degree + 1); FloodFiller flood_filler(*FESet.at(scalar_field_index), quadrature2); - pcout << "Locating the grains...\n"; + conditionalOStreams::pout_base << "Locating the grains...\n"; std::vector> grain_sets; for (unsigned int id = min_id; id < max_id + 1; id++) { - pcout << "Locating grain " << id << "...\n"; + conditionalOStreams::pout_base << "Locating grain " << id << "...\n"; std::vector> grain_sets_single_id; @@ -151,7 +153,8 @@ MatrixFreePDE::applyInitialConditions() grain_sets_single_id.end()); } - pcout << "Generating simplified representations of the grains...\n"; + conditionalOStreams::pout_base + << "Generating simplified representations of the grains...\n"; for (unsigned int g = 0; g < grain_sets.size(); g++) { SimplifiedGrainRepresentation simplified_grain_representation( @@ -159,22 +162,24 @@ MatrixFreePDE::applyInitialConditions() if (dim == 2) { - pcout << "Grain: " << simplified_grain_representation.getGrainId() << " " - << simplified_grain_representation.getOrderParameterId() - << " Center: " << simplified_grain_representation.getCenter()(0) - << " " << simplified_grain_representation.getCenter()(1) - << " Radius: " << simplified_grain_representation.getRadius() - << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representation.getGrainId() << " " + << simplified_grain_representation.getOrderParameterId() + << " Center: " << simplified_grain_representation.getCenter()(0) << " " + << simplified_grain_representation.getCenter()(1) + << " Radius: " << simplified_grain_representation.getRadius() + << std::endl; } else { - pcout << "Grain: " << simplified_grain_representation.getGrainId() << " " - << simplified_grain_representation.getOrderParameterId() - << " Center: " << simplified_grain_representation.getCenter()(0) - << " " << simplified_grain_representation.getCenter()(1) << " " - << simplified_grain_representation.getCenter()(2) - << " Radius: " << simplified_grain_representation.getRadius() - << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representation.getGrainId() << " " + << simplified_grain_representation.getOrderParameterId() + << " Center: " << simplified_grain_representation.getCenter()(0) << " " + << simplified_grain_representation.getCenter()(1) << " " + << simplified_grain_representation.getCenter()(2) + << " Radius: " << simplified_grain_representation.getRadius() + << std::endl; } simplified_grain_representations.push_back(simplified_grain_representation); @@ -193,35 +198,38 @@ MatrixFreePDE::applyInitialConditions() } } - pcout << "Reassigning the grains to new order parameters...\n"; + conditionalOStreams::pout_base + << "Reassigning the grains to new order parameters...\n"; SimplifiedGrainManipulator simplified_grain_manipulator; simplified_grain_manipulator.reassignGrains(simplified_grain_representations, userInputs.buffer_between_grains, userInputs.variables_for_remapping); - pcout << "After reassignment: " << std::endl; + conditionalOStreams::pout_base << "After reassignment: " << std::endl; for (unsigned int g = 0; g < simplified_grain_representations.size(); g++) { if (dim == 2) { - pcout << "Grain: " << simplified_grain_representations.at(g).getGrainId() - << " " << simplified_grain_representations.at(g).getOrderParameterId() - << " Center: " - << simplified_grain_representations.at(g).getCenter()(0) << " " - << simplified_grain_representations.at(g).getCenter()(1) << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representations.at(g).getGrainId() << " " + << simplified_grain_representations.at(g).getOrderParameterId() + << " Center: " << simplified_grain_representations.at(g).getCenter()(0) + << " " << simplified_grain_representations.at(g).getCenter()(1) + << std::endl; } else { - pcout << "Grain: " << simplified_grain_representations.at(g).getGrainId() - << " " << simplified_grain_representations.at(g).getOrderParameterId() - << " Center: " - << simplified_grain_representations.at(g).getCenter()(0) << " " - << simplified_grain_representations.at(g).getCenter()(1) << " " - << simplified_grain_representations.at(g).getCenter()(2) << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representations.at(g).getGrainId() << " " + << simplified_grain_representations.at(g).getOrderParameterId() + << " Center: " << simplified_grain_representations.at(g).getCenter()(0) + << " " << simplified_grain_representations.at(g).getCenter()(1) << " " + << simplified_grain_representations.at(g).getCenter()(2) << std::endl; } } - pcout << "Placing the grains in their new order parameters...\n"; + conditionalOStreams::pout_base + << "Placing the grains in their new order parameters...\n"; OrderParameterRemapper order_parameter_remapper; order_parameter_remapper.remap_from_index_field( simplified_grain_representations, @@ -304,12 +312,12 @@ MatrixFreePDE::applyInitialConditions() } } // Read out unique filenames - if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0 && !file_field_map.empty()) + if (!file_field_map.empty()) { - std::cout << "Unique VTK input files: " << std::endl; + conditionalOStreams::pout_base << "Unique VTK input files: " << std::endl; for (const auto &pair : file_field_map) { - std::cout << pair.first << ", "; + conditionalOStreams::pout_base << pair.first << ", "; } } // Read in each vtk once and apply initial conditions @@ -352,7 +360,8 @@ MatrixFreePDE::applyInitialConditions() } else { - pcout << "Error in vtk file type: Use either UNSTRUCTURED OR RECTILINEAR\n"; + conditionalOStreams::pout_base + << "Error in vtk file type: Use either UNSTRUCTURED OR RECTILINEAR\n"; abort(); } // new section ends @@ -365,8 +374,9 @@ MatrixFreePDE::applyInitialConditions() if (var_attributes.at(index).var_type == SCALAR) { - pcout << "Applying PField initial condition for " - << userInputs.load_field_name[index] << "...\n"; + conditionalOStreams::pout_base << "Applying PField initial condition for " + << userInputs.load_field_name[index] + << "...\n"; VectorTools::interpolate(*dofHandlersSet[index], InitialConditionPField(index, field), *solutionSet[index]); @@ -397,7 +407,8 @@ MatrixFreePDE::applyInitialConditions() { if (userInputs.load_ICs[var_index] == false) { - pcout << "Applying non-PField initial condition...\n"; + conditionalOStreams::pout_base + << "Applying non-PField initial condition...\n"; if (variable.var_type == SCALAR) { @@ -416,8 +427,9 @@ MatrixFreePDE::applyInitialConditions() *solutionSet[var_index]); } } - pcout << "Application of initial conditions for field number " << var_index - << " complete \n"; + conditionalOStreams::pout_base + << "Application of initial conditions for field number " << var_index + << " complete \n"; } } } diff --git a/src/core/inputFileReader.cc b/src/core/inputFileReader.cc index 16129d6f..fe483fc4 100644 --- a/src/core/inputFileReader.cc +++ b/src/core/inputFileReader.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -16,12 +17,9 @@ inputFileReader::inputFileReader(const std::string &input_file_name, model_constant_names = get_model_constant_names(); uint num_constants = model_constant_names.size(); - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "Number of constants: " << num_constants << "\n"; - std::cout << "Number of post-processing variables: " << pp_attributes.size() - << "\n"; - } + conditionalOStreams::pout_base + << "Number of constants: " << num_constants << "\n" + << "Number of post-processing variables: " << pp_attributes.size() << "\n"; // Read in all of the parameters now declare_parameters(); diff --git a/src/core/invM.cc b/src/core/invM.cc index b98f0ae4..231a564d 100644 --- a/src/core/invM.cc +++ b/src/core/invM.cc @@ -1,6 +1,6 @@ -// computeInvM() method for MatrixFreePDE class #include +#include #include // compute inverse of the diagonal mass matrix and store in vector invM @@ -125,8 +125,9 @@ MatrixFreePDE::computeInvM() invMscalar.local_element(k) = 0; } } - pcout << "computed scalar mass matrix (using FE space for field: " - << parabolicScalarFieldIndex << ")\n"; + conditionalOStreams::pout_base + << "computed scalar mass matrix (using FE space for field: " + << parabolicScalarFieldIndex << ")\n"; // Invert vector mass matrix diagonal elements for (unsigned int k = 0; k < invMvector.locally_owned_size(); ++k) @@ -140,8 +141,9 @@ MatrixFreePDE::computeInvM() invMvector.local_element(k) = 0; } } - pcout << "computed vector mass matrix (using FE space for field: " - << parabolicVectorFieldIndex << ")\n"; + conditionalOStreams::pout_base + << "computed vector mass matrix (using FE space for field: " + << parabolicVectorFieldIndex << ")\n"; } template class MatrixFreePDE<2, 1>; diff --git a/src/core/matrixFreePDE.cc b/src/core/matrixFreePDE.cc index c73e7cbe..6fac8afe 100644 --- a/src/core/matrixFreePDE.cc +++ b/src/core/matrixFreePDE.cc @@ -1,12 +1,10 @@ -// constructor and destructor for matrixFreePDE class - +#include #include // constructor template MatrixFreePDE::MatrixFreePDE(userInputParameters _userInputs) : Subscriptor() - , pcout(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) , userInputs(_userInputs) , var_attributes(_userInputs.var_attributes) , pp_attributes(_userInputs.pp_attributes) @@ -21,7 +19,6 @@ MatrixFreePDE::MatrixFreePDE(userInputParameters _userInputs) , currentOutput(0) , currentCheckpoint(0) , current_grain_reassignment(0) - , computing_timer(pcout, TimerOutput::summary, TimerOutput::wall_times) , first_integrated_var_output_complete(false) , AMR(_userInputs, triangulation, diff --git a/src/core/outputResults.cc b/src/core/outputResults.cc index 3ae485dd..5f340455 100644 --- a/src/core/outputResults.cc +++ b/src/core/outputResults.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -10,9 +11,6 @@ template void MatrixFreePDE::outputResults() { - // log time - computing_timer.enter_subsection("matrixFreePDE: output"); - // create DataOut object DataOut data_out; @@ -83,8 +81,9 @@ MatrixFreePDE::outputResults() { double integrated_field = NAN; computeIntegral(integrated_field, pp_index, postProcessedSet); - pcout << "Integrated value of " << pp_variable.name << ": " - << integrated_field << std::endl; + conditionalOStreams::pout_base << "Integrated value of " + << pp_variable.name << ": " + << integrated_field << std::endl; if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) { output_file << "\t" << pp_variable.name << "\t" << integrated_field; @@ -191,7 +190,8 @@ MatrixFreePDE::outputResults() std::ofstream master_output(pvtuFileName); data_out.write_pvtu_record(master_output, filenames); - pcout << "Output written to:" << pvtuFileName << "\n\n"; + conditionalOStreams::pout_base << "Output written to:" << pvtuFileName + << "\n\n"; } } else @@ -202,7 +202,8 @@ MatrixFreePDE::outputResults() std::string svtuFileName = svtuFileNameStream.str(); data_out.write_vtu_in_parallel(svtuFileName, MPI_COMM_WORLD); - pcout << "Output written to:" << svtuFileName << "\n\n"; + conditionalOStreams::pout_base << "Output written to:" << svtuFileName + << "\n\n"; } } else if (userInputs.output_file_type == "vtk") @@ -210,7 +211,7 @@ MatrixFreePDE::outputResults() // Write the results to separate files for each process std::ofstream output(vtuFileName); data_out.write_vtk(output); - pcout << "Output written to:" << vtuFileName << "\n\n"; + conditionalOStreams::pout_base << "Output written to:" << vtuFileName << "\n\n"; } else { @@ -218,9 +219,6 @@ MatrixFreePDE::outputResults() "either \"vtu\" or \"vtk\"\n"; abort(); } - - // log time - computing_timer.leave_subsection("matrixFreePDE: output"); } template class MatrixFreePDE<2, 1>; diff --git a/src/core/postprocessing/computeIntegral.cc b/src/core/postprocessing/computeIntegral.cc index e8b2e5a0..b67bd0c8 100644 --- a/src/core/postprocessing/computeIntegral.cc +++ b/src/core/postprocessing/computeIntegral.cc @@ -39,10 +39,6 @@ MatrixFreePDE::computeIntegral( value = Utilities::MPI::sum(value, MPI_COMM_WORLD); - // if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0){ - // std::cout<<"Integrated field: "< #include // populate with fields and setup matrix free system @@ -7,10 +6,8 @@ template void MatrixFreePDE::reinit() { - computing_timer.enter_subsection("matrixFreePDE: reinitialization"); - // setup system - pcout << "Reinitializing matrix free object\n"; + conditionalOStreams::pout_base << "Reinitializing matrix free object\n"; totalDOFs = 0; for (const auto &field : fields) { @@ -89,9 +86,9 @@ MatrixFreePDE::reinit() field.name.c_str(), dof_handler->n_dofs(), constraintsDirichlet->n_constraints()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } - pcout << "total DOF : " << totalDOFs << "\n"; + conditionalOStreams::pout_base << "total DOF : " << totalDOFs << "\n"; // Setup the matrix free object typename MatrixFree::AdditionalData additional_data; @@ -117,7 +114,8 @@ MatrixFreePDE::reinit() bool dU_vector_init = false; // Setup solution vectors - pcout << "initializing parallel::distributed residual and solution vectors\n"; + conditionalOStreams::pout_base + << "initializing parallel::distributed residual and solution vectors\n"; for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) { dealii::LinearAlgebra::distributed::Vector *U = nullptr; @@ -200,8 +198,6 @@ MatrixFreePDE::reinit() // Once the initial triangulation has been set, compute element volume compute_element_volume(); - - computing_timer.leave_subsection("matrixFreePDE: reinitialization"); } template class MatrixFreePDE<2, 1>; diff --git a/src/core/solvers/solve.cc b/src/core/solvers/solve.cc index 3684c835..0fca4569 100644 --- a/src/core/solvers/solve.cc +++ b/src/core/solvers/solve.cc @@ -1,5 +1,4 @@ -// solve() method for MatrixFreePDE class - +#include #include // solve BVP @@ -7,9 +6,7 @@ template void MatrixFreePDE::solve() { - // log time - computing_timer.enter_subsection("matrixFreePDE: solve"); - pcout << "\nsolving...\n\n"; + conditionalOStreams::pout_base << "\nsolving...\n\n"; // time dependent BVP if (isTimeDependentBVP) @@ -67,9 +64,10 @@ MatrixFreePDE::solve() } // time stepping - pcout << "\nTime stepping parameters: timeStep: " << userInputs.dtValue - << " timeFinal: " << userInputs.finalTime - << " timeIncrements: " << userInputs.totalIncrements << "\n"; + conditionalOStreams::pout_base + << "\nTime stepping parameters: timeStep: " << userInputs.dtValue + << " timeFinal: " << userInputs.finalTime + << " timeIncrements: " << userInputs.totalIncrements << "\n"; // This is the main time-stepping loop for (; currentIncrement <= userInputs.totalIncrements; ++currentIncrement) @@ -78,20 +76,16 @@ MatrixFreePDE::solve() currentTime += userInputs.dtValue; if (currentIncrement % userInputs.skip_print_steps == 0) { - pcout << "\ntime increment:" << currentIncrement - << " time: " << currentTime << "\n"; + conditionalOStreams::pout_base << "\ntime increment:" << currentIncrement + << " time: " << currentTime << "\n"; } // check and perform adaptive mesh refinement if (userInputs.h_adaptivity == true && currentIncrement % userInputs.skip_remeshing_steps == 0) { - computing_timer.enter_subsection("matrixFreePDE: AMR"); - AMR.do_adaptive_refinement(currentIncrement); reinit(); - - computing_timer.leave_subsection("matrixFreePDE: AMR"); } // Update the list of nuclei (if relevant) @@ -119,11 +113,6 @@ MatrixFreePDE::solve() solutionSet[fieldIndex]->update_ghost_values(); } outputResults(); - if (userInputs.print_timing_with_output && - currentIncrement < userInputs.totalIncrements) - { - computing_timer.print_summary(); - } currentOutput++; } @@ -148,9 +137,6 @@ MatrixFreePDE::solve() // output results to file outputResults(); } - - // log time - computing_timer.leave_subsection("matrixFreePDE: solve"); } template class MatrixFreePDE<2, 1>; diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index 8f45354b..c782a77c 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -9,8 +10,6 @@ template void MatrixFreePDE::solveIncrement(bool skip_time_dependent) { - // log time - computing_timer.enter_subsection("matrixFreePDE: solveIncrements"); Timer time; char buffer[200]; @@ -45,7 +44,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) fields[fieldIndex].name.c_str(), solution_L2_norm, residualSet[fieldIndex]->l2_norm()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; if (!numbers::is_finite(solution_L2_norm)) { @@ -53,7 +52,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) sizeof(buffer), "ERROR: field '%s' solution is NAN. exiting.\n\n", fields[fieldIndex].name.c_str()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; exit(-1); } } @@ -93,7 +92,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) fields[fieldIndex].name.c_str(), solutionSet[fieldIndex]->l2_norm(), residualSet[fieldIndex]->l2_norm()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } nonlinear_iteration_converged = @@ -135,7 +134,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) fields[fieldIndex].name.c_str(), solutionSet[fieldIndex]->l2_norm(), residualSet[fieldIndex]->l2_norm()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } // Check to see if this individual variable has converged @@ -168,7 +167,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) currentIncrement, nonlinear_iteration_index, diff); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } if (diff > userInputs.nonlinear_solver_parameters @@ -198,7 +197,7 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) sizeof(buffer), "ERROR: field '%s' solution is NAN. exiting.\n\n", fields[fieldIndex].name.c_str()); - pcout << buffer; + conditionalOStreams::pout_base << buffer; exit(-1); } } @@ -209,10 +208,8 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) if (currentIncrement % userInputs.skip_print_steps == 0) { - pcout << "wall time: " << time.wall_time() << "s\n"; + conditionalOStreams::pout_base << "wall time: " << time.wall_time() << "s\n"; } - // log time - computing_timer.leave_subsection("matrixFreePDE: solveIncrements"); } // Application of boundary conditions @@ -342,10 +339,10 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, } catch (...) { - pcout << "\nWarning: linear solver did not converge as " - "per set tolerances. consider increasing the " - "maximum number of iterations or decreasing the " - "solver tolerance.\n"; + conditionalOStreams::pout_base << "\nWarning: linear solver did not converge as " + "per set tolerances. consider increasing the " + "maximum number of iterations or decreasing the " + "solver tolerance.\n"; } if (var_attributes.at(fieldIndex).is_nonlinear) @@ -387,9 +384,10 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, if (currentIncrement % userInputs.skip_print_steps == 0) { - pcout << " Old residual: " << residual_old - << " Damping Coeff: " << damping_coefficient - << " New Residual: " << residual_new << "\n"; + conditionalOStreams::pout_base + << " Old residual: " << residual_old + << " Damping Coeff: " << damping_coefficient + << " New Residual: " << residual_new << "\n"; } // An improved approach would use the @@ -452,7 +450,7 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, solver_control.tolerance(), solutionSet[fieldIndex]->l2_norm(), dU_norm); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } // Check to see if this individual variable has converged @@ -480,7 +478,7 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, currentIncrement, nonlinear_iteration_index, diff); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } if (diff > @@ -493,10 +491,11 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, else if (diff > userInputs.nonlinear_solver_parameters.getToleranceValue(fieldIndex)) { - pcout << "\nWarning: nonlinear solver did not converge as " - "per set tolerances. consider increasing the " - "maximum number of iterations or decreasing the " - "solver tolerance.\n"; + conditionalOStreams::pout_base + << "\nWarning: nonlinear solver did not converge as " + "per set tolerances. consider increasing the " + "maximum number of iterations or decreasing the " + "solver tolerance.\n"; } } else @@ -543,7 +542,7 @@ MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, solver_control.tolerance(), solutionSet[fieldIndex]->l2_norm(), dU_norm); - pcout << buffer; + conditionalOStreams::pout_base << buffer; } } } diff --git a/src/core/userInputParameters.cc b/src/core/userInputParameters.cc index 0f7fdaf8..a5ce70e9 100644 --- a/src/core/userInputParameters.cc +++ b/src/core/userInputParameters.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -524,15 +525,13 @@ userInputParameters::assign_nonlinear_solve_parameters( } else { - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "PRISMS-PF Warning: Laplace's equation is only used " - "to generate the initial guess for time independent " - "equations. The equation for variable " - << variable.name - << " is not a time independent equation. No initial " - "guess is needed for this equation.\n"; - } + conditionalOStreams::pout_base + << "PRISMS-PF Warning: Laplace's equation is only used " + "to generate the initial guess for time independent " + "equations. The equation for variable " + << variable.name + << " is not a time independent equation. No initial " + "guess is needed for this equation.\n"; } nonlinear_solver_parameters.loadParameters(index, @@ -586,13 +585,12 @@ userInputParameters::assign_output_parameters( if ((output_file_type == "vtk") && (!output_vtu_per_process)) { output_vtu_per_process = true; - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "PRISMS-PF Warning: 'Output file type' given as 'vtk' and " - "'Output separate files per process' given as 'false'. Shared " - "output files are not supported for the vtk output format. " - "Separate files per process will be created.\n"; - } + + conditionalOStreams::pout_base + << "PRISMS-PF Warning: 'Output file type' given as 'vtk' and " + "'Output separate files per process' given as 'false'. Shared " + "output files are not supported for the vtk output format. " + "Separate files per process will be created.\n"; } print_timing_with_output = @@ -1345,34 +1343,29 @@ userInputParameters::get_Cij_tensor(std::vector elastic_constants, } } - dealii::ConditionalOStream pcout(std::cout, - dealii::Utilities::MPI::this_mpi_process( - MPI_COMM_WORLD) == 0); - - return getCIJMatrix(mat_model, elastic_constants, pcout); + return getCIJMatrix(mat_model, elastic_constants); } template dealii::Tensor<2, 2 * dim - 1 + dim / 3> -userInputParameters::getCIJMatrix(const elasticityModel model, - const std::vector &constants, - dealii::ConditionalOStream &pcout) const +userInputParameters::getCIJMatrix(const elasticityModel model, + const std::vector &constants) const { // CIJ.fill(0.0); dealii::Tensor<2, 2 * dim - 1 + dim / 3> CIJ; - pcout << "Reading material model:"; + conditionalOStreams::pout_base << "Reading material model:"; switch (dim) { case 1: { - pcout << " 1D "; + conditionalOStreams::pout_base << " 1D "; // 1D models switch (model) { case ISOTROPIC: { - pcout << " ISOTROPIC \n"; + conditionalOStreams::pout_base << " ISOTROPIC \n"; CIJ[0][0] = constants[0]; break; } @@ -1388,13 +1381,13 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case 2: { - pcout << " 2D "; + conditionalOStreams::pout_base << " 2D "; // 2D models switch (model) { case ISOTROPIC: { - pcout << " ISOTROPIC \n"; + conditionalOStreams::pout_base << " ISOTROPIC \n"; const double E = constants[0]; const double nu = constants[1]; const double mu = E / (2 * (1 + nu)); @@ -1407,7 +1400,7 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case ANISOTROPIC: { - pcout << " ANISOTROPIC \n"; + conditionalOStreams::pout_base << " ANISOTROPIC \n"; CIJ[0][0] = constants[0]; // C11 CIJ[1][1] = constants[1]; // C22 CIJ[2][2] = constants[2]; // C33 @@ -1428,13 +1421,13 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case 3: { - pcout << " 3D "; + conditionalOStreams::pout_base << " 3D "; // 3D models switch (model) { case ISOTROPIC: { - pcout << " ISOTROPIC \n"; + conditionalOStreams::pout_base << " ISOTROPIC \n"; const double E = constants[0]; const double nu = constants[1]; const double mu = E / (2 * (1 + nu)); @@ -1452,7 +1445,7 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case TRANSVERSE: { - pcout << " TRANSVERSE \n"; + conditionalOStreams::pout_base << " TRANSVERSE \n"; CIJ[0][0] = constants[0]; // C11 CIJ[1][1] = constants[0]; // C11 CIJ[2][2] = constants[1]; // C33 @@ -1466,7 +1459,7 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case ORTHOTROPIC: { - pcout << " ORTHOTROPIC \n"; + conditionalOStreams::pout_base << " ORTHOTROPIC \n"; CIJ[0][0] = constants[0]; // C11 CIJ[1][1] = constants[1]; // C22 CIJ[2][2] = constants[2]; // C33 @@ -1480,7 +1473,7 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } case ANISOTROPIC: { - pcout << " ANISOTROPIC \n"; + conditionalOStreams::pout_base << " ANISOTROPIC \n"; CIJ[0][0] = constants[0]; // C11 CIJ[1][1] = constants[1]; // C22 CIJ[2][2] = constants[2]; // C33 @@ -1521,18 +1514,18 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } } // print CIJ to terminal - pcout << "Elasticity matrix (Voigt notation):\n"; + conditionalOStreams::pout_base << "Elasticity matrix (Voigt notation):\n"; constexpr unsigned int voight_matrix_size = 2 * dim - 1 + dim / 3; for (unsigned int i = 0; i < voight_matrix_size; i++) { for (unsigned int j = 0; j < voight_matrix_size; j++) { - pcout << std::setw(8) << std::setprecision(3) << std::scientific << CIJ[i][j] - << " "; + conditionalOStreams::pout_base << std::setw(8) << std::setprecision(3) + << std::scientific << CIJ[i][j] << " "; } - pcout << "\n"; + conditionalOStreams::pout_base << "\n"; } - pcout << "\n"; + conditionalOStreams::pout_base << "\n"; return CIJ; } diff --git a/src/grains/SimplifiedGrainRepresentation.cc b/src/grains/SimplifiedGrainRepresentation.cc index b5e31e65..99f31674 100644 --- a/src/grains/SimplifiedGrainRepresentation.cc +++ b/src/grains/SimplifiedGrainRepresentation.cc @@ -1,3 +1,4 @@ +#include #include // ============================================================================ @@ -174,15 +175,11 @@ SimplifiedGrainManipulator::reassignGrains( if ((sum_radii + 2.0 * buffer_distance > center_distance) and (order_parameter_other == order_parameter_base)) { - if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) - { - std::cout << "Found overlap between grain " - << grain_representations.at(g_base).getGrainId() - << " and grain " - << grain_representations.at(g_other).getGrainId() - << " with order parameter " << order_parameter_base - << std::endl; - } + conditionalOStreams::pout_base + << "Found overlap between grain " + << grain_representations.at(g_base).getGrainId() << " and grain " + << grain_representations.at(g_other).getGrainId() + << " with order parameter " << order_parameter_base << std::endl; grain_representations.at(g_base).setDistanceToNeighbor( center_distance - sum_radii); diff --git a/src/grains/reassignGrains.cc b/src/grains/reassignGrains.cc index 8c09cd2a..c4b068fe 100644 --- a/src/grains/reassignGrains.cc +++ b/src/grains/reassignGrains.cc @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,10 +9,7 @@ template void MatrixFreePDE::reassignGrains() { - // log time - computing_timer.enter_subsection("matrixFreePDE: reassignGrains"); - - pcout << "Reassigning grains...\n"; + conditionalOStreams::pout_base << "Reassigning grains...\n"; // Get the index of the first scalar field (used to get the FE object and // DOFHandler) @@ -71,10 +69,11 @@ MatrixFreePDE::reassignGrains() SimplifiedGrainRepresentation simplified_grain_representation( grain_sets.at(g)); - pcout << "Grain: " << simplified_grain_representation.getGrainId() << " " - << simplified_grain_representation.getOrderParameterId() - << " Center: " << simplified_grain_representation.getCenter()(0) << " " - << simplified_grain_representation.getCenter()(1) << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representation.getGrainId() << " " + << simplified_grain_representation.getOrderParameterId() + << " Center: " << simplified_grain_representation.getCenter()(0) << " " + << simplified_grain_representation.getCenter()(1) << std::endl; simplified_grain_representations.push_back(simplified_grain_representation); } @@ -93,10 +92,11 @@ MatrixFreePDE::reassignGrains() for (unsigned int g = 0; g < this->simplified_grain_representations.size(); g++) { - pcout << "Grain: " << simplified_grain_representations[g].getGrainId() << " " - << simplified_grain_representations[g].getOrderParameterId() - << " Center: " << simplified_grain_representations[g].getCenter()(0) << " " - << simplified_grain_representations[g].getCenter()(1) << std::endl; + conditionalOStreams::pout_base + << "Grain: " << simplified_grain_representations[g].getGrainId() << " " + << simplified_grain_representations[g].getOrderParameterId() + << " Center: " << simplified_grain_representations[g].getCenter()(0) << " " + << simplified_grain_representations[g].getCenter()(1) << std::endl; } OrderParameterRemapper order_parameter_remapper; @@ -105,10 +105,7 @@ MatrixFreePDE::reassignGrains() *dofHandlersSet_nonconst.at(scalar_field_index), FESet.at(scalar_field_index)->dofs_per_cell); - pcout << "Reassigning grains completed.\n\n"; - - // end log - computing_timer.leave_subsection("matrixFreePDE: reassignGrains"); + conditionalOStreams::pout_base << "Reassigning grains completed.\n\n"; } template class MatrixFreePDE<2, 1>; diff --git a/src/nucleation/nucleation.cc b/src/nucleation/nucleation.cc index 55deab9f..f908611d 100644 --- a/src/nucleation/nucleation.cc +++ b/src/nucleation/nucleation.cc @@ -1,6 +1,6 @@ -// Methods in MatrixFreePDE to update the list of nuclei #include #include +#include #include #include #include @@ -23,7 +23,6 @@ MatrixFreePDE::updateNucleiList() userInputs.dtValue * (double) currentIncrement <= userInputs.nucleation_end_time) { - computing_timer.enter_subsection("matrixFreePDE: nucleation"); // Apply constraints for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) { @@ -70,7 +69,6 @@ MatrixFreePDE::updateNucleiList() { refineMeshNearNuclei(new_nuclei); } - computing_timer.leave_subsection("matrixFreePDE: nucleation"); } } } @@ -87,10 +85,12 @@ MatrixFreePDE::getNewNuclei() std::vector> newnuclei; // Get list of prospective new nuclei for the local processor - pcout << "Nucleation attempt for increment " << currentIncrement << "\n"; + conditionalOStreams::pout_base << "Nucleation attempt for increment " + << currentIncrement << "\n"; getLocalNucleiList(newnuclei); - pcout << "nucleation attempt! " << currentTime << " " << currentIncrement << "\n"; + conditionalOStreams::pout_base << "nucleation attempt! " << currentTime << " " + << currentIncrement << "\n"; // Generate global list of new nuclei and resolve conflicts between new nuclei parallelNucleationList new_nuclei_parallel(newnuclei); diff --git a/src/utilities/utilities.cc b/src/utilities/utilities.cc index 81ee5234..1510081b 100644 --- a/src/utilities/utilities.cc +++ b/src/utilities/utilities.cc @@ -1,5 +1,4 @@ -// utility functions for the MatrixFreePDE class - +#include #include // return index of given field name if exists, else throw error @@ -14,7 +13,8 @@ MatrixFreePDE::getFieldIndex(std::string _name) return field.index; } } - pcout << "\nutilities.h: field '" << _name.c_str() << "' not initialized\n"; + conditionalOStreams::pout_base << "\nutilities.h: field '" << _name.c_str() + << "' not initialized\n"; exit(-1); } From 3d9db411c6cfda1e0d5821688b276eda5fe9b3de Mon Sep 17 00:00:00 2001 From: landinjm Date: Wed, 15 Jan 2025 18:24:53 -0500 Subject: [PATCH 10/23] remove header --- include/core/matrixFreePDE.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/core/matrixFreePDE.h b/include/core/matrixFreePDE.h index d0687cd1..07724f42 100644 --- a/include/core/matrixFreePDE.h +++ b/include/core/matrixFreePDE.h @@ -4,7 +4,6 @@ // dealii headers #include #include -#include #include #include #include From a18d07e000be640256208e2d550d8cef48981162 Mon Sep 17 00:00:00 2001 From: landinjm Date: Wed, 15 Jan 2025 23:57:32 -0500 Subject: [PATCH 11/23] missed some stuff --- src/core/solvers/solveIncrement.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index c782a77c..afdd1f64 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -10,8 +10,7 @@ template void MatrixFreePDE::solveIncrement(bool skip_time_dependent) { - Timer time; - char buffer[200]; + char buffer[200]; // Get the RHS of the explicit equations if (hasExplicitEquation && !skip_time_dependent) @@ -205,11 +204,6 @@ MatrixFreePDE::solveIncrement(bool skip_time_dependent) nonlinear_iteration_index++; } } - - if (currentIncrement % userInputs.skip_print_steps == 0) - { - conditionalOStreams::pout_base << "wall time: " << time.wall_time() << "s\n"; - } } // Application of boundary conditions From fe002113e913221a840be71a80f260ffd9f8be43 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 00:11:20 -0500 Subject: [PATCH 12/23] small changes --- include/core/userInputParameters.h | 21 +++++++++------------ src/core/userInputParameters.cc | 6 +++--- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/include/core/userInputParameters.h b/include/core/userInputParameters.h index 187a07d5..fe39424d 100644 --- a/include/core/userInputParameters.h +++ b/include/core/userInputParameters.h @@ -31,7 +31,7 @@ using InputVariant = boost::variant, dealii::Tensor<2, dim>, - dealii::Tensor<2, 2 * dim - 1 + dim / 3>>; + dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>>; enum elasticityModel { @@ -163,7 +163,7 @@ class userInputParameters * * \param constant_name Name of the constant to retrieve. */ - [[nodiscard]] dealii::Tensor<2, 2 * dim - 1 + dim / 3> + [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> get_model_constant_elasticity_tensor(const std::string &constant_name) const { Assert(model_constants.find(constant_name) != model_constants.end(), @@ -172,7 +172,7 @@ class userInputParameters "customPDE.h. The constant that you attempted to access was " + constant_name + ".")); - return boost::get>( + return boost::get>( model_constants.at(constant_name)); }; @@ -304,8 +304,7 @@ class userInputParameters bool evolution_before_nucleation; // Declare later // bool multiple_nuclei_per_order_parameter; - double min_distance_between_nuclei; // Only enforced for nuclei placed during - // the same time step + double min_distance_between_nuclei; double nucleation_order_parameter_cutoff; unsigned int steps_between_nucleation_attempts; double nucleation_start_time; @@ -313,15 +312,13 @@ class userInputParameters // Grain remapping parameters bool grain_remapping_activated; - std::vector variables_for_remapping; // Note: this should be a sorted list + std::vector variables_for_remapping; unsigned int skip_grain_reassignment_steps; double order_parameter_threshold; double buffer_between_grains; - bool load_grain_structure; - std::string load_vtk_file_type; // adding this string to know what type of vtk file you - // want to read, it will be passed to - // initialconditions.cc + bool load_grain_structure; + std::string load_vtk_file_type; double min_radius_for_loading_grains; std::string grain_structure_filename; std::string grain_structure_variable_name; @@ -440,11 +437,11 @@ class userInputParameters InputVariant primitive_model_constant(std::vector &model_constants_strings); - [[nodiscard]] dealii::Tensor<2, 2 * dim - 1 + dim / 3> + [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> get_Cij_tensor(std::vector elastic_constants, const std::string &elastic_const_symmetry) const; - dealii::Tensor<2, 2 * dim - 1 + dim / 3> + dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> getCIJMatrix(const elasticityModel model, const std::vector &constants) const; // Private nucleation variables diff --git a/src/core/userInputParameters.cc b/src/core/userInputParameters.cc index a5ce70e9..78799bc9 100644 --- a/src/core/userInputParameters.cc +++ b/src/core/userInputParameters.cc @@ -1300,7 +1300,7 @@ userInputParameters::load_model_constants( } template -dealii::Tensor<2, 2 * dim - 1 + dim / 3> +dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> userInputParameters::get_Cij_tensor(std::vector elastic_constants, const std::string &elastic_const_symmetry) const { @@ -1347,7 +1347,7 @@ userInputParameters::get_Cij_tensor(std::vector elastic_constants, } template -dealii::Tensor<2, 2 * dim - 1 + dim / 3> +dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> userInputParameters::getCIJMatrix(const elasticityModel model, const std::vector &constants) const { @@ -1515,7 +1515,7 @@ userInputParameters::getCIJMatrix(const elasticityModel model, } // print CIJ to terminal conditionalOStreams::pout_base << "Elasticity matrix (Voigt notation):\n"; - constexpr unsigned int voight_matrix_size = 2 * dim - 1 + dim / 3; + constexpr unsigned int voight_matrix_size = (2 * dim) - 1 + (dim / 3); for (unsigned int i = 0; i < voight_matrix_size; i++) { for (unsigned int j = 0; j < voight_matrix_size; j++) From 5fc0490516bf3897eb34cbc740c95d4df5fd7d04 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 00:19:21 -0500 Subject: [PATCH 13/23] small changes --- applications/main.cc | 4 +- automatic_tests/main.cc | 4 +- ...eCommandLineOpts.h => parse_cmd_options.h} | 40 +++++++++++-------- 3 files changed, 27 insertions(+), 21 deletions(-) rename include/core/{ParseCommandLineOpts.h => parse_cmd_options.h} (75%) diff --git a/applications/main.cc b/applications/main.cc index f5526507..c9fd00bd 100644 --- a/applications/main.cc +++ b/applications/main.cc @@ -5,8 +5,8 @@ #include "core/variableAttributes.h" #include "equations.cc" -#include #include +#include #include // Header file for postprocessing that may or may not exist @@ -38,7 +38,7 @@ main(int argc, char **argv) std::string parameters_filename; try { - ParseCommandLineOpts cli_options(argc, argv); + parseCMDOptions cli_options(argc, argv); parameters_filename = cli_options.getParametersFilename(); } catch (const char *msg) diff --git a/automatic_tests/main.cc b/automatic_tests/main.cc index f5526507..c9fd00bd 100644 --- a/automatic_tests/main.cc +++ b/automatic_tests/main.cc @@ -5,8 +5,8 @@ #include "core/variableAttributes.h" #include "equations.cc" -#include #include +#include #include // Header file for postprocessing that may or may not exist @@ -38,7 +38,7 @@ main(int argc, char **argv) std::string parameters_filename; try { - ParseCommandLineOpts cli_options(argc, argv); + parseCMDOptions cli_options(argc, argv); parameters_filename = cli_options.getParametersFilename(); } catch (const char *msg) diff --git a/include/core/ParseCommandLineOpts.h b/include/core/parse_cmd_options.h similarity index 75% rename from include/core/ParseCommandLineOpts.h rename to include/core/parse_cmd_options.h index 063edf2b..2cc9bfa4 100644 --- a/include/core/ParseCommandLineOpts.h +++ b/include/core/parse_cmd_options.h @@ -1,5 +1,5 @@ -#ifndef INCLUDE_PARSECOMMANDLINE_OPTS_H_ -#define INCLUDE_PARSECOMMANDLINE_OPTS_H_ +#ifndef PARSE_CMD_OPTIONS_H_ +#define PARSE_CMD_OPTIONS_H_ #include @@ -10,14 +10,16 @@ #include #include -class ParseCommandLineOpts +class parseCMDOptions { public: - ParseCommandLineOpts(int &_argc, char **argv) + parseCMDOptions(int &_argc, char **argv) + : argc(_argc) { - argc = _argc; for (int i = 1; i < argc; ++i) - tokens.push_back(std::string(argv[i])); + { + tokens.emplace_back(argv[i]); + } } std::string @@ -31,7 +33,7 @@ class ParseCommandLineOpts { parameters_filename = getCmdOption("-i"); conditionalOStreams::pout_base - << "Using the input parameter file: " << parameters_filename << std::endl; + << "Using the input parameter file: " << parameters_filename << '\n'; } else { @@ -47,11 +49,13 @@ class ParseCommandLineOpts std::ifstream ifs_prm(parameters_filename); std::ifstream ifs_in("parameters.in"); if (!ifs_prm && ifs_in) - throw("The previous extension .in for the parameters file is no " - "longer accepted. Please rename parameters.in as " - "parameters.prm"); + { + throw("The previous extension .in for the parameters file is no " + "longer accepted. Please rename parameters.in as " + "parameters.prm"); + } conditionalOStreams::pout_base - << "Using the input parameter file: " << parameters_filename << std::endl; + << "Using the input parameter file: " << parameters_filename << '\n'; } else { @@ -65,11 +69,13 @@ class ParseCommandLineOpts std::ifstream ifs_prm(parameters_filename); std::ifstream ifs_in("parameters.in"); if (!ifs_prm && ifs_in) - throw("The previous extension .in for the parameters file is no longer " - "accepted. Please rename parameters.in as parameters.prm"); + { + throw("The previous extension .in for the parameters file is no longer " + "accepted. Please rename parameters.in as parameters.prm"); + } conditionalOStreams::pout_base - << "Using the input parameter file: " << parameters_filename << std::endl; + << "Using the input parameter file: " << parameters_filename << '\n'; } else { @@ -84,7 +90,7 @@ class ParseCommandLineOpts int argc; std::vector tokens; - const std::string & + [[nodiscard]] const std::string & getCmdOption(const std::string &option) const { std::vector::const_iterator itr; @@ -93,11 +99,11 @@ class ParseCommandLineOpts { return *itr; } - static const std::string empty_string(""); + static const std::string empty_string; return empty_string; } - bool + [[nodiscard]] bool cmdOptionExists(const std::string &option) const { return std::find(tokens.begin(), tokens.end(), option) != tokens.end(); From 782a6256196d0cb61d204f6897aa54545e973e30 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 11:17:02 -0500 Subject: [PATCH 14/23] small changes --- .clang-tidy | 2 ++ applications/multigrid_test/custom_PDE.h | 20 ++++++++++++++++++++ include/core/temp_test.h | 11 +++++------ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 applications/multigrid_test/custom_PDE.h diff --git a/.clang-tidy b/.clang-tidy index 6919bf1b..03b6ebb1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -9,6 +9,7 @@ Checks: > cppcoreguidelines-*, -cppcoreguidelines-avoid-const-or-ref-data-members, -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-avoid-magic-numbers, hicpp-*, misc-*, -misc-non-private-member-variables-in-classes, @@ -19,5 +20,6 @@ Checks: > readability-*, -readability-else-after-return, -readability-identifier-length, + -readability-magic-numbers, WarningsAsErrors: '*' diff --git a/applications/multigrid_test/custom_PDE.h b/applications/multigrid_test/custom_PDE.h new file mode 100644 index 00000000..81ae379a --- /dev/null +++ b/applications/multigrid_test/custom_PDE.h @@ -0,0 +1,20 @@ +#include + +using namespace dealii; + +/** + * \brief This is a derived class of `matrixFreeOperator` where the user implements their + * PDEs. + * + * \tparam dim The number of dimensions in the problem. + * \tparam degree The polynomial degree of the shape functions. + * \tparam number Datatype to use. Either double or float. + */ +template +class customPDE : public matrixFreeOperator +{ + /** + * \brief Constructor. + */ + customPDE(); +}; \ No newline at end of file diff --git a/include/core/temp_test.h b/include/core/temp_test.h index ac5995a9..a677df4d 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -115,7 +115,7 @@ LaplaceProblem::setup_system() setup_time += time.wall_time(); conditionalOStreams::pout_base << "Distribute DoFs & B.C. (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' - << std::endl; + << '\n'; time.restart(); { { @@ -140,7 +140,7 @@ LaplaceProblem::setup_system() setup_time += time.wall_time(); conditionalOStreams::pout_base << "Setup matrix-free system (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' - << std::endl; + << '\n'; time.restart(); { @@ -184,7 +184,7 @@ LaplaceProblem::setup_system() setup_time += time.wall_time(); conditionalOStreams::pout_base << "Setup matrix-free levels (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' - << std::endl; + << '\n'; } template @@ -211,7 +211,7 @@ LaplaceProblem::assemble_rhs() setup_time += time.wall_time(); conditionalOStreams::pout_base << "Assemble right hand side (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' - << std::endl; + << '\n'; } template @@ -336,8 +336,7 @@ LaplaceProblem::run() conditionalOStreams::pout_base << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits - << " bits (" << Utilities::System::get_current_vectorization_level() << ')' - << std::endl; + << " bits (" << Utilities::System::get_current_vectorization_level() << ')' << '\n'; } GridGenerator::hyper_cube(triangulation, 0.0, 1.0); From 47919cdf03d37250e15523a600484dbba664b9b5 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 12:05:57 -0500 Subject: [PATCH 15/23] small changes --- include/core/matrix_free_operator.h | 4 ++-- include/core/temp_test.h | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index 113915d4..0f2e5dc7 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -49,9 +49,9 @@ class matrixFreeOperator protected: /** - * \brief User-implemented PDE. TODO + * \brief User-implemented PDE. */ - void + virtual void nonexplicit_RHS(variableContainer &variable_list, const Point> &q_point_loc) const; diff --git a/include/core/temp_test.h b/include/core/temp_test.h index a677df4d..d0d87949 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -30,11 +30,10 @@ #include #include -#include #include -const unsigned int degree_finite_element = 2; -const unsigned int dimension = 3; +const unsigned int degree = 2; +const unsigned int dimension = 3; template class LaplaceProblem @@ -62,11 +61,11 @@ class LaplaceProblem MappingQ1 mapping; AffineConstraints constraints; - using SystemMatrixType = matrixFreeOperator; + using SystemMatrixType = matrixFreeOperator; SystemMatrixType system_matrix; MGConstrainedDoFs mg_constrained_dofs; - using LevelMatrixType = matrixFreeOperator; + using LevelMatrixType = matrixFreeOperator; MGLevelObject mg_matrices; LinearAlgebra::distributed::Vector solution; @@ -81,7 +80,7 @@ LaplaceProblem::LaplaceProblem() MPI_COMM_WORLD, Triangulation::limit_level_difference_at_vertices, parallel::distributed::Triangulation::construct_multigrid_hierarchy) - , fe(degree_finite_element) + , fe(degree) , dof_handler(triangulation) {} @@ -194,7 +193,7 @@ LaplaceProblem::assemble_rhs() Timer time; system_rhs = 0; - FEEvaluation phi(*system_matrix.get_matrix_free()); + FEEvaluation phi(*system_matrix.get_matrix_free()); for (unsigned int cell = 0; cell < system_matrix.get_matrix_free()->n_cell_batches(); ++cell) { From e427dd7e66483409eec8f8f06e909be916eb7c5b Mon Sep 17 00:00:00 2001 From: Xander <102053371+fractalsbyx@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:49:38 -0500 Subject: [PATCH 16/23] reorganize solveIncrement Broke solveIncrement into four smaller sections: 1. Aux vars that are not nonlinear (sequential) 2. Explicit vars (concurrent) 3. Linear solves (sequential) 4. Nonlinear solve (concurrent) TODO/NOTES: I broke the skip_time_dependent thing. Changes not yet propogated. Need some documentation. Prefer to pass var_index into solver rather than use member variable currentFieldIndex. Maybe removed need for member variable currentIncrement. computeExplicitRHS-like functions are commented with "HERE" to be replaced --- include/core/matrixFreePDE.h | 64 ++- src/core/solvers/solveIncrement.cc | 855 ++++++++++++++--------------- 2 files changed, 464 insertions(+), 455 deletions(-) diff --git a/include/core/matrixFreePDE.h b/include/core/matrixFreePDE.h index 07724f42..75c70940 100644 --- a/include/core/matrixFreePDE.h +++ b/include/core/matrixFreePDE.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include @@ -171,6 +173,10 @@ class MatrixFreePDE : public Subscriptor std::vector> simplified_grain_representations; + // =========================================================================== + // METHODS FOR SOLVING + // =========================================================================== + /** * Method to solve each time increment of a time-dependent problem. For * time-independent problems this method is called only once. This method @@ -179,7 +185,51 @@ class MatrixFreePDE : public Subscriptor * problems, Implicit (matrix-free) solver for Elliptic problems. */ virtual void - solveIncrement(bool skip_time_dependent); + solveIncrement(uint current_increment, bool skip_time_dependent); + + void + linearSolveOnce(unsigned int var_index, SolverControl &solver_control); + void + auxiliaryOnce(unsigned int var_index, uint current_increment); + bool + nonlinearIncrement(unsigned int var_index, + SolverControl &solver_control, + uint current_increment); + bool + auxiliaryIncrement(unsigned int var_index, uint current_increment); + void + print_explicit_update(uint var_index, uint current_increment); + void + print_linear_update(uint var_index, + uint current_increment, + SolverControl &solver_control); + void + print_nonlinear_update(uint var_index, uint current_increment); + void + print_nonlinear_status(uint var_index, + uint current_increment, + uint nonlinear_iteration_index, + double diff); + + /*Method to compute an explicit timestep*/ + void + updateExplicitSolution(unsigned int var_index); + + void + updateLinearSolution(unsigned int var_index); + + /*Method to compute an implicit timestep*/ + bool + updateImplicitSolution(unsigned int fieldIndex, unsigned int nonlinear_iteration_index); + + /*Method to apply boundary conditions*/ + void + applyBCs(unsigned int var_index); + + // =========================================================================== + // + // =========================================================================== + /* Method to write solution fields to vtu and pvtu (parallel) files. * * This method can be enabled/disabled by setting the flag writeOutput to @@ -263,18 +313,6 @@ class MatrixFreePDE : public Subscriptor void computeInvM(); - /*Method to compute an explicit timestep*/ - void - updateExplicitSolution(unsigned int fieldIndex); - - /*Method to compute an implicit timestep*/ - bool - updateImplicitSolution(unsigned int fieldIndex, unsigned int nonlinear_iteration_index); - - /*Method to apply boundary conditions*/ - void - applyBCs(unsigned int fieldIndex); - /** * \brief Compute element volume for the triangulation */ diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index afdd1f64..a6564324 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -1,218 +1,354 @@ #include +#include + +#include "core/typeEnums.h" #include #include #include #include +#include // solve each time increment template void -MatrixFreePDE::solveIncrement(bool skip_time_dependent) +MatrixFreePDE::solveIncrement(uint current_increment, + bool skip_time_dependent) { + // log time + computing_timer.enter_subsection("matrixFreePDE: solveIncrements"); char buffer[200]; - // Get the RHS of the explicit equations - if (hasExplicitEquation && !skip_time_dependent) + // Solve and update auxiliary fields that are not nonlinear (sequentially) + for (const auto &[var_index, variable] : var_attributes) { - // computeExplicitRHS(); + if (variable.eq_type == AUXILIARY && !variable.is_nonlinear) + { + auxiliaryOnce(var_index); + } } - // solve for each field - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // Solve and update explicit fields (concurrently) + // if (hasExplicitEquation && !skip_time_dependent) + computeExplicitRHS(); // HERE + for (const auto &[var_index, variable] : var_attributes) { - currentFieldIndex = fieldIndex; // Used in computeLHS() + if (variable.eq_type == EXPLICIT_TIME_DEPENDENT) + { + updateExplicitSolution(var_index); + // Apply Boundary conditions + applyBCs(var_index); + print_explicit_update(var_index, current_increment); + } + } - // Parabolic (first order derivatives in time) fields - if (fields[fieldIndex].pdetype == EXPLICIT_TIME_DEPENDENT && !skip_time_dependent) + // Solve and update linear-equation fields (sequentially) + for (const auto &[var_index, variable] : var_attributes) + { + if (variable.eq_type != EXPLICIT_TIME_DEPENDENT && !variable.is_nonlinear) { - updateExplicitSolution(fieldIndex); + SolverControl solver_control; + compute_nonexplicit_RHS(var_index); // HERE + linearSolveOnce(var_index, solver_control); // lhs + updateLinearSolution(var_index, solver_control); + print_linear_update(var_index, solver_control); // Apply Boundary conditions - applyBCs(fieldIndex); + applyBCs(var_index); + print_update(var_index, current_increment); + } + } - // Print update to screen and confirm that solution isn't nan - if (currentIncrement % userInputs.skip_print_steps == 0) + // Solve and update nonlinear-equation fields (concurrently) + bool nonlinear_converged = false; + uint nonlinear_iteration_index = 0; + uint max_nonlinear_iterations = + userInputs.nonlinear_solver_parameters.getMaxIterations(); + SolverControl solver_control; + while (!nonlinear_converged && nonlinear_iteration_index < max_nonlinear_iterations) + { + nonlinear_converged = true; + for (const auto &[var_index, variable] : var_attributes) + { + if (!variable.is_nonlinear) + { + continue; + } + if (variable.eq_type == TIME_INDEPENDENT) + { + print_nonlinear_update(var_index, current_increment); + if (!nonlinearIncrement(var_index, solver_control)) + { + nonlinear_converged = false; + } + // Apply Boundary conditions (could be placed in nonlinearIncrement) + applyBCs(var_index); + } + else if (variable.eq_type == AUXILIARY) + { + if (!auxiliaryIncrement(var_index, solver_control)) + { + nonlinear_converged = false; + } + // Apply Boundary conditions (could be placed in auxiliaryIncrement) + applyBCs(var_index); + } + // check if solution is nan + if (!numbers::is_finite(solutionSet[var_index]->l2_norm())) { - double solution_L2_norm = solutionSet[fieldIndex]->l2_norm(); - snprintf(buffer, sizeof(buffer), - "field '%2s' [explicit solve]: current solution: " - "%12.6e, current residual:%12.6e\n", - fields[fieldIndex].name.c_str(), - solution_L2_norm, - residualSet[fieldIndex]->l2_norm()); + "ERROR: field '%s' solution is NAN. exiting.\n\n", + fields[var_index].name.c_str()); conditionalOStreams::pout_base << buffer; - - if (!numbers::is_finite(solution_L2_norm)) - { - snprintf(buffer, - sizeof(buffer), - "ERROR: field '%s' solution is NAN. exiting.\n\n", - fields[fieldIndex].name.c_str()); - conditionalOStreams::pout_base << buffer; - exit(-1); - } + exit(-1); } } + nonlinear_iteration_index++; + } + if (!nonlinear_converged) + { + conditionalOStreams::pout_base << "\nWarning: nonlinear solver did not converge as " + "per set tolerances. consider increasing the " + "maximum number of iterations or decreasing the " + "solver tolerance.\n"; } + // log time + computing_timer.leave_subsection("matrixFreePDE: solveIncrements"); +} - // Now, update the non-explicit variables - // For the time being, this is just the elliptic equations, but implicit - // parabolic and auxilary equations should also be here - if (hasNonExplicitEquation) +template +void +MatrixFreePDE::linearSolveOnce(unsigned int var_index, + SolverControl &solver_control) +{ + // Apply Dirichlet BC's. This clears the residual where we want to apply Dirichlet BCs, + // otherwise the solver sees a positive residual + constraintsDirichletSet[var_index]->set_zero(*residualSet[var_index]); + + // Grab solver controls + double tol_value = NAN; + if (userInputs.linear_solver_parameters.getToleranceType(var_index) == + ABSOLUTE_RESIDUAL) { - bool nonlinear_iteration_converged = false; - unsigned int nonlinear_iteration_index = 0; + tol_value = userInputs.linear_solver_parameters.getToleranceValue(var_index); + } + else + { + tol_value = userInputs.linear_solver_parameters.getToleranceValue(var_index) * + residualSet[var_index]->l2_norm(); + } + solver_control = + SolverControl(userInputs.linear_solver_parameters.getMaxIterations(var_index), + tol_value); + SolverCG> solver(solver_control); - while (!nonlinear_iteration_converged) + // Solve the linear system + try + { + if (fields[var_index].type == SCALAR) + { + dU_scalar = 0.0; + solver.solve(*this, + dU_scalar, + *residualSet[var_index], + IdentityMatrix(solutionSet[var_index]->size())); + } + else { - nonlinear_iteration_converged = true; + dU_vector = 0.0; + solver.solve(*this, + dU_vector, + *residualSet[var_index], + IdentityMatrix(solutionSet[var_index]->size())); + } + } + catch (...) + { + conditionalOStreams::pout_base << "\nWarning: linear solver did not converge as " + "per set tolerances. consider increasing the " + "maximum number of iterations or decreasing the " + "solver tolerance.\n"; + } +} + +template +void +MatrixFreePDE::auxiliaryOnce(unsigned int var_index, uint current_increment) +{ + computeNonexplicitRHS(var_index); // HERE + updateExplicitSolution(var_index); - // Update residualSet for the non-explicitly updated variables - // computeNonexplicitRHS(); + // Apply Boundary conditions + applyBCs(var_index); - for (const auto &[fieldIndex, variable] : var_attributes) + // Print update to screen + if (current_increment % userInputs.skip_print_steps == 0) + { + char buffer[200]; + snprintf(buffer, + sizeof(buffer), + "field '%2s' [auxiliary solve]: current solution: " + "%12.6e, current residual:%12.6e\n", + fields[var_index].name.c_str(), + solutionSet[var_index]->l2_norm(), + residualSet[var_index]->l2_norm()); + conditionalOStreams::pout_base << buffer; + } +} + +// Nonlinear increment for time-independent fields +template +bool +MatrixFreePDE::nonlinearIncrement(unsigned int var_index, + SolverControl &solver_control, + uint current_increment) +{ + linearSolveOnce(var_index, solver_control); // lhs + + uint nonlinear_iteration_index = 0; + double damping_coefficient = NAN; + if (userInputs.nonlinear_solver_parameters.getBacktrackDampingFlag(var_index)) + { + dealii::LinearAlgebra::distributed::Vector solutionSet_old = + *solutionSet[var_index]; + double residual_old = residualSet[var_index]->l2_norm(); + + damping_coefficient = 1.0; + bool damping_coefficient_found = false; + while (!damping_coefficient_found) + { + if (fields[var_index].type == SCALAR) { - currentFieldIndex = fieldIndex; // Used in computeLHS() + solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); + } + else + { + solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); + } - if ((fields[fieldIndex].pdetype == IMPLICIT_TIME_DEPENDENT && - !skip_time_dependent) || - fields[fieldIndex].pdetype == TIME_INDEPENDENT) - { - if (currentIncrement % userInputs.skip_print_steps == 0 && - variable.is_nonlinear) - { - snprintf(buffer, - sizeof(buffer), - "field '%2s' [nonlinear solve]: current " - "solution: %12.6e, current residual:%12.6e\n", - fields[fieldIndex].name.c_str(), - solutionSet[fieldIndex]->l2_norm(), - residualSet[fieldIndex]->l2_norm()); - conditionalOStreams::pout_base << buffer; - } - - nonlinear_iteration_converged = - updateImplicitSolution(fieldIndex, nonlinear_iteration_index); - - // Apply Boundary conditions - applyBCs(fieldIndex); - } - else if (fields[fieldIndex].pdetype == AUXILIARY) - { - if (variable.is_nonlinear || nonlinear_iteration_index == 0) - { - // If the equation for this field is nonlinear, save the old - // solution - if (variable.is_nonlinear) - { - if (fields[fieldIndex].type == SCALAR) - { - dU_scalar = *solutionSet[fieldIndex]; - } - else - { - dU_vector = *solutionSet[fieldIndex]; - } - } - - updateExplicitSolution(fieldIndex); - - // Apply Boundary conditions - applyBCs(fieldIndex); - - // Print update to screen - if (currentIncrement % userInputs.skip_print_steps == 0) - { - snprintf(buffer, - sizeof(buffer), - "field '%2s' [auxiliary solve]: current solution: " - "%12.6e, current residual:%12.6e\n", - fields[fieldIndex].name.c_str(), - solutionSet[fieldIndex]->l2_norm(), - residualSet[fieldIndex]->l2_norm()); - conditionalOStreams::pout_base << buffer; - } - - // Check to see if this individual variable has converged - if (variable.is_nonlinear) - { - if (userInputs.nonlinear_solver_parameters.getToleranceType( - fieldIndex) == ABSOLUTE_SOLUTION_CHANGE) - { - double diff = NAN; - - if (fields[fieldIndex].type == SCALAR) - { - dU_scalar -= *solutionSet[fieldIndex]; - diff = dU_scalar.l2_norm(); - } - else - { - dU_vector -= *solutionSet[fieldIndex]; - diff = dU_vector.l2_norm(); - } - if (currentIncrement % userInputs.skip_print_steps == 0) - { - snprintf(buffer, - sizeof(buffer), - " field '%2s' [nonlinear solve] current " - "increment: %u, nonlinear " - "iteration: " - "%u, dU: %12.6e\n", - fields[fieldIndex].name.c_str(), - currentIncrement, - nonlinear_iteration_index, - diff); - conditionalOStreams::pout_base << buffer; - } - - if (diff > userInputs.nonlinear_solver_parameters - .getToleranceValue(fieldIndex) && - nonlinear_iteration_index < - userInputs.nonlinear_solver_parameters - .getMaxIterations()) - { - nonlinear_iteration_converged = false; - } - } - else - { - AssertThrow( - false, - FeatureNotImplemented( - "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); - } - } - } - } + computeNonexplicitRHS(); // HERE - // check if solution is nan - if (!numbers::is_finite(solutionSet[fieldIndex]->l2_norm())) + for (const auto &it : *valuesDirichletSet[var_index]) + { + if (residualSet[var_index]->in_local_range(it.first)) { - snprintf(buffer, - sizeof(buffer), - "ERROR: field '%s' solution is NAN. exiting.\n\n", - fields[fieldIndex].name.c_str()); - conditionalOStreams::pout_base << buffer; - exit(-1); + (*residualSet[var_index])(it.first) = 0.0; } } - nonlinear_iteration_index++; + double residual_new = residualSet[var_index]->l2_norm(); + + if (current_increment % userInputs.skip_print_steps == 0) + { + conditionalOStreams::pout_base << "\tOld residual: " << residual_old + << " Damping Coeff: " << damping_coefficient + << " New Residual: " << residual_new << "\n"; + } + + // An improved approach would use the + // Armijo–Goldstein condition to ensure a + // sufficent decrease in the residual. This way is + // just scales the residual. + if ((residual_new < + (residual_old * + userInputs.nonlinear_solver_parameters.getBacktrackResidualDecreaseCoeff( + var_index))) || + damping_coefficient < 1.0e-4) + { + damping_coefficient_found = true; + } + else + { + damping_coefficient *= + userInputs.nonlinear_solver_parameters.getBacktrackStepModifier( + var_index); + *solutionSet[var_index] = solutionSet_old; + } } } + else + { + damping_coefficient = + userInputs.nonlinear_solver_parameters.getDefaultDampingCoefficient(var_index); + + if (fields[var_index].type == SCALAR) + { + solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); + } + else + { + solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); + } + } + + // Print linear???? + print_linear_update(var_index, solver_control); + + // Check to see if this individual variable has converged + bool nonlinear_converged = false; + AssertThrow(userInputs.nonlinear_solver_parameters.getToleranceType(var_index) == + ABSOLUTE_SOLUTION_CHANGE, + FeatureNotImplemented( + "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); + double diff = NAN; + if (fields[var_index].type == SCALAR) + { + diff = dU_scalar.l2_norm(); + } + else + { + diff = dU_vector.l2_norm(); + } + print_nonlinear_status(var_index, current_increment, nonlinear_iteration_index, diff); + return !(diff > userInputs.nonlinear_solver_parameters.getToleranceValue(var_index)); +} + +// Nonlinear increment for auxiliary fields +template +bool +MatrixFreePDE::auxiliaryIncrement(unsigned int var_index, + uint current_increment) +{ + // Save the old solution + if (fields[var_index].type == SCALAR) + { + dU_scalar = *solutionSet[var_index]; + } + else + { + dU_vector = *solutionSet[var_index]; + } + + auxiliaryOnce(var_index); + + // Check to see if this individual variable has converged + AssertThrow(userInputs.nonlinear_solver_parameters.getToleranceType(var_index) == + ABSOLUTE_SOLUTION_CHANGE, + FeatureNotImplemented( + "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); + double diff = NAN; + if (fields[var_index].type == SCALAR) + { + dU_scalar -= *solutionSet[var_index]; + diff = dU_scalar.l2_norm(); + } + else + { + dU_vector -= *solutionSet[var_index]; + diff = dU_vector.l2_norm(); + } + print_nonlinear_update(var_index, current_increment); + return !(diff > userInputs.nonlinear_solver_parameters.getToleranceValue(var_index)); } // Application of boundary conditions template void -MatrixFreePDE::applyBCs(unsigned int fieldIndex) +MatrixFreePDE::applyBCs(unsigned int var_index) { // Add Neumann BCs - if (fields[fieldIndex].hasNeumannBCs) + if (fields[var_index].hasNeumannBCs) { // Currently commented out because it isn't working yet // applyNeumannBCs(); @@ -220,344 +356,179 @@ MatrixFreePDE::applyBCs(unsigned int fieldIndex) // Set the Dirichelet values (hanging node constraints don't need to be distributed // every time step, only at output) - if (fields[fieldIndex].hasDirichletBCs) + if (fields[var_index].hasDirichletBCs) { // Apply non-uniform Dirlichlet_BCs to the current field - if (fields[fieldIndex].hasnonuniformDirichletBCs) + if (fields[var_index].hasnonuniformDirichletBCs) { - DoFHandler *dof_handler = nullptr; - dof_handler = dofHandlersSet_nonconst.at(currentFieldIndex); - IndexSet *locally_relevant_dofs = nullptr; - locally_relevant_dofs = locally_relevant_dofsSet_nonconst.at(currentFieldIndex); + DoFHandler *dof_handler = dofHandlersSet_nonconst.at(currentvar_index); + IndexSet *locally_relevant_dofs = + locally_relevant_dofsSet_nonconst.at(currentvar_index); locally_relevant_dofs->clear(); DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); - AffineConstraints *constraintsDirichlet = nullptr; - constraintsDirichlet = constraintsDirichletSet_nonconst.at(currentFieldIndex); + AffineConstraints *constraintsDirichlet = + constraintsDirichletSet_nonconst.at(currentvar_index); constraintsDirichlet->clear(); constraintsDirichlet->reinit(*locally_relevant_dofs); applyDirichletBCs(); constraintsDirichlet->close(); } // Distribute for Uniform or Non-Uniform Dirichlet BCs - constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + constraintsDirichletSet[var_index]->distribute(*solutionSet[var_index]); } - solutionSet[fieldIndex]->update_ghost_values(); + solutionSet[var_index]->update_ghost_values(); } // Explicit time step for matrixfree solve template void -MatrixFreePDE::updateExplicitSolution(unsigned int fieldIndex) +MatrixFreePDE::updateExplicitSolution(unsigned int var_index) { // Explicit-time step each DOF // Takes advantage of knowledge that the length of solutionSet and residualSet // is an integer multiple of the length of invM for vector variables - if (fields[fieldIndex].type == SCALAR) + if (fields[var_index].type == SCALAR) { unsigned int invM_size = invMscalar.locally_owned_size(); - for (unsigned int dof = 0; dof < solutionSet[fieldIndex]->locally_owned_size(); + for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); ++dof) { - solutionSet[fieldIndex]->local_element(dof) = + solutionSet[var_index]->local_element(dof) = invMscalar.local_element(dof % invM_size) * - residualSet[fieldIndex]->local_element(dof); + residualSet[var_index]->local_element(dof); } } - else if (fields[fieldIndex].type == VECTOR) + else if (fields[var_index].type == VECTOR) { unsigned int invM_size = invMvector.locally_owned_size(); - for (unsigned int dof = 0; dof < solutionSet[fieldIndex]->locally_owned_size(); + for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); ++dof) { - solutionSet[fieldIndex]->local_element(dof) = + solutionSet[var_index]->local_element(dof) = invMvector.local_element(dof % invM_size) * - residualSet[fieldIndex]->local_element(dof); + residualSet[var_index]->local_element(dof); } } } template -bool -MatrixFreePDE::updateImplicitSolution(unsigned int fieldIndex, - unsigned int nonlinear_iteration_index) +void +MatrixFreePDE::updateLinearSolution(unsigned int var_index) { - char buffer[200]; - - // Assume convergence criterion is met, unless otherwise proven later on. - bool nonlinear_iteration_converged = true; - - // Apply Dirichlet BC's. This clears the residual where we want to apply Dirichlet BCs, - // otherwise the solver sees a positive residual - constraintsDirichletSet[fieldIndex]->set_zero(*residualSet[fieldIndex]); - - // Grab solver controls - double tol_value = NAN; - if (userInputs.linear_solver_parameters.getToleranceType(fieldIndex) == - ABSOLUTE_RESIDUAL) + if (fields[var_index].type == SCALAR) { - tol_value = userInputs.linear_solver_parameters.getToleranceValue(fieldIndex); + *solutionSet[var_index] += dU_scalar; } else { - tol_value = userInputs.linear_solver_parameters.getToleranceValue(fieldIndex) * - residualSet[fieldIndex]->l2_norm(); + *solutionSet[var_index] += dU_vector; } +} - SolverControl solver_control(userInputs.linear_solver_parameters.getMaxIterations( - fieldIndex), - tol_value); - - // Currently the only allowed solver is SolverCG, the - // SolverType input variable is a dummy - SolverCG> solver(solver_control); - - // Solve - try - { - if (fields[fieldIndex].type == SCALAR) - { - dU_scalar = 0.0; - // solver.solve(*this, - // dU_scalar, - // *residualSet[fieldIndex], - // IdentityMatrix(solutionSet[fieldIndex]->size())); - } - else - { - dU_vector = 0.0; - // solver.solve(*this, - // dU_vector, - // *residualSet[fieldIndex], - // IdentityMatrix(solutionSet[fieldIndex]->size())); - } - } - catch (...) - { - conditionalOStreams::pout_base << "\nWarning: linear solver did not converge as " - "per set tolerances. consider increasing the " - "maximum number of iterations or decreasing the " - "solver tolerance.\n"; - } +template +void +MatrixFreePDE::print_explicit_update(uint var_index, uint current_increment) +{ + char buffer[200]; - if (var_attributes.at(fieldIndex).is_nonlinear) + if (current_increment % userInputs.skip_print_steps == 0) { - // Now that we have the calculated change in the solution, - // we need to select a damping coefficient - double damping_coefficient = NAN; - - if (userInputs.nonlinear_solver_parameters.getBacktrackDampingFlag(fieldIndex)) - { - dealii::LinearAlgebra::distributed::Vector solutionSet_old = - *solutionSet[fieldIndex]; - double residual_old = residualSet[fieldIndex]->l2_norm(); - - damping_coefficient = 1.0; - bool damping_coefficient_found = false; - while (!damping_coefficient_found) - { - if (fields[fieldIndex].type == SCALAR) - { - solutionSet[fieldIndex]->sadd(1.0, damping_coefficient, dU_scalar); - } - else - { - solutionSet[fieldIndex]->sadd(1.0, damping_coefficient, dU_vector); - } - - // computeNonexplicitRHS(); - - for (const auto &it : *valuesDirichletSet[fieldIndex]) - { - if (residualSet[fieldIndex]->in_local_range(it.first)) - { - (*residualSet[fieldIndex])(it.first) = 0.0; - } - } - - double residual_new = residualSet[fieldIndex]->l2_norm(); - - if (currentIncrement % userInputs.skip_print_steps == 0) - { - conditionalOStreams::pout_base - << " Old residual: " << residual_old - << " Damping Coeff: " << damping_coefficient - << " New Residual: " << residual_new << "\n"; - } - - // An improved approach would use the - // Armijo–Goldstein condition to ensure a - // sufficent decrease in the residual. This way is - // just scales the residual. - if ((residual_new < - (residual_old * userInputs.nonlinear_solver_parameters - .getBacktrackResidualDecreaseCoeff(fieldIndex))) || - damping_coefficient < 1.0e-4) - { - damping_coefficient_found = true; - } - else - { - damping_coefficient *= - userInputs.nonlinear_solver_parameters.getBacktrackStepModifier( - fieldIndex); - *solutionSet[fieldIndex] = solutionSet_old; - } - } - } - else - { - damping_coefficient = - userInputs.nonlinear_solver_parameters.getDefaultDampingCoefficient( - fieldIndex); - - if (fields[fieldIndex].type == SCALAR) - { - solutionSet[fieldIndex]->sadd(1.0, damping_coefficient, dU_scalar); - } - else - { - solutionSet[fieldIndex]->sadd(1.0, damping_coefficient, dU_vector); - } - } - - if (currentIncrement % userInputs.skip_print_steps == 0) + double solution_L2_norm = solutionSet[var_index]->l2_norm(); + + snprintf(buffer, + sizeof(buffer), + "field '%2s' [explicit solve]: current solution: " + "%12.6e, current residual:%12.6e\n", + fields[var_index].name.c_str(), + solution_L2_norm, + residualSet[var_index]->l2_norm()); + conditionalOStreams::pout_base << buffer; + + if (!numbers::is_finite(solution_L2_norm)) { - double dU_norm = NAN; - if (fields[fieldIndex].type == SCALAR) - { - dU_norm = dU_scalar.l2_norm(); - } - else - { - dU_norm = dU_vector.l2_norm(); - } snprintf(buffer, sizeof(buffer), - "field '%2s' [linear solve]: initial " - "residual:%12.6e, current residual:%12.6e, " - "nsteps:%u, tolerance criterion:%12.6e, " - "solution: %12.6e, dU: %12.6e\n", - fields[fieldIndex].name.c_str(), - residualSet[fieldIndex]->l2_norm(), - solver_control.last_value(), - solver_control.last_step(), - solver_control.tolerance(), - solutionSet[fieldIndex]->l2_norm(), - dU_norm); + "ERROR: field '%s' solution is NAN. exiting.\n\n", + fields[var_index].name.c_str()); conditionalOStreams::pout_base << buffer; + exit(-1); } + } +} - // Check to see if this individual variable has converged - if (userInputs.nonlinear_solver_parameters.getToleranceType(fieldIndex) == - ABSOLUTE_SOLUTION_CHANGE) +template +void +MatrixFreePDE::print_linear_update(uint var_index, + uint current_increment, + SolverControl &solver_control) +{ + if (current_increment % userInputs.skip_print_steps == 0) + { + double dU_norm = NAN; + if (fields[var_index].type == SCALAR) { - double diff = NAN; - - if (fields[fieldIndex].type == SCALAR) - { - diff = dU_scalar.l2_norm(); - } - else - { - diff = dU_vector.l2_norm(); - } - if (currentIncrement % userInputs.skip_print_steps == 0) - { - snprintf(buffer, - sizeof(buffer), - " field '%2s' [nonlinear solve] current increment: %u, nonlinear " - "iteration: " - "%u, dU: %12.6e\n", - fields[fieldIndex].name.c_str(), - currentIncrement, - nonlinear_iteration_index, - diff); - conditionalOStreams::pout_base << buffer; - } - - if (diff > - userInputs.nonlinear_solver_parameters.getToleranceValue(fieldIndex) && - nonlinear_iteration_index < - userInputs.nonlinear_solver_parameters.getMaxIterations()) - { - nonlinear_iteration_converged = false; - } - else if (diff > - userInputs.nonlinear_solver_parameters.getToleranceValue(fieldIndex)) - { - conditionalOStreams::pout_base - << "\nWarning: nonlinear solver did not converge as " - "per set tolerances. consider increasing the " - "maximum number of iterations or decreasing the " - "solver tolerance.\n"; - } + dU_norm = dU_scalar.l2_norm(); } else { - AssertThrow(false, - FeatureNotImplemented( - "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); + dU_norm = dU_vector.l2_norm(); } + char buffer[200]; + snprintf(buffer, + sizeof(buffer), + "field '%2s' [linear solve]: initial " + "residual:%12.6e, current residual:%12.6e, " + "nsteps:%u, tolerance criterion:%12.6e, " + "solution: %12.6e, dU: %12.6e\n", + fields[var_index].name.c_str(), + residualSet[var_index]->l2_norm(), + solver_control.last_value(), + solver_control.last_step(), + solver_control.tolerance(), + solutionSet[var_index]->l2_norm(), + dU_norm); + conditionalOStreams::pout_base << buffer; } - else - { - if (nonlinear_iteration_index == 0) - { - if (fields[fieldIndex].type == SCALAR) - { - *solutionSet[fieldIndex] += dU_scalar; - } - else - { - *solutionSet[fieldIndex] += dU_vector; - } - - if (currentIncrement % userInputs.skip_print_steps == 0) - { - double dU_norm = NAN; - if (fields[fieldIndex].type == SCALAR) - { - dU_norm = dU_scalar.l2_norm(); - } - else - { - dU_norm = dU_vector.l2_norm(); - } - snprintf(buffer, - sizeof(buffer), - "field '%2s' [linear solve]: initial " - "residual:%12.6e, current residual:%12.6e, " - "nsteps:%u, tolerance criterion:%12.6e, " - "solution: %12.6e, dU: %12.6e\n", - fields[fieldIndex].name.c_str(), - residualSet[fieldIndex]->l2_norm(), - solver_control.last_value(), - solver_control.last_step(), - solver_control.tolerance(), - solutionSet[fieldIndex]->l2_norm(), - dU_norm); - conditionalOStreams::pout_base << buffer; - } - } - } - - return nonlinear_iteration_converged; } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; +template +void +MatrixFreePDE::print_nonlinear_update(uint var_index, uint current_increment) +{ + char buffer[200]; -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; + if (!(current_increment % userInputs.skip_print_steps)) + { + snprintf(buffer, + sizeof(buffer), + "field '%2s' [nonlinear solve]: current " + "solution: %12.6e, current residual:%12.6e\n", + fields[var_index].name.c_str(), + solutionSet[var_index]->l2_norm(), + residualSet[var_index]->l2_norm()); + conditionalOStreams::pout_base << buffer; + } +} -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +template +void +MatrixFreePDE::print_nonlinear_status(uint var_index, + uint current_increment, + uint nonlinear_iteration_index, + double diff) +{ + if (!(current_increment % userInputs.skip_print_steps)) + { + char buffer[200]; + snprintf(buffer, + sizeof(buffer), + " field '%2s' [nonlinear solve] current increment: %u, nonlinear " + "iteration: " + "%u, dU: %12.6e\n", + fields[var_index].name.c_str(), + current_increment, + nonlinear_iteration_index, + diff); + conditionalOStreams::pout_base << buffer; + } +} \ No newline at end of file From 260cc37c8da71d49fa2c6c95f382a318129b42bc Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 16:54:37 -0500 Subject: [PATCH 17/23] user facing functions --- applications/multigrid_test/custom_PDE.h | 32 ++- applications/multigrid_test/main.cc | 28 +-- include/core/matrix_free_operator.h | 90 ++++---- include/core/temp_test.h | 251 ++++++++++++----------- 4 files changed, 210 insertions(+), 191 deletions(-) diff --git a/applications/multigrid_test/custom_PDE.h b/applications/multigrid_test/custom_PDE.h index 81ae379a..92d758a7 100644 --- a/applications/multigrid_test/custom_PDE.h +++ b/applications/multigrid_test/custom_PDE.h @@ -13,8 +13,36 @@ using namespace dealii; template class customPDE : public matrixFreeOperator { +public: + using scalarValue = VectorizedArray; + using scalarGrad = Tensor<1, dim, VectorizedArray>; + using scalarHess = Tensor<2, dim, VectorizedArray>; + using vectorValue = Tensor<1, dim, VectorizedArray>; + using vectorGrad = Tensor<2, dim, VectorizedArray>; + using vectorHess = Tensor<3, dim, VectorizedArray>; + /** * \brief Constructor. */ - customPDE(); -}; \ No newline at end of file + customPDE() = default; + + /** + * \brief User-implemented class for the RHS of nonexplicit equations. + */ + void + nonexplicit_RHS(variableContainer &variable_list, + const Point> &q_point_loc) const override; +}; + +template +void +customPDE::nonexplicit_RHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{ + scalarGrad phi = variable_list.get_scalar_gradient(0); + + scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); + + variable_list.set_scalar_gradient_term(0, phi * coefficient); +} \ No newline at end of file diff --git a/applications/multigrid_test/main.cc b/applications/multigrid_test/main.cc index bc73f53a..c4bfe737 100644 --- a/applications/multigrid_test/main.cc +++ b/applications/multigrid_test/main.cc @@ -1,3 +1,5 @@ +#include "custom_PDE.h" + #include int @@ -12,23 +14,23 @@ main(int argc, char *argv[]) } catch (std::exception &exc) { - std::cerr << std::endl - << std::endl - << "----------------------------------------------------" << std::endl; - std::cerr << "Exception on processing: " << std::endl - << exc.what() << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" << std::endl; + std::cerr << '\n' + << '\n' + << "----------------------------------------------------" << '\n'; + std::cerr << "Exception on processing: " << '\n' + << exc.what() << '\n' + << "Aborting!" << '\n' + << "----------------------------------------------------" << '\n'; return 1; } catch (...) { - std::cerr << std::endl - << std::endl - << "----------------------------------------------------" << std::endl; - std::cerr << "Unknown exception!" << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" << std::endl; + std::cerr << '\n' + << '\n' + << "----------------------------------------------------" << '\n'; + std::cerr << "Unknown exception!" << '\n' + << "Aborting!" << '\n' + << "----------------------------------------------------" << '\n'; return 1; } diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index 0f2e5dc7..aa05f29b 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -7,8 +7,6 @@ #include -using namespace dealii; - /** * \brief This is the abstract base class for the matrix free implementation of some PDE. * @@ -19,16 +17,10 @@ using namespace dealii; */ template class matrixFreeOperator - : public MatrixFreeOperators::Base> + : public dealii::MatrixFreeOperators:: + Base> { public: - using scalarValue = VectorizedArray; - using scalarGrad = Tensor<1, dim, VectorizedArray>; - using scalarHess = Tensor<2, dim, VectorizedArray>; - using vectorValue = Tensor<1, dim, VectorizedArray>; - using vectorGrad = Tensor<2, dim, VectorizedArray>; - using vectorHess = Tensor<3, dim, VectorizedArray>; - /** * \brief Constructor. */ @@ -49,66 +41,69 @@ class matrixFreeOperator protected: /** - * \brief User-implemented PDE. + * \brief User-implemented class for the RHS of nonexplicit equations. */ virtual void - nonexplicit_RHS(variableContainer &variable_list, - const Point> &q_point_loc) const; + nonexplicit_RHS( + variableContainer &variable_list, + const dealii::Point> &q_point_loc) const = 0; private: /** * \brief Apply operator to src and add result in dst. */ void - apply_add(LinearAlgebra::distributed::Vector &dst, - const LinearAlgebra::distributed::Vector &src) const override; + apply_add(dealii::LinearAlgebra::distributed::Vector &dst, + const dealii::LinearAlgebra::distributed::Vector &src) const override; /** * \brief Local application of the operator. */ void - local_apply(const MatrixFree &data, - LinearAlgebra::distributed::Vector &dst, - const LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const; + local_apply(const dealii::MatrixFree &data, + dealii::LinearAlgebra::distributed::Vector &dst, + const dealii::LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const; /** * \brief Local computation of the diagonal of the operator. */ void - local_compute_diagonal(const MatrixFree &data, - LinearAlgebra::distributed::Vector &dst, - const unsigned int &dummy, + local_compute_diagonal(const dealii::MatrixFree &data, + dealii::LinearAlgebra::distributed::Vector &dst, + const unsigned int &dummy, const std::pair &cell_range) const; }; template matrixFreeOperator::matrixFreeOperator() - : MatrixFreeOperators::Base>() + : dealii::MatrixFreeOperators:: + Base>() {} template void matrixFreeOperator::clear() { - MatrixFreeOperators::Base>::clear(); + dealii::MatrixFreeOperators:: + Base>::clear(); } template void matrixFreeOperator::local_apply( - const MatrixFree &data, - LinearAlgebra::distributed::Vector &dst, - const LinearAlgebra::distributed::Vector &src, - const std::pair &cell_range) const + const dealii::MatrixFree &data, + dealii::LinearAlgebra::distributed::Vector &dst, + const dealii::LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const { // Constructor for FEEvaluation objects variableContainer variable_list(data); // Initialize, evaluate, and submit based on user function. variable_list.eval_local_operator( - [this](variableContainer &var_list, - const Point> &q_point_loc) + [this](variableContainer &var_list, + const dealii::Point> &q_point_loc) { this->nonexplicit_RHS(var_list, q_point_loc); }, @@ -117,24 +112,11 @@ matrixFreeOperator::local_apply( cell_range); } -template -void -matrixFreeOperator::nonexplicit_RHS( - variableContainer &variable_list, - const Point> &q_point_loc) const -{ - scalarGrad phi = variable_list.get_scalar_gradient(0); - - scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); - - variable_list.set_scalar_gradient_term(0, phi * coefficient); -} - template void matrixFreeOperator::apply_add( - LinearAlgebra::distributed::Vector &dst, - const LinearAlgebra::distributed::Vector &src) const + dealii::LinearAlgebra::distributed::Vector &dst, + const dealii::LinearAlgebra::distributed::Vector &src) const { this->data->cell_loop(&matrixFreeOperator::local_apply, this, dst, src); } @@ -144,8 +126,8 @@ void matrixFreeOperator::compute_diagonal() { this->inverse_diagonal_entries.reset( - new DiagonalMatrix>()); - LinearAlgebra::distributed::Vector &inverse_diagonal = + new DiagonalMatrix>()); + dealii::LinearAlgebra::distributed::Vector &inverse_diagonal = this->inverse_diagonal_entries->get_vector(); this->data->initialize_dof_vector(inverse_diagonal); unsigned int dummy = 0; @@ -159,7 +141,7 @@ matrixFreeOperator::compute_diagonal() for (unsigned int i = 0; i < inverse_diagonal.locally_owned_size(); ++i) { Assert(inverse_diagonal.local_element(i) > 0.0, - ExcMessage( + dealii::ExcMessage( "No diagonal entry in a positive definite operator should be zero")); inverse_diagonal.local_element(i) = 1.0 / inverse_diagonal.local_element(i); } @@ -168,10 +150,10 @@ matrixFreeOperator::compute_diagonal() template void matrixFreeOperator::local_compute_diagonal( - const MatrixFree &data, - LinearAlgebra::distributed::Vector &dst, - [[maybe_unused]] const unsigned int &dummy, - const std::pair &cell_range) const + const dealii::MatrixFree &data, + dealii::LinearAlgebra::distributed::Vector &dst, + [[maybe_unused]] const unsigned int &dummy, + const std::pair &cell_range) const { // Field index unsigned int field_index = 0; @@ -181,8 +163,8 @@ matrixFreeOperator::local_compute_diagonal( // Initialize, evaluate, and submit diagonal based on user function. variable_list.eval_local_diagonal( - [this](variableContainer &var_list, - const Point> &q_point_loc) + [this](variableContainer &var_list, + const dealii::Point> &q_point_loc) { this->nonexplicit_RHS(var_list, q_point_loc); }, diff --git a/include/core/temp_test.h b/include/core/temp_test.h index d0d87949..d4221f54 100644 --- a/include/core/temp_test.h +++ b/include/core/temp_test.h @@ -32,6 +32,12 @@ #include #include +/** + * Forward declaration for user-implemented PDE class. + */ +template +class customPDE; + const unsigned int degree = 2; const unsigned int dimension = 3; @@ -39,6 +45,9 @@ template class LaplaceProblem { public: + using SystemMatrixType = customPDE; + using LevelMatrixType = customPDE; + LaplaceProblem(); void run(); @@ -53,23 +62,23 @@ class LaplaceProblem void output_results(unsigned int cycle) const; - parallel::distributed::Triangulation triangulation; + dealii::parallel::distributed::Triangulation triangulation; - const FE_Q fe; - DoFHandler dof_handler; + const dealii::FE_Q fe; + dealii::DoFHandler dof_handler; - MappingQ1 mapping; + dealii::MappingQ1 mapping; + + dealii::AffineConstraints constraints; - AffineConstraints constraints; - using SystemMatrixType = matrixFreeOperator; SystemMatrixType system_matrix; - MGConstrainedDoFs mg_constrained_dofs; - using LevelMatrixType = matrixFreeOperator; - MGLevelObject mg_matrices; + dealii::MGConstrainedDoFs mg_constrained_dofs; + + dealii::MGLevelObject mg_matrices; - LinearAlgebra::distributed::Vector solution; - LinearAlgebra::distributed::Vector system_rhs; + dealii::LinearAlgebra::distributed::Vector solution; + dealii::LinearAlgebra::distributed::Vector system_rhs; double setup_time {}; }; @@ -78,8 +87,8 @@ template LaplaceProblem::LaplaceProblem() : triangulation( MPI_COMM_WORLD, - Triangulation::limit_level_difference_at_vertices, - parallel::distributed::Triangulation::construct_multigrid_hierarchy) + dealii::Triangulation::limit_level_difference_at_vertices, + dealii::parallel::distributed::Triangulation::construct_multigrid_hierarchy) , fe(degree) , dof_handler(triangulation) {} @@ -90,96 +99,92 @@ LaplaceProblem::setup_system() { Timer time; setup_time = 0; - { - system_matrix.clear(); - mg_matrices.clear_elements(); - - dof_handler.distribute_dofs(fe); - dof_handler.distribute_mg_dofs(); - - conditionalOStreams::pout_base - << "Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; - - constraints.clear(); - constraints.reinit(dof_handler.locally_owned_dofs(), - DoFTools::extract_locally_relevant_dofs(dof_handler)); - DoFTools::make_hanging_node_constraints(dof_handler, constraints); - VectorTools::interpolate_boundary_values(mapping, - dof_handler, - 0, - Functions::ZeroFunction(), - constraints); - constraints.close(); - } + + system_matrix.clear(); + mg_matrices.clear_elements(); + + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + conditionalOStreams::pout_base + << "Number of degrees of freedom: " << dof_handler.n_dofs() << std::endl; + + constraints.clear(); + constraints.reinit(dof_handler.locally_owned_dofs(), + dealii::DoFTools::extract_locally_relevant_dofs(dof_handler)); + dealii::DoFTools::make_hanging_node_constraints(dof_handler, constraints); + dealii::VectorTools::interpolate_boundary_values(mapping, + dof_handler, + 0, + dealii::Functions::ZeroFunction(), + constraints); + constraints.close(); + setup_time += time.wall_time(); conditionalOStreams::pout_base << "Distribute DoFs & B.C. (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' << '\n'; time.restart(); - { - { - typename MatrixFree::AdditionalData additional_data; - additional_data.tasks_parallel_scheme = - MatrixFree::AdditionalData::none; - additional_data.mapping_update_flags = - (update_gradients | update_JxW_values | update_quadrature_points); - std::shared_ptr> system_mf_storage( - new MatrixFree()); - system_mf_storage->reinit(mapping, - dof_handler, - constraints, - QGauss<1>(fe.degree + 1), - additional_data); - system_matrix.initialize(system_mf_storage); - } - system_matrix.initialize_dof_vector(solution); - system_matrix.initialize_dof_vector(system_rhs); - } + typename dealii::MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + dealii::MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + std::shared_ptr> system_mf_storage( + new dealii::MatrixFree()); + system_mf_storage->reinit(mapping, + dof_handler, + constraints, + dealii::QGauss<1>(fe.degree + 1), + additional_data); + system_matrix.initialize(system_mf_storage); + + system_matrix.initialize_dof_vector(solution); + system_matrix.initialize_dof_vector(system_rhs); + setup_time += time.wall_time(); conditionalOStreams::pout_base << "Setup matrix-free system (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' << '\n'; time.restart(); - { - const unsigned int nlevels = triangulation.n_global_levels(); - mg_matrices.resize(0, nlevels - 1); - - const std::set dirichlet_boundary_ids = {0}; - mg_constrained_dofs.initialize(dof_handler); - mg_constrained_dofs.make_zero_boundary_constraints(dof_handler, - dirichlet_boundary_ids); - - for (unsigned int level = 0; level < nlevels; ++level) - { - AffineConstraints level_constraints( - dof_handler.locally_owned_mg_dofs(level), - DoFTools::extract_locally_relevant_level_dofs(dof_handler, level)); - for (const types::global_dof_index dof_index : - mg_constrained_dofs.get_boundary_indices(level)) - { - level_constraints.constrain_dof_to_zero(dof_index); - } - level_constraints.close(); - - typename MatrixFree::AdditionalData additional_data; - additional_data.tasks_parallel_scheme = - MatrixFree::AdditionalData::none; - additional_data.mapping_update_flags = - (update_gradients | update_JxW_values | update_quadrature_points); - additional_data.mg_level = level; - std::shared_ptr> mg_mf_storage_level = - std::make_shared>(); - mg_mf_storage_level->reinit(mapping, - dof_handler, - level_constraints, - QGauss<1>(fe.degree + 1), - additional_data); - - mg_matrices[level].initialize(mg_mf_storage_level, mg_constrained_dofs, level); - } - } + const unsigned int nlevels = triangulation.n_global_levels(); + mg_matrices.resize(0, nlevels - 1); + + const std::set dirichlet_boundary_ids = {0}; + mg_constrained_dofs.initialize(dof_handler); + mg_constrained_dofs.make_zero_boundary_constraints(dof_handler, dirichlet_boundary_ids); + + for (unsigned int level = 0; level < nlevels; ++level) + { + dealii::AffineConstraints level_constraints( + dof_handler.locally_owned_mg_dofs(level), + dealii::DoFTools::extract_locally_relevant_level_dofs(dof_handler, level)); + for (const dealii::types::global_dof_index dof_index : + mg_constrained_dofs.get_boundary_indices(level)) + { + level_constraints.constrain_dof_to_zero(dof_index); + } + level_constraints.close(); + + typename dealii::MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + dealii::MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + additional_data.mg_level = level; + std::shared_ptr> mg_mf_storage_level = + std::make_shared>(); + mg_mf_storage_level->reinit(mapping, + dof_handler, + level_constraints, + dealii::QGauss<1>(fe.degree + 1), + additional_data); + + mg_matrices[level].initialize(mg_mf_storage_level, mg_constrained_dofs, level); + } + setup_time += time.wall_time(); conditionalOStreams::pout_base << "Setup matrix-free levels (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << 's' @@ -193,19 +198,19 @@ LaplaceProblem::assemble_rhs() Timer time; system_rhs = 0; - FEEvaluation phi(*system_matrix.get_matrix_free()); + dealii::FEEvaluation phi(*system_matrix.get_matrix_free()); for (unsigned int cell = 0; cell < system_matrix.get_matrix_free()->n_cell_batches(); ++cell) { phi.reinit(cell); for (const unsigned int q : phi.quadrature_point_indices()) { - phi.submit_value(make_vectorized_array(1.0), q); + phi.submit_value(dealii::make_vectorized_array(1.0), q); } - phi.integrate(EvaluationFlags::values); + phi.integrate(dealii::EvaluationFlags::EvaluationFlags::values); phi.distribute_local_to_global(system_rhs); } - system_rhs.compress(VectorOperation::add); + system_rhs.compress(dealii::VectorOperation::add); setup_time += time.wall_time(); conditionalOStreams::pout_base << "Assemble right hand side (CPU/wall) " @@ -217,8 +222,8 @@ template void LaplaceProblem::solve() { - Timer time; - MGTransferMatrixFree mg_transfer(mg_constrained_dofs); + Timer time; + dealii::MGTransferMatrixFree mg_transfer(mg_constrained_dofs); mg_transfer.build(dof_handler); setup_time += time.wall_time(); conditionalOStreams::pout_base << "MG build transfer time (CPU/wall) " @@ -226,10 +231,12 @@ LaplaceProblem::solve() time.restart(); using SmootherType = - PreconditionChebyshev>; - mg::SmootherRelaxation> - mg_smoother; - MGLevelObject smoother_data; + dealii::PreconditionChebyshev>; + dealii::mg::SmootherRelaxation> + mg_smoother; + dealii::MGLevelObject smoother_data; smoother_data.resize(0, triangulation.n_global_levels() - 1); for (unsigned int level = 0; level < triangulation.n_global_levels(); ++level) { @@ -242,7 +249,7 @@ LaplaceProblem::solve() else { smoother_data[0].smoothing_range = 1e-3; - smoother_data[0].degree = numbers::invalid_unsigned_int; + smoother_data[0].degree = dealii::numbers::invalid_unsigned_int; smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m(); } mg_matrices[level].compute_diagonal(); @@ -251,19 +258,21 @@ LaplaceProblem::solve() } mg_smoother.initialize(mg_matrices, smoother_data); - MGCoarseGridApplySmoother> mg_coarse; + dealii::MGCoarseGridApplySmoother> + mg_coarse; mg_coarse.initialize(mg_smoother); - mg::Matrix> mg_matrix(mg_matrices); + dealii::mg::Matrix> mg_matrix( + mg_matrices); - MGLevelObject> + dealii::MGLevelObject> mg_interface_matrices; mg_interface_matrices.resize(0, triangulation.n_global_levels() - 1); for (unsigned int level = 0; level < triangulation.n_global_levels(); ++level) { mg_interface_matrices[level].initialize(mg_matrices[level]); } - mg::Matrix> mg_interface( + dealii::mg::Matrix> mg_interface( mg_interface_matrices); Multigrid> mg(mg_matrix, @@ -273,13 +282,13 @@ LaplaceProblem::solve() mg_smoother); mg.set_edge_matrices(mg_interface, mg_interface); - PreconditionMG, - MGTransferMatrixFree> + dealii::PreconditionMG, + dealii::MGTransferMatrixFree> preconditioner(dof_handler, mg, mg_transfer); - SolverControl solver_control(100, 1e-12 * system_rhs.l2_norm()); - SolverCG> cg(solver_control); + dealii::SolverControl solver_control(100, 1e-12 * system_rhs.l2_norm()); + dealii::SolverCG> cg(solver_control); setup_time += time.wall_time(); conditionalOStreams::pout_base << "MG build smoother time (CPU/wall) " << time.cpu_time() << "s/" << time.wall_time() << "s\n"; @@ -309,15 +318,15 @@ LaplaceProblem::output_results(unsigned int cycle) const return; } - DataOut data_out; + dealii::DataOut data_out; solution.update_ghost_values(); data_out.attach_dof_handler(dof_handler); data_out.add_data_vector(solution, "solution"); data_out.build_patches(mapping); - DataOutBase::VtkFlags flags; - flags.compression_level = DataOutBase::CompressionLevel::best_speed; + dealii::DataOutBase::VtkFlags flags; + flags.compression_level = dealii::DataOutBase::CompressionLevel::best_speed; data_out.set_flags(flags); data_out.write_vtu_with_pvtu_record("./", "solution", cycle, MPI_COMM_WORLD, 3); @@ -329,16 +338,14 @@ template void LaplaceProblem::run() { - { - const unsigned int n_vect_doubles = VectorizedArray::size(); - const unsigned int n_vect_bits = 8 * sizeof(double) * n_vect_doubles; + const unsigned int n_vect_doubles = dealii::VectorizedArray::size(); + const unsigned int n_vect_bits = 8 * sizeof(double) * n_vect_doubles; - conditionalOStreams::pout_base - << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits - << " bits (" << Utilities::System::get_current_vectorization_level() << ')' << '\n'; - } + conditionalOStreams::pout_base + << "Vectorization over " << n_vect_doubles << " doubles = " << n_vect_bits + << " bits (" << Utilities::System::get_current_vectorization_level() << ')' << '\n'; - GridGenerator::hyper_cube(triangulation, 0.0, 1.0); + dealii::GridGenerator::hyper_cube(triangulation, 0.0, 1.0); triangulation.refine_global(6); setup_system(); From 9569b8de10a9e597826e3c4d91f59cb4866a031c Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 17:01:06 -0500 Subject: [PATCH 18/23] adding some stuff for explicit RHS LHS stuff --- applications/multigrid_test/custom_PDE.h | 39 +++++++++++++++++++++--- include/core/matrix_free_operator.h | 22 +++++++++++-- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/applications/multigrid_test/custom_PDE.h b/applications/multigrid_test/custom_PDE.h index 92d758a7..ead3d84b 100644 --- a/applications/multigrid_test/custom_PDE.h +++ b/applications/multigrid_test/custom_PDE.h @@ -26,17 +26,41 @@ class customPDE : public matrixFreeOperator */ customPDE() = default; + /** + * \brief User-implemented class for the RHS of explicit equations. + */ + void + compute_explicit_RHS(variableContainer &variable_list, + const dealii::Point> + &q_point_loc) const override; + /** * \brief User-implemented class for the RHS of nonexplicit equations. */ void - nonexplicit_RHS(variableContainer &variable_list, - const Point> &q_point_loc) const override; + compute_nonexplicit_RHS(variableContainer &variable_list, + const dealii::Point> + &q_point_loc) const override; + + /** + * \brief User-implemented class for the LHS of nonexplicit equations. + */ + void + compute_nonexplicit_LHS(variableContainer &variable_list, + const dealii::Point> + &q_point_loc) const override; }; template void -customPDE::nonexplicit_RHS( +customPDE::compute_explicit_RHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{} + +template +void +customPDE::compute_nonexplicit_RHS( variableContainer &variable_list, const Point> &q_point_loc) const { @@ -45,4 +69,11 @@ customPDE::nonexplicit_RHS( scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); variable_list.set_scalar_gradient_term(0, phi * coefficient); -} \ No newline at end of file +} + +template +void +customPDE::compute_nonexplicit_LHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{} \ No newline at end of file diff --git a/include/core/matrix_free_operator.h b/include/core/matrix_free_operator.h index aa05f29b..ad605062 100644 --- a/include/core/matrix_free_operator.h +++ b/include/core/matrix_free_operator.h @@ -40,11 +40,27 @@ class matrixFreeOperator compute_diagonal() override; protected: + /** + * \brief User-implemented class for the RHS of explicit equations. + */ + virtual void + compute_explicit_RHS( + variableContainer &variable_list, + const dealii::Point> &q_point_loc) const = 0; + /** * \brief User-implemented class for the RHS of nonexplicit equations. */ virtual void - nonexplicit_RHS( + compute_nonexplicit_RHS( + variableContainer &variable_list, + const dealii::Point> &q_point_loc) const = 0; + + /** + * \brief User-implemented class for the LHS of nonexplicit equations. + */ + virtual void + compute_nonexplicit_LHS( variableContainer &variable_list, const dealii::Point> &q_point_loc) const = 0; @@ -105,7 +121,7 @@ matrixFreeOperator::local_apply( [this](variableContainer &var_list, const dealii::Point> &q_point_loc) { - this->nonexplicit_RHS(var_list, q_point_loc); + this->compute_nonexplicit_RHS(var_list, q_point_loc); }, dst, src, @@ -166,7 +182,7 @@ matrixFreeOperator::local_compute_diagonal( [this](variableContainer &var_list, const dealii::Point> &q_point_loc) { - this->nonexplicit_RHS(var_list, q_point_loc); + this->compute_nonexplicit_RHS(var_list, q_point_loc); }, dst, cell_range, From f648b24086cfad5eee5882385385531f8fc41cb7 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 17:16:26 -0500 Subject: [PATCH 19/23] fixing some stuff so it compiles --- src/core/solvers/solve.cc | 6 ++--- src/core/solvers/solveIncrement.cc | 36 +++++++++++++----------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/core/solvers/solve.cc b/src/core/solvers/solve.cc index 0fca4569..75cab9a9 100644 --- a/src/core/solvers/solve.cc +++ b/src/core/solvers/solve.cc @@ -26,7 +26,7 @@ MatrixFreePDE::solve() // generatingInitialGuess = false; // Do an initial solve to set the elliptic fields - solveIncrement(true); + // solveIncrement(true); // output initial conditions for time dependent BVP if (userInputs.outputTimeStepList[currentOutput] == currentIncrement) @@ -100,7 +100,7 @@ MatrixFreePDE::solve() } // solve time increment - solveIncrement(false); + // solveIncrement(false); // Output results to file (on the proper increments) if (userInputs.outputTimeStepList[currentOutput] == currentIncrement) @@ -132,7 +132,7 @@ MatrixFreePDE::solve() // generatingInitialGuess = false; // solve - solveIncrement(false); + // solveIncrement(false); // output results to file outputResults(); diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index a6564324..61f6c92a 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -15,8 +15,6 @@ void MatrixFreePDE::solveIncrement(uint current_increment, bool skip_time_dependent) { - // log time - computing_timer.enter_subsection("matrixFreePDE: solveIncrements"); char buffer[200]; // Solve and update auxiliary fields that are not nonlinear (sequentially) @@ -30,7 +28,7 @@ MatrixFreePDE::solveIncrement(uint current_increment, // Solve and update explicit fields (concurrently) // if (hasExplicitEquation && !skip_time_dependent) - computeExplicitRHS(); // HERE + // computeExplicitRHS(); // HERE for (const auto &[var_index, variable] : var_attributes) { if (variable.eq_type == EXPLICIT_TIME_DEPENDENT) @@ -48,14 +46,14 @@ MatrixFreePDE::solveIncrement(uint current_increment, if (variable.eq_type != EXPLICIT_TIME_DEPENDENT && !variable.is_nonlinear) { SolverControl solver_control; - compute_nonexplicit_RHS(var_index); // HERE + // compute_nonexplicit_RHS(var_index); // HERE linearSolveOnce(var_index, solver_control); // lhs updateLinearSolution(var_index, solver_control); print_linear_update(var_index, solver_control); // Apply Boundary conditions applyBCs(var_index); - print_update(var_index, current_increment); + // print_update(var_index, current_increment); } } @@ -113,8 +111,6 @@ MatrixFreePDE::solveIncrement(uint current_increment, "maximum number of iterations or decreasing the " "solver tolerance.\n"; } - // log time - computing_timer.leave_subsection("matrixFreePDE: solveIncrements"); } template @@ -176,7 +172,7 @@ template void MatrixFreePDE::auxiliaryOnce(unsigned int var_index, uint current_increment) { - computeNonexplicitRHS(var_index); // HERE + // computeNonexplicitRHS(var_index); // HERE updateExplicitSolution(var_index); // Apply Boundary conditions @@ -227,7 +223,7 @@ MatrixFreePDE::nonlinearIncrement(unsigned int var_index, solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); } - computeNonexplicitRHS(); // HERE + // computeNonexplicitRHS(); // HERE for (const auto &it : *valuesDirichletSet[var_index]) { @@ -361,17 +357,17 @@ MatrixFreePDE::applyBCs(unsigned int var_index) // Apply non-uniform Dirlichlet_BCs to the current field if (fields[var_index].hasnonuniformDirichletBCs) { - DoFHandler *dof_handler = dofHandlersSet_nonconst.at(currentvar_index); - IndexSet *locally_relevant_dofs = - locally_relevant_dofsSet_nonconst.at(currentvar_index); - locally_relevant_dofs->clear(); - DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); - AffineConstraints *constraintsDirichlet = - constraintsDirichletSet_nonconst.at(currentvar_index); - constraintsDirichlet->clear(); - constraintsDirichlet->reinit(*locally_relevant_dofs); - applyDirichletBCs(); - constraintsDirichlet->close(); + // DoFHandler *dof_handler = dofHandlersSet_nonconst.at(currentvar_index); + // IndexSet *locally_relevant_dofs = + // locally_relevant_dofsSet_nonconst.at(currentvar_index); + // locally_relevant_dofs->clear(); + // DoFTools::extract_locally_relevant_dofs(*dof_handler, + // *locally_relevant_dofs); AffineConstraints *constraintsDirichlet = + // constraintsDirichletSet_nonconst.at(currentvar_index); + // constraintsDirichlet->clear(); + // constraintsDirichlet->reinit(*locally_relevant_dofs); + // applyDirichletBCs(); + // constraintsDirichlet->close(); } // Distribute for Uniform or Non-Uniform Dirichlet BCs constraintsDirichletSet[var_index]->distribute(*solutionSet[var_index]); From 01989d4b695a7b67096c10f5e843d49053f851a9 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 18:02:53 -0500 Subject: [PATCH 20/23] user-facing equations.cc --- applications/multigrid_test/CMakeLists.txt | 2 +- applications/multigrid_test/custom_PDE.h | 30 ++----------- applications/multigrid_test/equations.cc | 32 ++++++++++++++ include/config.h.in | 42 +++++++++++++++++++ .../boundary_conditions/boundaryConditions.cc | 19 +-------- .../boundary_conditions/markBoundaries.cc | 21 +--------- src/core/buildFields.cc | 28 ++----------- src/core/checkpoint.cc | 19 +-------- src/core/init.cc | 19 +-------- .../initial_conditions/initialConditions.cc | 19 +-------- src/core/invM.cc | 19 +-------- src/core/matrixFreePDE.cc | 19 +-------- src/core/outputResults.cc | 19 +-------- src/core/postprocessing/computeIntegral.cc | 19 +-------- src/core/refinement/AdaptiveRefinement.cc | 20 +-------- src/core/reinit.cc | 19 +-------- src/core/solvers/solve.cc | 19 +-------- src/core/variableContainer.cc | 31 +------------- src/grains/FloodFiller.cc | 20 +-------- src/grains/reassignGrains.cc | 19 +-------- src/nucleation/nucleation.cc | 19 +-------- src/utilities/utilities.cc | 19 +-------- 22 files changed, 116 insertions(+), 357 deletions(-) create mode 100644 applications/multigrid_test/equations.cc diff --git a/applications/multigrid_test/CMakeLists.txt b/applications/multigrid_test/CMakeLists.txt index dc0a2d4b..7780059a 100644 --- a/applications/multigrid_test/CMakeLists.txt +++ b/applications/multigrid_test/CMakeLists.txt @@ -133,7 +133,7 @@ include_directories(${CMAKE_SOURCE_DIR}/../../src) include_directories(${CMAKE_SOURCE_DIR}) # Set the location of the main.cc file -set(TARGET_SRC "${CMAKE_SOURCE_DIR}/main.cc") +set(TARGET_SRC "${CMAKE_SOURCE_DIR}/main.cc" "${CMAKE_SOURCE_DIR}/equations.cc") # Check if there has been updates to main library set(dir ${PROJECT_SOURCE_DIR}/../..) diff --git a/applications/multigrid_test/custom_PDE.h b/applications/multigrid_test/custom_PDE.h index ead3d84b..ee568561 100644 --- a/applications/multigrid_test/custom_PDE.h +++ b/applications/multigrid_test/custom_PDE.h @@ -1,3 +1,6 @@ +#ifndef CUSTOM_PDE_H_ +#define CUSTOM_PDE_H_ + #include using namespace dealii; @@ -51,29 +54,4 @@ class customPDE : public matrixFreeOperator &q_point_loc) const override; }; -template -void -customPDE::compute_explicit_RHS( - variableContainer &variable_list, - const Point> &q_point_loc) const -{} - -template -void -customPDE::compute_nonexplicit_RHS( - variableContainer &variable_list, - const Point> &q_point_loc) const -{ - scalarGrad phi = variable_list.get_scalar_gradient(0); - - scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); - - variable_list.set_scalar_gradient_term(0, phi * coefficient); -} - -template -void -customPDE::compute_nonexplicit_LHS( - variableContainer &variable_list, - const Point> &q_point_loc) const -{} \ No newline at end of file +#endif \ No newline at end of file diff --git a/applications/multigrid_test/equations.cc b/applications/multigrid_test/equations.cc new file mode 100644 index 00000000..f4e9650e --- /dev/null +++ b/applications/multigrid_test/equations.cc @@ -0,0 +1,32 @@ +#include "custom_PDE.h" + +#include + +template +void +customPDE::compute_explicit_RHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{} + +template +void +customPDE::compute_nonexplicit_RHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{ + scalarGrad phi = variable_list.get_scalar_gradient(0); + + scalarValue coefficient = 1.0 / (0.05 + 2.0 * q_point_loc.square()); + + variable_list.set_scalar_gradient_term(0, phi * coefficient); +} + +template +void +customPDE::compute_nonexplicit_LHS( + variableContainer &variable_list, + const Point> &q_point_loc) const +{} + +INSTANTIATE_TRI_TEMPLATE(customPDE) \ No newline at end of file diff --git a/include/config.h.in b/include/config.h.in index 622a2f0f..bf643496 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -10,4 +10,46 @@ #cmakedefine PRISMS_PF_WITH_CALIPER +// Macro for template instantations with +#define INSTANTIATE_TRI_TEMPLATE(class_name) \ + template class class_name<2, 1, float>; \ + template class class_name<2, 2, float>; \ + template class class_name<2, 3, float>; \ + template class class_name<2, 4, float>; \ + template class class_name<2, 5, float>; \ + template class class_name<2, 6, float>; \ + template class class_name<2, 1, double>; \ + template class class_name<2, 2, double>; \ + template class class_name<2, 3, double>; \ + template class class_name<2, 4, double>; \ + template class class_name<2, 5, double>; \ + template class class_name<2, 6, double>; \ + template class class_name<3, 1, float>; \ + template class class_name<3, 2, float>; \ + template class class_name<3, 3, float>; \ + template class class_name<3, 4, float>; \ + template class class_name<3, 5, float>; \ + template class class_name<3, 6, float>; \ + template class class_name<3, 1, double>; \ + template class class_name<3, 2, double>; \ + template class class_name<3, 3, double>; \ + template class class_name<3, 4, double>; \ + template class class_name<3, 5, double>; \ + template class class_name<3, 6, double>; + +// Macro for template instantations with +#define INSTANTIATE_BI_TEMPLATE(class_name) \ + template class class_name<2, 1>; \ + template class class_name<2, 2>; \ + template class class_name<2, 3>; \ + template class class_name<2, 4>; \ + template class class_name<2, 5>; \ + template class class_name<2, 6>; \ + template class class_name<3, 1>; \ + template class class_name<3, 2>; \ + template class class_name<3, 3>; \ + template class class_name<3, 4>; \ + template class class_name<3, 5>; \ + template class class_name<3, 6>; + #endif diff --git a/src/core/boundary_conditions/boundaryConditions.cc b/src/core/boundary_conditions/boundaryConditions.cc index 75548c32..9fe08c7c 100644 --- a/src/core/boundary_conditions/boundaryConditions.cc +++ b/src/core/boundary_conditions/boundaryConditions.cc @@ -1,3 +1,4 @@ +#include #include #include #include @@ -313,20 +314,4 @@ MatrixFreePDE::set_rigid_body_mode_constraints( } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/boundary_conditions/markBoundaries.cc b/src/core/boundary_conditions/markBoundaries.cc index 4723df5f..d4ec0618 100644 --- a/src/core/boundary_conditions/markBoundaries.cc +++ b/src/core/boundary_conditions/markBoundaries.cc @@ -1,5 +1,4 @@ -// methods to mark boundaries - +#include #include #include @@ -32,20 +31,4 @@ MatrixFreePDE::markBoundaries( } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/buildFields.cc b/src/core/buildFields.cc index 497b7aed..79276dc3 100644 --- a/src/core/buildFields.cc +++ b/src/core/buildFields.cc @@ -1,14 +1,8 @@ -/* - * buildFields.cc - * - * Created on: Feb 22, 2017 - * Author: stephendewitt - */ - -// ===================================================================== +//================================================================ // FUNCTION TO BUILD THE VECTOR OF FIELDS // ===================================================================== +#include #include template @@ -22,20 +16,4 @@ MatrixFreePDE::buildFields() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/checkpoint.cc b/src/core/checkpoint.cc index ce5cd1ac..ed9d88ea 100644 --- a/src/core/checkpoint.cc +++ b/src/core/checkpoint.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -273,20 +274,4 @@ MatrixFreePDE::verify_checkpoint_file_exists(const std::string &fil } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/init.cc b/src/core/init.cc index 2b065e30..63008be8 100644 --- a/src/core/init.cc +++ b/src/core/init.cc @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -439,20 +440,4 @@ MatrixFreePDE::compute_element_volume() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/initial_conditions/initialConditions.cc b/src/core/initial_conditions/initialConditions.cc index 0de683eb..25fa5d3d 100644 --- a/src/core/initial_conditions/initialConditions.cc +++ b/src/core/initial_conditions/initialConditions.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -434,20 +435,4 @@ MatrixFreePDE::applyInitialConditions() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/invM.cc b/src/core/invM.cc index 231a564d..d9db7050 100644 --- a/src/core/invM.cc +++ b/src/core/invM.cc @@ -1,5 +1,6 @@ #include +#include #include #include @@ -146,20 +147,4 @@ MatrixFreePDE::computeInvM() << parabolicVectorFieldIndex << ")\n"; } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/matrixFreePDE.cc b/src/core/matrixFreePDE.cc index 6fac8afe..0fc326e9 100644 --- a/src/core/matrixFreePDE.cc +++ b/src/core/matrixFreePDE.cc @@ -1,3 +1,4 @@ +#include #include #include @@ -70,20 +71,4 @@ MatrixFreePDE::~MatrixFreePDE() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/outputResults.cc b/src/core/outputResults.cc index 5f340455..376af85b 100644 --- a/src/core/outputResults.cc +++ b/src/core/outputResults.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -221,20 +222,4 @@ MatrixFreePDE::outputResults() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/postprocessing/computeIntegral.cc b/src/core/postprocessing/computeIntegral.cc index b67bd0c8..cf2b6cba 100644 --- a/src/core/postprocessing/computeIntegral.cc +++ b/src/core/postprocessing/computeIntegral.cc @@ -1,4 +1,5 @@ +#include #include template @@ -42,20 +43,4 @@ MatrixFreePDE::computeIntegral( integratedField = value; } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/refinement/AdaptiveRefinement.cc b/src/core/refinement/AdaptiveRefinement.cc index 47cf0b46..b900c1e6 100644 --- a/src/core/refinement/AdaptiveRefinement.cc +++ b/src/core/refinement/AdaptiveRefinement.cc @@ -1,3 +1,4 @@ +#include #include using namespace dealii; @@ -168,21 +169,4 @@ AdaptiveRefinement::refine_grid() triangulation.execute_coarsening_and_refinement(); } -// Explicit instantiation -template class AdaptiveRefinement<2, 1>; -template class AdaptiveRefinement<3, 1>; - -template class AdaptiveRefinement<2, 2>; -template class AdaptiveRefinement<3, 2>; - -template class AdaptiveRefinement<2, 3>; -template class AdaptiveRefinement<3, 3>; - -template class AdaptiveRefinement<2, 4>; -template class AdaptiveRefinement<3, 4>; - -template class AdaptiveRefinement<2, 5>; -template class AdaptiveRefinement<3, 5>; - -template class AdaptiveRefinement<2, 6>; -template class AdaptiveRefinement<3, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(AdaptiveRefinement) \ No newline at end of file diff --git a/src/core/reinit.cc b/src/core/reinit.cc index 31fa5a5b..8a62456c 100644 --- a/src/core/reinit.cc +++ b/src/core/reinit.cc @@ -1,3 +1,4 @@ +#include #include #include @@ -200,20 +201,4 @@ MatrixFreePDE::reinit() compute_element_volume(); } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/solvers/solve.cc b/src/core/solvers/solve.cc index 75cab9a9..2d50f2f4 100644 --- a/src/core/solvers/solve.cc +++ b/src/core/solvers/solve.cc @@ -1,3 +1,4 @@ +#include #include #include @@ -139,20 +140,4 @@ MatrixFreePDE::solve() } } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/variableContainer.cc b/src/core/variableContainer.cc index 5e2afaa7..bacf3527 100644 --- a/src/core/variableContainer.cc +++ b/src/core/variableContainer.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -239,32 +240,4 @@ variableContainer::set_vector_gradient_term( vector_vars_map.at(global_variable_index)->submit_gradient(grad, q_point); } -template class variableContainer<2, 1, float>; -template class variableContainer<3, 1, float>; -template class variableContainer<2, 1, double>; -template class variableContainer<3, 1, double>; - -template class variableContainer<2, 2, float>; -template class variableContainer<3, 2, float>; -template class variableContainer<2, 2, double>; -template class variableContainer<3, 2, double>; - -template class variableContainer<2, 3, float>; -template class variableContainer<3, 3, float>; -template class variableContainer<2, 3, double>; -template class variableContainer<3, 3, double>; - -template class variableContainer<2, 4, float>; -template class variableContainer<3, 4, float>; -template class variableContainer<2, 4, double>; -template class variableContainer<3, 4, double>; - -template class variableContainer<2, 5, float>; -template class variableContainer<3, 5, float>; -template class variableContainer<2, 5, double>; -template class variableContainer<3, 5, double>; - -template class variableContainer<2, 6, float>; -template class variableContainer<3, 6, float>; -template class variableContainer<2, 6, double>; -template class variableContainer<3, 6, double>; \ No newline at end of file +INSTANTIATE_TRI_TEMPLATE(variableContainer) \ No newline at end of file diff --git a/src/grains/FloodFiller.cc b/src/grains/FloodFiller.cc index 32e79ac9..b9deb929 100644 --- a/src/grains/FloodFiller.cc +++ b/src/grains/FloodFiller.cc @@ -1,3 +1,4 @@ +#include #include template @@ -410,21 +411,4 @@ FloodFiller::mergeSplitGrains(std::vector> &grain_set } } -// Template instantiations -template class FloodFiller<2, 1>; -template class FloodFiller<3, 1>; - -template class FloodFiller<2, 2>; -template class FloodFiller<3, 2>; - -template class FloodFiller<2, 3>; -template class FloodFiller<3, 3>; - -template class FloodFiller<2, 4>; -template class FloodFiller<3, 4>; - -template class FloodFiller<2, 5>; -template class FloodFiller<3, 5>; - -template class FloodFiller<2, 6>; -template class FloodFiller<3, 6>; +INSTANTIATE_BI_TEMPLATE(FloodFiller) \ No newline at end of file diff --git a/src/grains/reassignGrains.cc b/src/grains/reassignGrains.cc index c4b068fe..d41c5f7f 100644 --- a/src/grains/reassignGrains.cc +++ b/src/grains/reassignGrains.cc @@ -1,3 +1,4 @@ +#include #include #include #include @@ -108,20 +109,4 @@ MatrixFreePDE::reassignGrains() conditionalOStreams::pout_base << "Reassigning grains completed.\n\n"; } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/nucleation/nucleation.cc b/src/nucleation/nucleation.cc index f908611d..50885cd1 100644 --- a/src/nucleation/nucleation.cc +++ b/src/nucleation/nucleation.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -587,20 +588,4 @@ MatrixFreePDE::weightedDistanceFromNucleusCenter( return weighted_dist; } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/utilities/utilities.cc b/src/utilities/utilities.cc index 1510081b..ed52bd84 100644 --- a/src/utilities/utilities.cc +++ b/src/utilities/utilities.cc @@ -1,3 +1,4 @@ +#include #include #include @@ -18,20 +19,4 @@ MatrixFreePDE::getFieldIndex(std::string _name) exit(-1); } -template class MatrixFreePDE<2, 1>; -template class MatrixFreePDE<3, 1>; - -template class MatrixFreePDE<2, 2>; -template class MatrixFreePDE<3, 2>; - -template class MatrixFreePDE<3, 3>; -template class MatrixFreePDE<2, 3>; - -template class MatrixFreePDE<3, 4>; -template class MatrixFreePDE<2, 4>; - -template class MatrixFreePDE<3, 5>; -template class MatrixFreePDE<2, 5>; - -template class MatrixFreePDE<3, 6>; -template class MatrixFreePDE<2, 6>; \ No newline at end of file +INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file From dd98ec1d2f35a72a956d576cc24921c8f6006124 Mon Sep 17 00:00:00 2001 From: landinjm Date: Thu, 16 Jan 2025 20:31:45 -0500 Subject: [PATCH 21/23] renaming --- applications/multigrid_test/{custom_PDE.h => custom_pde.h} | 0 applications/multigrid_test/equations.cc | 2 +- applications/multigrid_test/main.cc | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename applications/multigrid_test/{custom_PDE.h => custom_pde.h} (100%) diff --git a/applications/multigrid_test/custom_PDE.h b/applications/multigrid_test/custom_pde.h similarity index 100% rename from applications/multigrid_test/custom_PDE.h rename to applications/multigrid_test/custom_pde.h diff --git a/applications/multigrid_test/equations.cc b/applications/multigrid_test/equations.cc index f4e9650e..9e2f988e 100644 --- a/applications/multigrid_test/equations.cc +++ b/applications/multigrid_test/equations.cc @@ -1,4 +1,4 @@ -#include "custom_PDE.h" +#include "custom_pde.h" #include diff --git a/applications/multigrid_test/main.cc b/applications/multigrid_test/main.cc index c4bfe737..f3c561f0 100644 --- a/applications/multigrid_test/main.cc +++ b/applications/multigrid_test/main.cc @@ -1,4 +1,4 @@ -#include "custom_PDE.h" +#include "custom_pde.h" #include From 7444bcb30a7bc29b8f5eed93b1ff0e08ec0f0dc5 Mon Sep 17 00:00:00 2001 From: landinjm Date: Fri, 17 Jan 2025 00:09:54 -0500 Subject: [PATCH 22/23] adding some more stuff in equations.cc --- applications/multigrid_test/equations.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/applications/multigrid_test/equations.cc b/applications/multigrid_test/equations.cc index 9e2f988e..ef428c76 100644 --- a/applications/multigrid_test/equations.cc +++ b/applications/multigrid_test/equations.cc @@ -1,6 +1,22 @@ #include "custom_pde.h" #include +#include + +void +customAttributeLoader::loadVariableAttributes() +{ + set_variable_name(0, "phi"); + set_variable_type(0, SCALAR); + set_variable_equation_type(0, EXPLICIT_TIME_DEPENDENT); + + set_dependencies_value_term_RHS(0, ""); + set_dependencies_gradient_term_RHS(0, ""); +} + +void +customAttributeLoader::loadPostProcessorVariableAttributes() +{} template void From ebd89b446a52de6230a53320af6a06272bc3d3a5 Mon Sep 17 00:00:00 2001 From: landinjm Date: Fri, 17 Jan 2025 14:05:14 -0500 Subject: [PATCH 23/23] removing fields.h --- include/core/matrixFreePDE.h | 32 -- include/core/refinement/AdaptiveRefinement.h | 4 - src/core/CMakeLists.txt | 1 - src/core/buildFields.cc | 19 - src/core/init.cc | 466 +++++++++--------- .../initial_conditions/initialConditions.cc | 98 ++-- src/core/invM.cc | 118 ++--- src/core/matrixFreePDE.cc | 1 - src/core/outputResults.cc | 32 +- src/core/refinement/AdaptiveRefinement.cc | 24 +- src/core/reinit.cc | 274 +++++----- src/core/solvers/solve.cc | 27 +- src/core/solvers/solveIncrement.cc | 353 ++++++------- src/grains/reassignGrains.cc | 48 +- src/nucleation/nucleation.cc | 15 +- src/utilities/CMakeLists.txt | 1 - src/utilities/utilities.cc | 22 - 17 files changed, 728 insertions(+), 807 deletions(-) delete mode 100644 src/core/buildFields.cc delete mode 100644 src/utilities/utilities.cc diff --git a/include/core/matrixFreePDE.h b/include/core/matrixFreePDE.h index 75c70940..617087c8 100644 --- a/include/core/matrixFreePDE.h +++ b/include/core/matrixFreePDE.h @@ -26,7 +26,6 @@ #include // PRISMS headers -#include #include #include #include @@ -79,18 +78,6 @@ class MatrixFreePDE : public Subscriptor virtual void create_triangulation(parallel::distributed::Triangulation &tria) const; - /** - * \brief Initializes the data structures for enabling unit tests. - * - * \details This method initializes the MatrixFreePDE object with a fixed geometry, - * discretization and other custom selected options specifically to help with unit - * tests, and should not be called in any of the physical models. - * - * \param _fields Vector of PDE descriptions (e.g., scalar/vector) for each field. - */ - void - initForTests(std::vector> _fields); - /** * \brief This method implements the time stepping algorithm and invokes the * solveIncrement() method. @@ -98,20 +85,6 @@ class MatrixFreePDE : public Subscriptor void solve(); - /** - * \brief Vector of all the physical fields in the problem. Fields are identified by - * dimentionality (SCALAR/VECTOR), the kind of PDE (ELLIPTIC/PARABOLIC) used to compute - * them and a character identifier (e.g.: "c" for composition) which is used to write - * the fields to the output files. - */ - std::vector> fields; - - /** - * \brief Create the vector of all physical fields in the problem. - */ - void - buildFields(); - /** * \brief Set the initial condition for all fields. This function is overriden in each * application. @@ -428,11 +401,6 @@ class MatrixFreePDE : public Subscriptor return 0.0; }; - // utility functions - /*Returns index of given field name if exists, else throw error.*/ - unsigned int - getFieldIndex(std::string _name); - /*Method to compute the integral of a field.*/ void computeIntegral( diff --git a/include/core/refinement/AdaptiveRefinement.h b/include/core/refinement/AdaptiveRefinement.h index fad85f84..0ab00343 100644 --- a/include/core/refinement/AdaptiveRefinement.h +++ b/include/core/refinement/AdaptiveRefinement.h @@ -10,7 +10,6 @@ #include #include -#include #include using namespace dealii; @@ -28,7 +27,6 @@ class AdaptiveRefinement AdaptiveRefinement( const userInputParameters &_userInputs, parallel::distributed::Triangulation &_triangulation, - std::vector> &_fields, std::vector *> &_solutionSet, std::vector &triangulation; - std::vector> &fields; - std::vector *> &solutionSet; std::vector -#include - -template -void -MatrixFreePDE::buildFields() -{ - // Build each of the fields in the system - for (const auto &[index, variable] : var_attributes) - { - fields.push_back(Field(variable.var_type, variable.eq_type, variable.name)); - } -} - -INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file diff --git a/src/core/init.cc b/src/core/init.cc index 63008be8..054da32a 100644 --- a/src/core/init.cc +++ b/src/core/init.cc @@ -51,183 +51,183 @@ MatrixFreePDE::init() // Setup system conditionalOStreams::pout_base << "initializing matrix free object\n"; totalDOFs = 0; - for (auto &field : fields) - { - currentFieldIndex = field.index; - - char buffer[100]; - - // print to std::out - std::string var_type; - if (field.pdetype == EXPLICIT_TIME_DEPENDENT) - { - var_type = "EXPLICIT_TIME_DEPENDENT"; - } - else if (field.pdetype == IMPLICIT_TIME_DEPENDENT) - { - var_type = "IMPLICIT_TIME_DEPENDENT"; - } - else if (field.pdetype == TIME_INDEPENDENT) - { - var_type = "TIME_INDEPENDENT"; - } - else if (field.pdetype == AUXILIARY) - { - var_type = "AUXILIARY"; - } - - snprintf(buffer, - sizeof(buffer), - "initializing finite element space P^%u for %9s:%6s field '%s'\n", - degree, - var_type.c_str(), - (field.type == SCALAR ? "SCALAR" : "VECTOR"), - field.name.c_str()); - conditionalOStreams::pout_base << buffer; - - // Check if any time dependent fields present - if (field.pdetype == EXPLICIT_TIME_DEPENDENT) - { - isTimeDependentBVP = true; - hasExplicitEquation = true; - } - else if (field.pdetype == IMPLICIT_TIME_DEPENDENT) - { - isTimeDependentBVP = true; - hasNonExplicitEquation = true; - std::cerr << "PRISMS-PF Error: IMPLICIT_TIME_DEPENDENT equation " - "types are not currently supported\n"; - abort(); - } - else if (field.pdetype == AUXILIARY) - { - hasNonExplicitEquation = true; - } - else if (field.pdetype == TIME_INDEPENDENT) - { - isEllipticBVP = true; - hasNonExplicitEquation = true; - } - - // create FESystem - FESystem *fe = nullptr; - - if (field.type == SCALAR) - { - fe = new FESystem(FE_Q(QGaussLobatto<1>(degree + 1)), 1); - } - else if (field.type == VECTOR) - { - fe = new FESystem(FE_Q(QGaussLobatto<1>(degree + 1)), dim); - } - else - { - conditionalOStreams::pout_base << "\nmatrixFreePDE.h: unknown field type\n"; - exit(-1); - } - FESet.push_back(fe); - - // distribute DOFs - DoFHandler *dof_handler = nullptr; - - dof_handler = new DoFHandler(triangulation); - dofHandlersSet.push_back(dof_handler); - dofHandlersSet_nonconst.push_back(dof_handler); - - dof_handler->distribute_dofs(*fe); - totalDOFs += dof_handler->n_dofs(); - - // Extract locally_relevant_dofs - IndexSet *locally_relevant_dofs = nullptr; - - locally_relevant_dofs = new IndexSet; - locally_relevant_dofsSet.push_back(locally_relevant_dofs); - locally_relevant_dofsSet_nonconst.push_back(locally_relevant_dofs); - - locally_relevant_dofs->clear(); - DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); - - // Create constraints - AffineConstraints *constraintsDirichlet = nullptr; - AffineConstraints *constraintsOther = nullptr; - - constraintsDirichlet = new AffineConstraints; - constraintsDirichletSet.push_back(constraintsDirichlet); - constraintsDirichletSet_nonconst.push_back(constraintsDirichlet); - constraintsOther = new AffineConstraints; - constraintsOtherSet.push_back(constraintsOther); - constraintsOtherSet_nonconst.push_back(constraintsOther); - valuesDirichletSet.push_back(new std::map); - - constraintsDirichlet->clear(); - constraintsDirichlet->reinit(*locally_relevant_dofs); - constraintsOther->clear(); - constraintsOther->reinit(*locally_relevant_dofs); - - // Get hanging node constraints - DoFTools::make_hanging_node_constraints(*dof_handler, *constraintsOther); - - // Pin solution - if (userInputs.pinned_point.find(currentFieldIndex) != - userInputs.pinned_point.end()) - { - set_rigid_body_mode_constraints(constraintsOther, - dof_handler, - userInputs.pinned_point[currentFieldIndex]); - } - - // Get constraints for periodic BCs - setPeriodicityConstraints(constraintsOther, dof_handler); - - // Check if Dirichlet BCs are used - for (unsigned int i = 0; i < userInputs.BC_list.size(); i++) - { - for (unsigned int direction = 0; direction < 2 * dim; direction++) - { - if (userInputs.BC_list[i].var_BC_type[direction] == DIRICHLET) - { - field.hasDirichletBCs = true; - } - else if (userInputs.BC_list[i].var_BC_type[direction] == - NON_UNIFORM_DIRICHLET) - { - field.hasnonuniformDirichletBCs = true; - } - else if (userInputs.BC_list[i].var_BC_type[direction] == NEUMANN) - { - field.hasNeumannBCs = true; - } - } - } - - // Get constraints for Dirichlet BCs - applyDirichletBCs(); - - constraintsDirichlet->close(); - constraintsOther->close(); - - // Store Dirichlet BC DOF's - valuesDirichletSet[field.index]->clear(); - for (types::global_dof_index i = 0; i < dof_handler->n_dofs(); i++) - { - if (locally_relevant_dofs->is_element(i)) - { - if (constraintsDirichlet->is_constrained(i)) - { - (*valuesDirichletSet[field.index])[i] = - constraintsDirichlet->get_inhomogeneity(i); - } - } - } - - snprintf(buffer, - sizeof(buffer), - "field '%2s' DOF : %u (Constraint DOF : %u)\n", - field.name.c_str(), - dof_handler->n_dofs(), - constraintsDirichlet->n_constraints()); - conditionalOStreams::pout_base << buffer; - } + // for (auto &field : fields) + // { + // currentFieldIndex = field.index; + + // char buffer[100]; + + // // print to std::out + // std::string var_type; + // if (field.pdetype == EXPLICIT_TIME_DEPENDENT) + // { + // var_type = "EXPLICIT_TIME_DEPENDENT"; + // } + // else if (field.pdetype == IMPLICIT_TIME_DEPENDENT) + // { + // var_type = "IMPLICIT_TIME_DEPENDENT"; + // } + // else if (field.pdetype == TIME_INDEPENDENT) + // { + // var_type = "TIME_INDEPENDENT"; + // } + // else if (field.pdetype == AUXILIARY) + // { + // var_type = "AUXILIARY"; + // } + + // snprintf(buffer, + // sizeof(buffer), + // "initializing finite element space P^%u for %9s:%6s field '%s'\n", + // degree, + // var_type.c_str(), + // (field.type == SCALAR ? "SCALAR" : "VECTOR"), + // field.name.c_str()); + // conditionalOStreams::pout_base << buffer; + + // // Check if any time dependent fields present + // if (field.pdetype == EXPLICIT_TIME_DEPENDENT) + // { + // isTimeDependentBVP = true; + // hasExplicitEquation = true; + // } + // else if (field.pdetype == IMPLICIT_TIME_DEPENDENT) + // { + // isTimeDependentBVP = true; + // hasNonExplicitEquation = true; + // std::cerr << "PRISMS-PF Error: IMPLICIT_TIME_DEPENDENT equation " + // "types are not currently supported\n"; + // abort(); + // } + // else if (field.pdetype == AUXILIARY) + // { + // hasNonExplicitEquation = true; + // } + // else if (field.pdetype == TIME_INDEPENDENT) + // { + // isEllipticBVP = true; + // hasNonExplicitEquation = true; + // } + + // // create FESystem + // FESystem *fe = nullptr; + + // if (field.type == SCALAR) + // { + // fe = new FESystem(FE_Q(QGaussLobatto<1>(degree + 1)), 1); + // } + // else if (field.type == VECTOR) + // { + // fe = new FESystem(FE_Q(QGaussLobatto<1>(degree + 1)), dim); + // } + // else + // { + // conditionalOStreams::pout_base << "\nmatrixFreePDE.h: unknown field type\n"; + // exit(-1); + // } + // FESet.push_back(fe); + + // // distribute DOFs + // DoFHandler *dof_handler = nullptr; + + // dof_handler = new DoFHandler(triangulation); + // dofHandlersSet.push_back(dof_handler); + // dofHandlersSet_nonconst.push_back(dof_handler); + + // dof_handler->distribute_dofs(*fe); + // totalDOFs += dof_handler->n_dofs(); + + // // Extract locally_relevant_dofs + // IndexSet *locally_relevant_dofs = nullptr; + + // locally_relevant_dofs = new IndexSet; + // locally_relevant_dofsSet.push_back(locally_relevant_dofs); + // locally_relevant_dofsSet_nonconst.push_back(locally_relevant_dofs); + + // locally_relevant_dofs->clear(); + // DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); + + // // Create constraints + // AffineConstraints *constraintsDirichlet = nullptr; + // AffineConstraints *constraintsOther = nullptr; + + // constraintsDirichlet = new AffineConstraints; + // constraintsDirichletSet.push_back(constraintsDirichlet); + // constraintsDirichletSet_nonconst.push_back(constraintsDirichlet); + // constraintsOther = new AffineConstraints; + // constraintsOtherSet.push_back(constraintsOther); + // constraintsOtherSet_nonconst.push_back(constraintsOther); + // valuesDirichletSet.push_back(new std::map); + + // constraintsDirichlet->clear(); + // constraintsDirichlet->reinit(*locally_relevant_dofs); + // constraintsOther->clear(); + // constraintsOther->reinit(*locally_relevant_dofs); + + // // Get hanging node constraints + // DoFTools::make_hanging_node_constraints(*dof_handler, *constraintsOther); + + // // Pin solution + // if (userInputs.pinned_point.find(currentFieldIndex) != + // userInputs.pinned_point.end()) + // { + // set_rigid_body_mode_constraints(constraintsOther, + // dof_handler, + // userInputs.pinned_point[currentFieldIndex]); + // } + + // // Get constraints for periodic BCs + // setPeriodicityConstraints(constraintsOther, dof_handler); + + // // Check if Dirichlet BCs are used + // for (unsigned int i = 0; i < userInputs.BC_list.size(); i++) + // { + // for (unsigned int direction = 0; direction < 2 * dim; direction++) + // { + // if (userInputs.BC_list[i].var_BC_type[direction] == DIRICHLET) + // { + // field.hasDirichletBCs = true; + // } + // else if (userInputs.BC_list[i].var_BC_type[direction] == + // NON_UNIFORM_DIRICHLET) + // { + // field.hasnonuniformDirichletBCs = true; + // } + // else if (userInputs.BC_list[i].var_BC_type[direction] == NEUMANN) + // { + // field.hasNeumannBCs = true; + // } + // } + // } + + // // Get constraints for Dirichlet BCs + // applyDirichletBCs(); + + // constraintsDirichlet->close(); + // constraintsOther->close(); + + // // Store Dirichlet BC DOF's + // valuesDirichletSet[field.index]->clear(); + // for (types::global_dof_index i = 0; i < dof_handler->n_dofs(); i++) + // { + // if (locally_relevant_dofs->is_element(i)) + // { + // if (constraintsDirichlet->is_constrained(i)) + // { + // (*valuesDirichletSet[field.index])[i] = + // constraintsDirichlet->get_inhomogeneity(i); + // } + // } + // } + + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' DOF : %u (Constraint DOF : %u)\n", + // field.name.c_str(), + // dof_handler->n_dofs(), + // constraintsDirichlet->n_constraints()); + // conditionalOStreams::pout_base << buffer; + // } conditionalOStreams::pout_base << "total DOF : " << totalDOFs << "\n"; // Setup the matrix free object @@ -250,46 +250,46 @@ MatrixFreePDE::init() // Setup solution vectors conditionalOStreams::pout_base << "initializing parallel::distributed residual and solution vectors\n"; - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - dealii::LinearAlgebra::distributed::Vector *U = nullptr; - dealii::LinearAlgebra::distributed::Vector *R = nullptr; - - U = new dealii::LinearAlgebra::distributed::Vector; - R = new dealii::LinearAlgebra::distributed::Vector; - solutionSet.push_back(U); - residualSet.push_back(R); - matrixFreeObject.initialize_dof_vector(*R, fieldIndex); - *R = 0; - - matrixFreeObject.initialize_dof_vector(*U, fieldIndex); - *U = 0; - - // Initializing temporary dU vector required for implicit solves of the - // elliptic equation. - if (fields[fieldIndex].pdetype == TIME_INDEPENDENT || - fields[fieldIndex].pdetype == IMPLICIT_TIME_DEPENDENT || - (fields[fieldIndex].pdetype == AUXILIARY && - var_attributes.at(fieldIndex).is_nonlinear)) - { - if (fields[fieldIndex].type == SCALAR) - { - if (!dU_scalar_init) - { - matrixFreeObject.initialize_dof_vector(dU_scalar, fieldIndex); - dU_scalar_init = true; - } - } - else - { - if (!dU_vector_init) - { - matrixFreeObject.initialize_dof_vector(dU_vector, fieldIndex); - dU_vector_init = true; - } - } - } - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // dealii::LinearAlgebra::distributed::Vector *U = nullptr; + // dealii::LinearAlgebra::distributed::Vector *R = nullptr; + + // U = new dealii::LinearAlgebra::distributed::Vector; + // R = new dealii::LinearAlgebra::distributed::Vector; + // solutionSet.push_back(U); + // residualSet.push_back(R); + // matrixFreeObject.initialize_dof_vector(*R, fieldIndex); + // *R = 0; + + // matrixFreeObject.initialize_dof_vector(*U, fieldIndex); + // *U = 0; + + // // Initializing temporary dU vector required for implicit solves of the + // // elliptic equation. + // if (fields[fieldIndex].pdetype == TIME_INDEPENDENT || + // fields[fieldIndex].pdetype == IMPLICIT_TIME_DEPENDENT || + // (fields[fieldIndex].pdetype == AUXILIARY && + // var_attributes.at(fieldIndex).is_nonlinear)) + // { + // if (fields[fieldIndex].type == SCALAR) + // { + // if (!dU_scalar_init) + // { + // matrixFreeObject.initialize_dof_vector(dU_scalar, fieldIndex); + // dU_scalar_init = true; + // } + // } + // else + // { + // if (!dU_vector_init) + // { + // matrixFreeObject.initialize_dof_vector(dU_vector, fieldIndex); + // dU_vector_init = true; + // } + // } + // } + // } // check if time dependent BVP and compute invM if (isTimeDependentBVP) @@ -312,22 +312,22 @@ MatrixFreePDE::init() // Create new solution transfer sets (needed for the "refine_grid" call, might // be able to move this elsewhere) soltransSet.clear(); - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - soltransSet.push_back( - new parallel::distributed:: - SolutionTransfer>( - *dofHandlersSet_nonconst[fieldIndex])); - } - - // Ghost the solution vectors. Also apply the constraints (if any) on the - // solution vectors - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // soltransSet.push_back( + // new parallel::distributed:: + // SolutionTransfer>( + // *dofHandlersSet_nonconst[fieldIndex])); + // } + + // // Ghost the solution vectors. Also apply the constraints (if any) on the + // // solution vectors + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } // If not resuming from a checkpoint, check and perform adaptive mesh refinement, which // reinitializes the system with the new mesh diff --git a/src/core/initial_conditions/initialConditions.cc b/src/core/initial_conditions/initialConditions.cc index 25fa5d3d..19d55496 100644 --- a/src/core/initial_conditions/initialConditions.cc +++ b/src/core/initial_conditions/initialConditions.cc @@ -252,55 +252,55 @@ MatrixFreePDE::applyInitialConditions() double dt_for_smoothing = 0.25 * min_dx * min_dx / (1.0 * dim); op_list_index = 0; - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - if (op_list_index < userInputs.variables_for_remapping.size()) - { - if (fieldIndex == userInputs.variables_for_remapping.at(op_list_index)) - { - for (unsigned int cycle = 0; - cycle < userInputs.num_grain_smoothing_cycles; - cycle++) - { - // Calculates the Laplace RHS and stores the information - // in residualSet - // computeLaplaceRHS(fieldIndex); - if (fields[fieldIndex].type == SCALAR) - { - unsigned int invM_size = invMscalar.locally_owned_size(); - for (unsigned int dof = 0; - dof < solutionSet[fieldIndex]->locally_owned_size(); - ++dof) - { - solutionSet[fieldIndex]->local_element(dof) = - solutionSet[fieldIndex]->local_element(dof) - - invMscalar.local_element(dof % invM_size) * - residualSet[fieldIndex]->local_element(dof) * - dt_for_smoothing; - } - } - else if (fields[fieldIndex].type == VECTOR) - { - unsigned int invM_size = invMvector.locally_owned_size(); - for (unsigned int dof = 0; - dof < solutionSet[fieldIndex]->locally_owned_size(); - ++dof) - { - solutionSet[fieldIndex]->local_element(dof) = - solutionSet[fieldIndex]->local_element(dof) - - invMvector.local_element(dof % invM_size) * - residualSet[fieldIndex]->local_element(dof) * - dt_for_smoothing; - } - } - - solutionSet[fieldIndex]->update_ghost_values(); - } - - op_list_index++; - } - } - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // if (op_list_index < userInputs.variables_for_remapping.size()) + // { + // if (fieldIndex == userInputs.variables_for_remapping.at(op_list_index)) + // { + // for (unsigned int cycle = 0; + // cycle < userInputs.num_grain_smoothing_cycles; + // cycle++) + // { + // // Calculates the Laplace RHS and stores the information + // // in residualSet + // // computeLaplaceRHS(fieldIndex); + // // if (fields[fieldIndex].type == SCALAR) + // // { + // // unsigned int invM_size = invMscalar.locally_owned_size(); + // // for (unsigned int dof = 0; + // // dof < solutionSet[fieldIndex]->locally_owned_size(); + // // ++dof) + // // { + // // solutionSet[fieldIndex]->local_element(dof) = + // // solutionSet[fieldIndex]->local_element(dof) - + // // invMscalar.local_element(dof % invM_size) * + // // residualSet[fieldIndex]->local_element(dof) * + // // dt_for_smoothing; + // // } + // // } + // // else if (fields[fieldIndex].type == VECTOR) + // // { + // // unsigned int invM_size = invMvector.locally_owned_size(); + // // for (unsigned int dof = 0; + // // dof < solutionSet[fieldIndex]->locally_owned_size(); + // // ++dof) + // // { + // // solutionSet[fieldIndex]->local_element(dof) = + // // solutionSet[fieldIndex]->local_element(dof) - + // // invMvector.local_element(dof % invM_size) * + // // residualSet[fieldIndex]->local_element(dof) * + // // dt_for_smoothing; + // // } + // // } + + // solutionSet[fieldIndex]->update_ghost_values(); + // } + + // op_list_index++; + // } + // } + // } } // Create map of vtk files that are read in diff --git a/src/core/invM.cc b/src/core/invM.cc index d9db7050..d89e00a2 100644 --- a/src/core/invM.cc +++ b/src/core/invM.cc @@ -23,25 +23,25 @@ MatrixFreePDE::computeInvM() unsigned int parabolicScalarFieldIndex = 0; unsigned int parabolicVectorFieldIndex = 0; - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - if (fields[fieldIndex].pdetype == EXPLICIT_TIME_DEPENDENT || - fields[fieldIndex].pdetype == AUXILIARY) - { - if (fields[fieldIndex].type == SCALAR && !invMscalarFound) - { - parabolicScalarFieldIndex = fieldIndex; - invMscalarFound = true; - continue; - } - else if (fields[fieldIndex].type == VECTOR && !invMvectorFound) - { - parabolicVectorFieldIndex = fieldIndex; - invMvectorFound = true; - continue; - } - } - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // if (fields[fieldIndex].pdetype == EXPLICIT_TIME_DEPENDENT || + // fields[fieldIndex].pdetype == AUXILIARY) + // { + // if (fields[fieldIndex].type == SCALAR && !invMscalarFound) + // { + // parabolicScalarFieldIndex = fieldIndex; + // invMscalarFound = true; + // continue; + // } + // else if (fields[fieldIndex].type == VECTOR && !invMvectorFound) + // { + // parabolicVectorFieldIndex = fieldIndex; + // invMvectorFound = true; + // continue; + // } + // } + // } // Initialize invM and clear its values matrixFreeObject.initialize_dof_vector(invMscalar, parabolicScalarFieldIndex); @@ -54,46 +54,46 @@ MatrixFreePDE::computeInvM() // Compute mass matrix for the given type of quadrature. Selecting gauss // lobatto quadrature points which are suboptimal but give diagonal M - if (fields[parabolicScalarFieldIndex].type == SCALAR) - { - VectorizedArray one = make_vectorized_array(1.0); - FEEvaluation fe_eval(matrixFreeObject, parabolicScalarFieldIndex); - - const unsigned int n_q_points = fe_eval.n_q_points; - for (unsigned int cell = 0; cell < matrixFreeObject.n_cell_batches(); ++cell) - { - fe_eval.reinit(cell); - for (unsigned int q = 0; q < n_q_points; ++q) - { - fe_eval.submit_value(one, q); - } - fe_eval.integrate(invM_flags); - fe_eval.distribute_local_to_global(invMscalar); - } - } - if (fields[parabolicVectorFieldIndex].type == VECTOR) - { - dealii::Tensor<1, dim, dealii::VectorizedArray> oneV; - for (unsigned int i = 0; i < dim; i++) - { - oneV[i] = 1.0; - } - - FEEvaluation fe_eval(matrixFreeObject, - parabolicVectorFieldIndex); - - const unsigned int n_q_points = fe_eval.n_q_points; - for (unsigned int cell = 0; cell < matrixFreeObject.n_cell_batches(); ++cell) - { - fe_eval.reinit(cell); - for (unsigned int q = 0; q < n_q_points; ++q) - { - fe_eval.submit_value(oneV, q); - } - fe_eval.integrate(invM_flags); - fe_eval.distribute_local_to_global(invMvector); - } - } + // if (fields[parabolicScalarFieldIndex].type == SCALAR) + // { + // VectorizedArray one = make_vectorized_array(1.0); + // FEEvaluation fe_eval(matrixFreeObject, parabolicScalarFieldIndex); + + // const unsigned int n_q_points = fe_eval.n_q_points; + // for (unsigned int cell = 0; cell < matrixFreeObject.n_cell_batches(); ++cell) + // { + // fe_eval.reinit(cell); + // for (unsigned int q = 0; q < n_q_points; ++q) + // { + // fe_eval.submit_value(one, q); + // } + // fe_eval.integrate(invM_flags); + // fe_eval.distribute_local_to_global(invMscalar); + // } + // } + // if (fields[parabolicVectorFieldIndex].type == VECTOR) + // { + // dealii::Tensor<1, dim, dealii::VectorizedArray> oneV; + // for (unsigned int i = 0; i < dim; i++) + // { + // oneV[i] = 1.0; + // } + + // FEEvaluation fe_eval(matrixFreeObject, + // parabolicVectorFieldIndex); + + // const unsigned int n_q_points = fe_eval.n_q_points; + // for (unsigned int cell = 0; cell < matrixFreeObject.n_cell_batches(); ++cell) + // { + // fe_eval.reinit(cell); + // for (unsigned int q = 0; q < n_q_points; ++q) + // { + // fe_eval.submit_value(oneV, q); + // } + // fe_eval.integrate(invM_flags); + // fe_eval.distribute_local_to_global(invMvector); + // } + // } invMscalar.compress(VectorOperation::add); invMvector.compress(VectorOperation::add); diff --git a/src/core/matrixFreePDE.cc b/src/core/matrixFreePDE.cc index 0fc326e9..67b836b8 100644 --- a/src/core/matrixFreePDE.cc +++ b/src/core/matrixFreePDE.cc @@ -23,7 +23,6 @@ MatrixFreePDE::MatrixFreePDE(userInputParameters _userInputs) , first_integrated_var_output_complete(false) , AMR(_userInputs, triangulation, - fields, solutionSet, soltransSet, FESet, diff --git a/src/core/outputResults.cc b/src/core/outputResults.cc index 376af85b..5f3d7e37 100644 --- a/src/core/outputResults.cc +++ b/src/core/outputResults.cc @@ -17,22 +17,22 @@ MatrixFreePDE::outputResults() // loop over fields - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - // mark field as scalar/vector - std::vector dataType( - fields[fieldIndex].numComponents, - (fields[fieldIndex].type == SCALAR - ? DataComponentInterpretation::component_is_scalar - : DataComponentInterpretation::component_is_part_of_vector)); - // add field to data_out - std::vector solutionNames(fields[fieldIndex].numComponents, - fields[fieldIndex].name.c_str()); - data_out.add_data_vector(*dofHandlersSet[fieldIndex], - *solutionSet[fieldIndex], - solutionNames, - dataType); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // // mark field as scalar/vector + // std::vector dataType( + // fields[fieldIndex].numComponents, + // (fields[fieldIndex].type == SCALAR + // ? DataComponentInterpretation::component_is_scalar + // : DataComponentInterpretation::component_is_part_of_vector)); + // // add field to data_out + // std::vector solutionNames(fields[fieldIndex].numComponents, + // fields[fieldIndex].name.c_str()); + // data_out.add_data_vector(*dofHandlersSet[fieldIndex], + // *solutionSet[fieldIndex], + // solutionNames, + // dataType); + // } // Test section for outputting postprocessed fields // Currently there are hacks in place, using the matrixFreeObject, invM, diff --git a/src/core/refinement/AdaptiveRefinement.cc b/src/core/refinement/AdaptiveRefinement.cc index b900c1e6..95b1a547 100644 --- a/src/core/refinement/AdaptiveRefinement.cc +++ b/src/core/refinement/AdaptiveRefinement.cc @@ -7,7 +7,6 @@ template AdaptiveRefinement::AdaptiveRefinement( const userInputParameters &_userInputs, parallel::distributed::Triangulation &_triangulation, - std::vector> &_fields, std::vector *> &_solutionSet, std::vector::AdaptiveRefinement( std::vector *> &_constraintsOtherSet) : userInputs(_userInputs) , triangulation(_triangulation) - , fields(_fields) , solutionSet(_solutionSet) , soltransSet(_soltransSet) , FESet(_FESet) @@ -34,12 +32,12 @@ AdaptiveRefinement::do_adaptive_refinement(unsigned int currentIncr // Apply constraints for the initial condition so they are considered when remeshing if (currentIncrement != 0) { - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } } adaptive_refinement_criterion(); @@ -159,11 +157,11 @@ AdaptiveRefinement::refine_grid() triangulation.prepare_coarsening_and_refinement(); // Transfer solution - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - soltransSet[fieldIndex]->prepare_for_coarsening_and_refinement( - *solutionSet[fieldIndex]); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // soltransSet[fieldIndex]->prepare_for_coarsening_and_refinement( + // *solutionSet[fieldIndex]); + // } // Execute refinement triangulation.execute_coarsening_and_refinement(); diff --git a/src/core/reinit.cc b/src/core/reinit.cc index 8a62456c..f0e5f09e 100644 --- a/src/core/reinit.cc +++ b/src/core/reinit.cc @@ -10,85 +10,85 @@ MatrixFreePDE::reinit() // setup system conditionalOStreams::pout_base << "Reinitializing matrix free object\n"; totalDOFs = 0; - for (const auto &field : fields) - { - currentFieldIndex = field.index; - - char buffer[100]; - - // create FESystem - FESystem *fe = nullptr; - fe = FESet.at(field.index); - - // distribute DOFs - DoFHandler *dof_handler = nullptr; - dof_handler = dofHandlersSet_nonconst.at(field.index); - - dof_handler->distribute_dofs(*fe); - totalDOFs += dof_handler->n_dofs(); - - // extract locally_relevant_dofs - IndexSet *locally_relevant_dofs = nullptr; - locally_relevant_dofs = locally_relevant_dofsSet_nonconst.at(field.index); - - locally_relevant_dofs->clear(); - DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); - - // create constraints - AffineConstraints *constraintsDirichlet = nullptr; - AffineConstraints *constraintsOther = nullptr; - - constraintsDirichlet = constraintsDirichletSet_nonconst.at(field.index); - constraintsOther = constraintsOtherSet_nonconst.at(field.index); - - constraintsDirichlet->clear(); - constraintsDirichlet->reinit(*locally_relevant_dofs); - constraintsOther->clear(); - constraintsOther->reinit(*locally_relevant_dofs); - - // Get hanging node constraints - DoFTools::make_hanging_node_constraints(*dof_handler, *constraintsOther); - - // Pin solution - if (userInputs.pinned_point.find(currentFieldIndex) != - userInputs.pinned_point.end()) - { - set_rigid_body_mode_constraints(constraintsOther, - dof_handler, - userInputs.pinned_point[currentFieldIndex]); - } - - // Get constraints for periodic BCs - setPeriodicityConstraints(constraintsOther, dof_handler); - - // Get constraints for Dirichlet BCs - applyDirichletBCs(); - - constraintsDirichlet->close(); - constraintsOther->close(); - - // Store Dirichlet BC DOF's - valuesDirichletSet[field.index]->clear(); - for (types::global_dof_index i = 0; i < dof_handler->n_dofs(); i++) - { - if (locally_relevant_dofs->is_element(i)) - { - if (constraintsDirichlet->is_constrained(i)) - { - (*valuesDirichletSet[field.index])[i] = - constraintsDirichlet->get_inhomogeneity(i); - } - } - } - - snprintf(buffer, - sizeof(buffer), - "field '%2s' DOF : %u (Constraint DOF : %u)\n", - field.name.c_str(), - dof_handler->n_dofs(), - constraintsDirichlet->n_constraints()); - conditionalOStreams::pout_base << buffer; - } + // for (const auto &field : fields) + // { + // currentFieldIndex = field.index; + + // char buffer[100]; + + // // create FESystem + // FESystem *fe = nullptr; + // fe = FESet.at(field.index); + + // // distribute DOFs + // DoFHandler *dof_handler = nullptr; + // dof_handler = dofHandlersSet_nonconst.at(field.index); + + // dof_handler->distribute_dofs(*fe); + // totalDOFs += dof_handler->n_dofs(); + + // // extract locally_relevant_dofs + // IndexSet *locally_relevant_dofs = nullptr; + // locally_relevant_dofs = locally_relevant_dofsSet_nonconst.at(field.index); + + // locally_relevant_dofs->clear(); + // DoFTools::extract_locally_relevant_dofs(*dof_handler, *locally_relevant_dofs); + + // // create constraints + // AffineConstraints *constraintsDirichlet = nullptr; + // AffineConstraints *constraintsOther = nullptr; + + // constraintsDirichlet = constraintsDirichletSet_nonconst.at(field.index); + // constraintsOther = constraintsOtherSet_nonconst.at(field.index); + + // constraintsDirichlet->clear(); + // constraintsDirichlet->reinit(*locally_relevant_dofs); + // constraintsOther->clear(); + // constraintsOther->reinit(*locally_relevant_dofs); + + // // Get hanging node constraints + // DoFTools::make_hanging_node_constraints(*dof_handler, *constraintsOther); + + // // Pin solution + // if (userInputs.pinned_point.find(currentFieldIndex) != + // userInputs.pinned_point.end()) + // { + // set_rigid_body_mode_constraints(constraintsOther, + // dof_handler, + // userInputs.pinned_point[currentFieldIndex]); + // } + + // // Get constraints for periodic BCs + // setPeriodicityConstraints(constraintsOther, dof_handler); + + // // Get constraints for Dirichlet BCs + // applyDirichletBCs(); + + // constraintsDirichlet->close(); + // constraintsOther->close(); + + // // Store Dirichlet BC DOF's + // valuesDirichletSet[field.index]->clear(); + // for (types::global_dof_index i = 0; i < dof_handler->n_dofs(); i++) + // { + // if (locally_relevant_dofs->is_element(i)) + // { + // if (constraintsDirichlet->is_constrained(i)) + // { + // (*valuesDirichletSet[field.index])[i] = + // constraintsDirichlet->get_inhomogeneity(i); + // } + // } + // } + + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' DOF : %u (Constraint DOF : %u)\n", + // field.name.c_str(), + // dof_handler->n_dofs(), + // constraintsDirichlet->n_constraints()); + // conditionalOStreams::pout_base << buffer; + // } conditionalOStreams::pout_base << "total DOF : " << totalDOFs << "\n"; // Setup the matrix free object @@ -117,40 +117,40 @@ MatrixFreePDE::reinit() // Setup solution vectors conditionalOStreams::pout_base << "initializing parallel::distributed residual and solution vectors\n"; - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - dealii::LinearAlgebra::distributed::Vector *U = nullptr; - - U = solutionSet.at(fieldIndex); - - matrixFreeObject.initialize_dof_vector(*U, fieldIndex); - *U = 0; - - // Initializing temporary dU vector required for implicit solves of the - // elliptic equation. - if (fields[fieldIndex].pdetype == TIME_INDEPENDENT || - fields[fieldIndex].pdetype == IMPLICIT_TIME_DEPENDENT || - (fields[fieldIndex].pdetype == AUXILIARY && - var_attributes.at(fieldIndex).is_nonlinear)) - { - if (fields[fieldIndex].type == SCALAR) - { - if (!dU_scalar_init) - { - matrixFreeObject.initialize_dof_vector(dU_scalar, fieldIndex); - dU_scalar_init = true; - } - } - else - { - if (!dU_vector_init) - { - matrixFreeObject.initialize_dof_vector(dU_vector, fieldIndex); - dU_vector_init = true; - } - } - } - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // dealii::LinearAlgebra::distributed::Vector *U = nullptr; + + // U = solutionSet.at(fieldIndex); + + // matrixFreeObject.initialize_dof_vector(*U, fieldIndex); + // *U = 0; + + // // Initializing temporary dU vector required for implicit solves of the + // // elliptic equation. + // if (fields[fieldIndex].pdetype == TIME_INDEPENDENT || + // fields[fieldIndex].pdetype == IMPLICIT_TIME_DEPENDENT || + // (fields[fieldIndex].pdetype == AUXILIARY && + // var_attributes.at(fieldIndex).is_nonlinear)) + // { + // if (fields[fieldIndex].type == SCALAR) + // { + // if (!dU_scalar_init) + // { + // matrixFreeObject.initialize_dof_vector(dU_scalar, fieldIndex); + // dU_scalar_init = true; + // } + // } + // else + // { + // if (!dU_vector_init) + // { + // matrixFreeObject.initialize_dof_vector(dU_vector, fieldIndex); + // dU_vector_init = true; + // } + // } + // } + // } // Compute invM in PDE is a time-dependent BVP if (isTimeDependentBVP) @@ -159,27 +159,27 @@ MatrixFreePDE::reinit() } // Transfer solution from previous mesh - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - // interpolate and clear used solution transfer sets - soltransSet[fieldIndex]->interpolate(*solutionSet[fieldIndex]); - delete soltransSet[fieldIndex]; - - // reset residual vector - dealii::LinearAlgebra::distributed::Vector *R = residualSet.at(fieldIndex); - matrixFreeObject.initialize_dof_vector(*R, fieldIndex); - *R = 0; - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // // interpolate and clear used solution transfer sets + // soltransSet[fieldIndex]->interpolate(*solutionSet[fieldIndex]); + // delete soltransSet[fieldIndex]; + + // // reset residual vector + // dealii::LinearAlgebra::distributed::Vector *R = residualSet.at(fieldIndex); + // matrixFreeObject.initialize_dof_vector(*R, fieldIndex); + // *R = 0; + // } // Create new solution transfer sets soltransSet.clear(); - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - soltransSet.push_back( - new parallel::distributed:: - SolutionTransfer>( - *dofHandlersSet_nonconst[fieldIndex])); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // soltransSet.push_back( + // new parallel::distributed:: + // SolutionTransfer>( + // *dofHandlersSet_nonconst[fieldIndex])); + // } // If remeshing at the zeroth time step, re-apply initial conditions so the // starting values are correct on the refined mesh @@ -190,12 +190,12 @@ MatrixFreePDE::reinit() // Ghost the solution vectors. Also apply the Dirichet BC's (if any) on the // solution vectors - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } // Once the initial triangulation has been set, compute element volume compute_element_volume(); diff --git a/src/core/solvers/solve.cc b/src/core/solvers/solve.cc index 2d50f2f4..e1748d22 100644 --- a/src/core/solvers/solve.cc +++ b/src/core/solvers/solve.cc @@ -32,12 +32,12 @@ MatrixFreePDE::solve() // output initial conditions for time dependent BVP if (userInputs.outputTimeStepList[currentOutput] == currentIncrement) { - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } outputResults(); currentOutput++; } @@ -106,13 +106,14 @@ MatrixFreePDE::solve() // Output results to file (on the proper increments) if (userInputs.outputTimeStepList[currentOutput] == currentIncrement) { - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute( - *solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); + // fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute( + // *solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } outputResults(); currentOutput++; diff --git a/src/core/solvers/solveIncrement.cc b/src/core/solvers/solveIncrement.cc index 61f6c92a..6f314593 100644 --- a/src/core/solvers/solveIncrement.cc +++ b/src/core/solvers/solveIncrement.cc @@ -94,10 +94,10 @@ MatrixFreePDE::solveIncrement(uint current_increment, // check if solution is nan if (!numbers::is_finite(solutionSet[var_index]->l2_norm())) { - snprintf(buffer, - sizeof(buffer), - "ERROR: field '%s' solution is NAN. exiting.\n\n", - fields[var_index].name.c_str()); + // snprintf(buffer, + // sizeof(buffer), + // "ERROR: field '%s' solution is NAN. exiting.\n\n", + // fields[var_index].name.c_str()); conditionalOStreams::pout_base << buffer; exit(-1); } @@ -142,22 +142,22 @@ MatrixFreePDE::linearSolveOnce(unsigned int var_index, // Solve the linear system try { - if (fields[var_index].type == SCALAR) - { - dU_scalar = 0.0; - solver.solve(*this, - dU_scalar, - *residualSet[var_index], - IdentityMatrix(solutionSet[var_index]->size())); - } - else - { - dU_vector = 0.0; - solver.solve(*this, - dU_vector, - *residualSet[var_index], - IdentityMatrix(solutionSet[var_index]->size())); - } + // if (fields[var_index].type == SCALAR) + // { + // dU_scalar = 0.0; + // solver.solve(*this, + // dU_scalar, + // *residualSet[var_index], + // IdentityMatrix(solutionSet[var_index]->size())); + // } + // else + // { + // dU_vector = 0.0; + // solver.solve(*this, + // dU_vector, + // *residualSet[var_index], + // IdentityMatrix(solutionSet[var_index]->size())); + // } } catch (...) { @@ -181,15 +181,15 @@ MatrixFreePDE::auxiliaryOnce(unsigned int var_index, uint current_i // Print update to screen if (current_increment % userInputs.skip_print_steps == 0) { - char buffer[200]; - snprintf(buffer, - sizeof(buffer), - "field '%2s' [auxiliary solve]: current solution: " - "%12.6e, current residual:%12.6e\n", - fields[var_index].name.c_str(), - solutionSet[var_index]->l2_norm(), - residualSet[var_index]->l2_norm()); - conditionalOStreams::pout_base << buffer; + // char buffer[200]; + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' [auxiliary solve]: current solution: " + // "%12.6e, current residual:%12.6e\n", + // fields[var_index].name.c_str(), + // solutionSet[var_index]->l2_norm(), + // residualSet[var_index]->l2_norm()); + // conditionalOStreams::pout_base << buffer; } } @@ -214,14 +214,14 @@ MatrixFreePDE::nonlinearIncrement(unsigned int var_index, bool damping_coefficient_found = false; while (!damping_coefficient_found) { - if (fields[var_index].type == SCALAR) - { - solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); - } - else - { - solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); - } + // if (fields[var_index].type == SCALAR) + // { + // solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); + // } + // else + // { + // solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); + // } // computeNonexplicitRHS(); // HERE @@ -268,14 +268,14 @@ MatrixFreePDE::nonlinearIncrement(unsigned int var_index, damping_coefficient = userInputs.nonlinear_solver_parameters.getDefaultDampingCoefficient(var_index); - if (fields[var_index].type == SCALAR) - { - solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); - } - else - { - solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); - } + // if (fields[var_index].type == SCALAR) + // { + // solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_scalar); + // } + // else + // { + // solutionSet[var_index]->sadd(1.0, damping_coefficient, dU_vector); + // } } // Print linear???? @@ -288,14 +288,14 @@ MatrixFreePDE::nonlinearIncrement(unsigned int var_index, FeatureNotImplemented( "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); double diff = NAN; - if (fields[var_index].type == SCALAR) - { - diff = dU_scalar.l2_norm(); - } - else - { - diff = dU_vector.l2_norm(); - } + // if (fields[var_index].type == SCALAR) + // { + // diff = dU_scalar.l2_norm(); + // } + // else + // { + // diff = dU_vector.l2_norm(); + // } print_nonlinear_status(var_index, current_increment, nonlinear_iteration_index, diff); return !(diff > userInputs.nonlinear_solver_parameters.getToleranceValue(var_index)); } @@ -307,14 +307,14 @@ MatrixFreePDE::auxiliaryIncrement(unsigned int var_index, uint current_increment) { // Save the old solution - if (fields[var_index].type == SCALAR) - { - dU_scalar = *solutionSet[var_index]; - } - else - { - dU_vector = *solutionSet[var_index]; - } + // if (fields[var_index].type == SCALAR) + // { + // dU_scalar = *solutionSet[var_index]; + // } + // else + // { + // dU_vector = *solutionSet[var_index]; + // } auxiliaryOnce(var_index); @@ -324,16 +324,16 @@ MatrixFreePDE::auxiliaryIncrement(unsigned int var_index, FeatureNotImplemented( "Nonlinear solver tolerances besides ABSOLUTE_CHANGE")); double diff = NAN; - if (fields[var_index].type == SCALAR) - { - dU_scalar -= *solutionSet[var_index]; - diff = dU_scalar.l2_norm(); - } - else - { - dU_vector -= *solutionSet[var_index]; - diff = dU_vector.l2_norm(); - } + // if (fields[var_index].type == SCALAR) + // { + // dU_scalar -= *solutionSet[var_index]; + // diff = dU_scalar.l2_norm(); + // } + // else + // { + // dU_vector -= *solutionSet[var_index]; + // diff = dU_vector.l2_norm(); + // } print_nonlinear_update(var_index, current_increment); return !(diff > userInputs.nonlinear_solver_parameters.getToleranceValue(var_index)); } @@ -344,34 +344,35 @@ void MatrixFreePDE::applyBCs(unsigned int var_index) { // Add Neumann BCs - if (fields[var_index].hasNeumannBCs) - { - // Currently commented out because it isn't working yet - // applyNeumannBCs(); - } + // if (fields[var_index].hasNeumannBCs) + // { + // // Currently commented out because it isn't working yet + // // applyNeumannBCs(); + // } // Set the Dirichelet values (hanging node constraints don't need to be distributed // every time step, only at output) - if (fields[var_index].hasDirichletBCs) - { - // Apply non-uniform Dirlichlet_BCs to the current field - if (fields[var_index].hasnonuniformDirichletBCs) - { - // DoFHandler *dof_handler = dofHandlersSet_nonconst.at(currentvar_index); - // IndexSet *locally_relevant_dofs = - // locally_relevant_dofsSet_nonconst.at(currentvar_index); - // locally_relevant_dofs->clear(); - // DoFTools::extract_locally_relevant_dofs(*dof_handler, - // *locally_relevant_dofs); AffineConstraints *constraintsDirichlet = - // constraintsDirichletSet_nonconst.at(currentvar_index); - // constraintsDirichlet->clear(); - // constraintsDirichlet->reinit(*locally_relevant_dofs); - // applyDirichletBCs(); - // constraintsDirichlet->close(); - } - // Distribute for Uniform or Non-Uniform Dirichlet BCs - constraintsDirichletSet[var_index]->distribute(*solutionSet[var_index]); - } + // if (fields[var_index].hasDirichletBCs) + // { + // // Apply non-uniform Dirlichlet_BCs to the current field + // if (fields[var_index].hasnonuniformDirichletBCs) + // { + // // DoFHandler *dof_handler = + // dofHandlersSet_nonconst.at(currentvar_index); + // // IndexSet *locally_relevant_dofs = + // // locally_relevant_dofsSet_nonconst.at(currentvar_index); + // // locally_relevant_dofs->clear(); + // // DoFTools::extract_locally_relevant_dofs(*dof_handler, + // // *locally_relevant_dofs); AffineConstraints *constraintsDirichlet = + // // constraintsDirichletSet_nonconst.at(currentvar_index); + // // constraintsDirichlet->clear(); + // // constraintsDirichlet->reinit(*locally_relevant_dofs); + // // applyDirichletBCs(); + // // constraintsDirichlet->close(); + // } + // // Distribute for Uniform or Non-Uniform Dirichlet BCs + // constraintsDirichletSet[var_index]->distribute(*solutionSet[var_index]); + // } solutionSet[var_index]->update_ghost_values(); } @@ -383,42 +384,42 @@ MatrixFreePDE::updateExplicitSolution(unsigned int var_index) // Explicit-time step each DOF // Takes advantage of knowledge that the length of solutionSet and residualSet // is an integer multiple of the length of invM for vector variables - if (fields[var_index].type == SCALAR) - { - unsigned int invM_size = invMscalar.locally_owned_size(); - for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); - ++dof) - { - solutionSet[var_index]->local_element(dof) = - invMscalar.local_element(dof % invM_size) * - residualSet[var_index]->local_element(dof); - } - } - else if (fields[var_index].type == VECTOR) - { - unsigned int invM_size = invMvector.locally_owned_size(); - for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); - ++dof) - { - solutionSet[var_index]->local_element(dof) = - invMvector.local_element(dof % invM_size) * - residualSet[var_index]->local_element(dof); - } - } + // if (fields[var_index].type == SCALAR) + // { + // unsigned int invM_size = invMscalar.locally_owned_size(); + // for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); + // ++dof) + // { + // solutionSet[var_index]->local_element(dof) = + // invMscalar.local_element(dof % invM_size) * + // residualSet[var_index]->local_element(dof); + // } + // } + // else if (fields[var_index].type == VECTOR) + // { + // unsigned int invM_size = invMvector.locally_owned_size(); + // for (unsigned int dof = 0; dof < solutionSet[var_index]->locally_owned_size(); + // ++dof) + // { + // solutionSet[var_index]->local_element(dof) = + // invMvector.local_element(dof % invM_size) * + // residualSet[var_index]->local_element(dof); + // } + // } } template void MatrixFreePDE::updateLinearSolution(unsigned int var_index) { - if (fields[var_index].type == SCALAR) - { - *solutionSet[var_index] += dU_scalar; - } - else - { - *solutionSet[var_index] += dU_vector; - } + // if (fields[var_index].type == SCALAR) + // { + // *solutionSet[var_index] += dU_scalar; + // } + // else + // { + // *solutionSet[var_index] += dU_vector; + // } } template @@ -431,22 +432,22 @@ MatrixFreePDE::print_explicit_update(uint var_index, uint current_i { double solution_L2_norm = solutionSet[var_index]->l2_norm(); - snprintf(buffer, - sizeof(buffer), - "field '%2s' [explicit solve]: current solution: " - "%12.6e, current residual:%12.6e\n", - fields[var_index].name.c_str(), - solution_L2_norm, - residualSet[var_index]->l2_norm()); - conditionalOStreams::pout_base << buffer; + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' [explicit solve]: current solution: " + // "%12.6e, current residual:%12.6e\n", + // fields[var_index].name.c_str(), + // solution_L2_norm, + // residualSet[var_index]->l2_norm()); + // conditionalOStreams::pout_base << buffer; if (!numbers::is_finite(solution_L2_norm)) { - snprintf(buffer, - sizeof(buffer), - "ERROR: field '%s' solution is NAN. exiting.\n\n", - fields[var_index].name.c_str()); - conditionalOStreams::pout_base << buffer; + // snprintf(buffer, + // sizeof(buffer), + // "ERROR: field '%s' solution is NAN. exiting.\n\n", + // fields[var_index].name.c_str()); + // conditionalOStreams::pout_base << buffer; exit(-1); } } @@ -461,28 +462,28 @@ MatrixFreePDE::print_linear_update(uint var_index, if (current_increment % userInputs.skip_print_steps == 0) { double dU_norm = NAN; - if (fields[var_index].type == SCALAR) - { - dU_norm = dU_scalar.l2_norm(); - } - else - { - dU_norm = dU_vector.l2_norm(); - } + // if (fields[var_index].type == SCALAR) + // { + // dU_norm = dU_scalar.l2_norm(); + // } + // else + // { + // dU_norm = dU_vector.l2_norm(); + // } char buffer[200]; - snprintf(buffer, - sizeof(buffer), - "field '%2s' [linear solve]: initial " - "residual:%12.6e, current residual:%12.6e, " - "nsteps:%u, tolerance criterion:%12.6e, " - "solution: %12.6e, dU: %12.6e\n", - fields[var_index].name.c_str(), - residualSet[var_index]->l2_norm(), - solver_control.last_value(), - solver_control.last_step(), - solver_control.tolerance(), - solutionSet[var_index]->l2_norm(), - dU_norm); + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' [linear solve]: initial " + // "residual:%12.6e, current residual:%12.6e, " + // "nsteps:%u, tolerance criterion:%12.6e, " + // "solution: %12.6e, dU: %12.6e\n", + // fields[var_index].name.c_str(), + // residualSet[var_index]->l2_norm(), + // solver_control.last_value(), + // solver_control.last_step(), + // solver_control.tolerance(), + // solutionSet[var_index]->l2_norm(), + // dU_norm); conditionalOStreams::pout_base << buffer; } } @@ -495,13 +496,13 @@ MatrixFreePDE::print_nonlinear_update(uint var_index, uint current_ if (!(current_increment % userInputs.skip_print_steps)) { - snprintf(buffer, - sizeof(buffer), - "field '%2s' [nonlinear solve]: current " - "solution: %12.6e, current residual:%12.6e\n", - fields[var_index].name.c_str(), - solutionSet[var_index]->l2_norm(), - residualSet[var_index]->l2_norm()); + // snprintf(buffer, + // sizeof(buffer), + // "field '%2s' [nonlinear solve]: current " + // "solution: %12.6e, current residual:%12.6e\n", + // fields[var_index].name.c_str(), + // solutionSet[var_index]->l2_norm(), + // residualSet[var_index]->l2_norm()); conditionalOStreams::pout_base << buffer; } } @@ -516,15 +517,15 @@ MatrixFreePDE::print_nonlinear_status(uint var_index, if (!(current_increment % userInputs.skip_print_steps)) { char buffer[200]; - snprintf(buffer, - sizeof(buffer), - " field '%2s' [nonlinear solve] current increment: %u, nonlinear " - "iteration: " - "%u, dU: %12.6e\n", - fields[var_index].name.c_str(), - current_increment, - nonlinear_iteration_index, - diff); + // snprintf(buffer, + // sizeof(buffer), + // " field '%2s' [nonlinear solve] current increment: %u, nonlinear " + // "iteration: " + // "%u, dU: %12.6e\n", + // fields[var_index].name.c_str(), + // current_increment, + // nonlinear_iteration_index, + // diff); conditionalOStreams::pout_base << buffer; } } \ No newline at end of file diff --git a/src/grains/reassignGrains.cc b/src/grains/reassignGrains.cc index d41c5f7f..3990be62 100644 --- a/src/grains/reassignGrains.cc +++ b/src/grains/reassignGrains.cc @@ -31,30 +31,30 @@ MatrixFreePDE::reassignGrains() std::vector> grain_sets; unsigned int op_list_index = 0; - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - if (op_list_index < userInputs.variables_for_remapping.size()) - { - if (fieldIndex == userInputs.variables_for_remapping.at(op_list_index)) - { - op_list_index++; - - std::vector> single_OP_grain_sets; - flood_filler.calcGrainSets(*FESet.at(scalar_field_index), - *dofHandlersSet_nonconst.at(scalar_field_index), - solutionSet.at(fieldIndex), - userInputs.order_parameter_threshold, - 1.0 + userInputs.order_parameter_threshold, - 0, - fieldIndex, - single_OP_grain_sets); - - grain_sets.insert(grain_sets.end(), - single_OP_grain_sets.begin(), - single_OP_grain_sets.end()); - } - } - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + // { + // if (op_list_index < userInputs.variables_for_remapping.size()) + // { + // if (fieldIndex == userInputs.variables_for_remapping.at(op_list_index)) + // { + // op_list_index++; + + // std::vector> single_OP_grain_sets; + // flood_filler.calcGrainSets(*FESet.at(scalar_field_index), + // *dofHandlersSet_nonconst.at(scalar_field_index), + // solutionSet.at(fieldIndex), + // userInputs.order_parameter_threshold, + // 1.0 + userInputs.order_parameter_threshold, + // 0, + // fieldIndex, + // single_OP_grain_sets); + + // grain_sets.insert(grain_sets.end(), + // single_OP_grain_sets.begin(), + // single_OP_grain_sets.end()); + // } + // } + // } // Set the grain indices to unique values for (unsigned int g = 0; g < grain_sets.size(); g++) diff --git a/src/nucleation/nucleation.cc b/src/nucleation/nucleation.cc index 50885cd1..210abe2a 100644 --- a/src/nucleation/nucleation.cc +++ b/src/nucleation/nucleation.cc @@ -25,13 +25,14 @@ MatrixFreePDE::updateNucleiList() userInputs.nucleation_end_time) { // Apply constraints - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - constraintsDirichletSet[fieldIndex]->distribute( - *solutionSet[fieldIndex]); - constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); - solutionSet[fieldIndex]->update_ghost_values(); - } + // for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); + // fieldIndex++) + // { + // constraintsDirichletSet[fieldIndex]->distribute( + // *solutionSet[fieldIndex]); + // constraintsOtherSet[fieldIndex]->distribute(*solutionSet[fieldIndex]); + // solutionSet[fieldIndex]->update_ghost_values(); + // } std::vector> new_nuclei; if (currentIncrement == 1 && !userInputs.evolution_before_nucleation) diff --git a/src/utilities/CMakeLists.txt b/src/utilities/CMakeLists.txt index be0c80f3..e8104c5d 100644 --- a/src/utilities/CMakeLists.txt +++ b/src/utilities/CMakeLists.txt @@ -1,5 +1,4 @@ # Manually specify files to be included list(APPEND PRISMS_PF_SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/utilities.cc ) set(PRISMS_PF_SOURCE_FILES ${PRISMS_PF_SOURCE_FILES} PARENT_SCOPE) \ No newline at end of file diff --git a/src/utilities/utilities.cc b/src/utilities/utilities.cc deleted file mode 100644 index ed52bd84..00000000 --- a/src/utilities/utilities.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -// return index of given field name if exists, else throw error -template -unsigned int -MatrixFreePDE::getFieldIndex(std::string _name) -{ - for (const auto &field : fields) - { - if (field.name.compare(_name) == 0) - { - return field.index; - } - } - conditionalOStreams::pout_base << "\nutilities.h: field '" << _name.c_str() - << "' not initialized\n"; - exit(-1); -} - -INSTANTIATE_BI_TEMPLATE(MatrixFreePDE) \ No newline at end of file