diff --git a/.gitignore b/.gitignore index c8ad40df2..f9385a929 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ compile_commands.json *.exe *.out *.app +*.pbs #Output files *vtk diff --git a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6a/submit_mpi.pbs b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6a/submit_mpi.pbs deleted file mode 100644 index df5febc74..000000000 --- a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6a/submit_mpi.pbs +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -#### PBS preamble - -#PBS -l nodes=1:ppn=8,pmem=4gb,walltime=2:00:00 -#PBS -o out.txt -#PBS -e err.txt -#PBS -N chimad_bp2a -#PBS -V -#PBS -A kthorn_flux -#PBS -q flux -#PBS -l qos=flux - -# End PBS Settings -############################### - -# Change to the directory you submitted from -if [ -n "$PBS_O_WORKDIR" ]; then cd $PBS_O_WORKDIR; fi - -mkdir /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2a/ - -cp main /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2a/ -cp parameters.in /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2a/ - -cd /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2a/ - -# For mpi run -mpirun -n 8 ./main diff --git a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/customPDE.h b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/customPDE.h index 0d5dd1118..0c332d389 100644 --- a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/customPDE.h +++ b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/customPDE.h @@ -1,3 +1,6 @@ +#include +#include + #include "matrixFreePDE.h" using namespace dealii; @@ -105,48 +108,41 @@ void customPDE::makeTriangulation( parallel::distributed::Triangulation &tria) const { - parallel::distributed::Triangulation tria_box(MPI_COMM_WORLD), - tria_semicircle(MPI_COMM_WORLD); - if (dim == 3) - { - GridGenerator::subdivided_hyper_rectangle(tria_box, - userInputs.subdivisions, - Point(), - Point(userInputs.domain_size[0], - userInputs.domain_size[1], - userInputs.domain_size[2])); - } - else if (dim == 2) - { - GridGenerator::subdivided_hyper_rectangle(tria_box, - userInputs.subdivisions, - Point(), - Point(userInputs.domain_size[0], - userInputs.domain_size[1])); - } - else + parallel::distributed::Triangulation tria_box(MPI_COMM_WORLD); + parallel::distributed::Triangulation tria_semicircle(MPI_COMM_WORLD); + + // Check that dimensions match the benchmark + AssertThrow(dim == 2, ExcMessage("CHiMaD Benchmark 6b should only be run in 2D.")); + + // Create bounding points for each part of the triangulation + Point box_origin; + Point box_corner; + Point semicircle_origin; + + if (dim == 2) { - GridGenerator::subdivided_hyper_rectangle(tria_box, - userInputs.subdivisions, - Point(), - Point(userInputs.domain_size[0])); + box_corner = Point(userInputs.domain_size[0], userInputs.domain_size[1]); + semicircle_origin = + Point(userInputs.domain_size[0], userInputs.domain_size[1] / 2.0); } + GridGenerator::subdivided_hyper_rectangle(tria_box, + userInputs.subdivisions, + box_origin, + box_corner); + GridGenerator::half_hyper_ball(tria_semicircle, - Point(userInputs.domain_size[0], - userInputs.domain_size[1] / 2.0), + semicircle_origin, userInputs.domain_size[1] / 2.0); // Find the two non-corner vertices on the right side of the rectangular mesh - Point pt1, pt2; - typename parallel::distributed::Triangulation::active_cell_iterator - cell3 = tria_box.begin_active(), - endc3 = tria_box.end(); - for (; cell3 != endc3; ++cell3) + Point pt1; + Point pt2; + for (auto &cell : tria_box.active_cell_iterators()) { for (unsigned int i = 0; i < GeometryInfo::vertices_per_cell; ++i) { - Point &v = cell3->vertex(i); + Point &v = cell->vertex(i); if ((std::abs(v(0) - userInputs.domain_size[0]) < 1e-10) && (v(1) > userInputs.domain_size[1] / 2.0) && (v(1) < userInputs.domain_size[1] - 1.0e-10)) @@ -160,16 +156,14 @@ customPDE::makeTriangulation( } } } + // Move the vertices at the center of the half hyper ball so that they will // align with non-corner vertices on the right side of the rectangular mesh - typename parallel::distributed::Triangulation::active_cell_iterator - cell2 = tria_semicircle.begin_active(), - endc2 = tria_semicircle.end(); - for (; cell2 != endc2; ++cell2) + for (auto &cell : tria_semicircle.active_cell_iterators()) { for (unsigned int i = 0; i < GeometryInfo::vertices_per_cell; ++i) { - Point &v = cell2->vertex(i); + Point &v = cell->vertex(i); if ((std::abs(v(0) - userInputs.domain_size[0]) < 1e-10) && (v(1) > userInputs.domain_size[1] / 2.0) && (v(1) < userInputs.domain_size[1] - 1.0e-10)) @@ -183,69 +177,69 @@ customPDE::makeTriangulation( } } } + // Merge the rectangle and the semicircle GridGenerator::merge_triangulations(tria_box, tria_semicircle, tria); - // Attach a spherical manifold to the semicircular part of the domain so that - // it gets refined with rounded edges - static const SphericalManifold boundary( - Point(userInputs.domain_size[0], userInputs.domain_size[1] / 2.0)); - tria.set_manifold(8, boundary); + // Attach flat manifold to the entire domain + tria.reset_all_manifolds(); + tria.set_manifold(0, FlatManifold()); + tria.set_all_manifold_ids(0); + + // Attach spherical manifold + tria.set_manifold(8, SphericalManifold(semicircle_origin)); - typename parallel::distributed::Triangulation::active_cell_iterator - cell = tria.begin_active(), - endc = tria.end(); - for (; cell != endc; ++cell) + // Set the 3 outer cells of semicircle to the spherical manifold + for (const auto &cell : tria.active_cell_iterators()) { - for (unsigned int f = 0; f < GeometryInfo::faces_per_cell; ++f) + const Point cell_center = cell->center(); + const double distance_from_center = cell_center.distance(semicircle_origin); + + if (cell_center[0] > userInputs.domain_size[0] + 1.0e-10 && + distance_from_center > 0.1 * userInputs.domain_size[1]) { - const Point face_center = cell->face(f)->center(); - if (face_center[0] > userInputs.domain_size[0] + 1.0e-10) - { - cell->face(f)->set_all_manifold_ids(8); - if (face_center.distance(Point(userInputs.domain_size[0], - userInputs.domain_size[1] / 2.0)) > - 0.2 * userInputs.domain_size[1]) - { - cell->set_all_manifold_ids(8); - } - } + cell->set_all_manifold_ids(8); } } + // Transfinite interpolation + TransfiniteInterpolationManifold transfinite_manifold; + transfinite_manifold.initialize(tria); + tria.set_manifold(0, transfinite_manifold); + // Mark the boundaries - for (const auto &cell4 : tria.active_cell_iterators()) + for (const auto &cell : tria.active_cell_iterators()) { // Mark all of the faces for (unsigned int face_number = 0; face_number < GeometryInfo::faces_per_cell; ++face_number) { - if (cell4->face(face_number)->at_boundary()) + if (cell->face(face_number)->at_boundary()) { for (unsigned int i = 0; i < dim; i++) { if (i == 0) { - if (std::fabs(cell4->face(face_number)->center()(i) - (0)) < 1e-12) + if (std::fabs(cell->face(face_number)->center()(i) - (0)) < 1e-12) { - cell4->face(face_number)->set_boundary_id(2 * i); + cell->face(face_number)->set_boundary_id(2 * i); } - else if (std::fabs(cell4->face(face_number)->center()(i) > + else if (std::fabs(cell->face(face_number)->center()(i) > (userInputs.domain_size[i]))) { - cell4->face(face_number)->set_boundary_id(2 * i + 1); + cell->face(face_number)->set_boundary_id(2 * i + 1); } } else { - if (std::fabs(cell4->face(face_number)->center()(i) - (0)) < 1e-12) + if (std::fabs(cell->face(face_number)->center()(i) - (0)) < 1e-12) { - cell4->face(face_number)->set_boundary_id(2 * i); + cell->face(face_number)->set_boundary_id(2 * i); } - else if (std::fabs(cell4->face(face_number)->center()(i) - + else if (std::fabs(cell->face(face_number)->center()(i) - (userInputs.domain_size[i])) < 1e-12) { - cell4->face(face_number)->set_boundary_id(2 * i + 1); + cell->face(face_number)->set_boundary_id(2 * i + 1); } } } diff --git a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/parameters.prm b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/parameters.prm index d76bba216..7b5c6e4af 100644 --- a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/parameters.prm +++ b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/parameters.prm @@ -31,7 +31,7 @@ set Element degree = 2 # Set the time step parameters # ================================================================================= # The size of the time step -set Time step = 0.2e-4 +set Time step = 0.1e-4 # The simulation ends when either the number of time steps is reached or the # simulation time is reached. diff --git a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/submit_mpi.pbs b/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/submit_mpi.pbs deleted file mode 100644 index 4c0c1c6e4..000000000 --- a/applications/CHiMaD_benchmarks/CHiMaD_benchmark6b/submit_mpi.pbs +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -#### PBS preamble - -#PBS -l nodes=2:ppn=8,pmem=4gb,walltime=2:00:00 -#PBS -o out.txt -#PBS -e err.txt -#PBS -N chimad_bp2b -#PBS -V -#PBS -A kthorn_flux -#PBS -q flux -#PBS -l qos=flux - -# End PBS Settings -############################### - -# Change to the directory you submitted from -if [ -n "$PBS_O_WORKDIR" ]; then cd $PBS_O_WORKDIR; fi - -mkdir /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2b/ - -cp main /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2b/ -cp parameters.in /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2b/ - -cd /scratch/kthorn_flux/dmontiel/CH_electrostatics_bp_2b/ - -# For mpi run -mpirun -n 16 ./main diff --git a/applications/fickianDiffusion/integratedFields.txt b/applications/fickianDiffusion/integratedFields.txt deleted file mode 100644 index 0486bcf32..000000000 --- a/applications/fickianDiffusion/integratedFields.txt +++ /dev/null @@ -1,3 +0,0 @@ -0 c_x 0 -5 c_x -50.42273226 -10 c_x -71.00777182 diff --git a/applications/grainGrowth/integratedFields.txt b/applications/grainGrowth/integratedFields.txt deleted file mode 100644 index c57b33fb5..000000000 --- a/applications/grainGrowth/integratedFields.txt +++ /dev/null @@ -1,21 +0,0 @@ -0 diff1 6.302753372 -2 diff1 9.272165056 -4 diff1 10.48934769 -6 diff1 9.87554228 -8 diff1 8.068710441 -10 diff1 4.365246041 -12 diff1 3.011654139 -14 diff1 2.078855898 -16 diff1 1.452358016 -18 diff1 1.076649095 -20 diff1 0.8341042436 -22 diff1 0.4586567388 -24 diff1 0.3095193461 -26 diff1 0.2290179444 -28 diff1 0.1510074249 -30 diff1 0.05453975367 -32 diff1 -0.009341608481 -34 diff1 -0.009585723581 -36 diff1 -0.008783314296 -38 diff1 -0.008392747583 -40 diff1 -0.008305823929 diff --git a/applications/precipitateEvolution_pfunction/integratedFields.txt b/applications/precipitateEvolution_pfunction/integratedFields.txt deleted file mode 100644 index ba0faea6a..000000000 --- a/applications/precipitateEvolution_pfunction/integratedFields.txt +++ /dev/null @@ -1,2 +0,0 @@ -0 f_tot -2961.102683 -1.2 f_tot -2965.677538 diff --git a/applications/steadyStateAllenCahn/CMakeLists.txt b/applications/steadyStateAllenCahn/CMakeLists.txt deleted file mode 100644 index 31e2527fe..000000000 --- a/applications/steadyStateAllenCahn/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -## -# CMake script for the PRISMS-PF applications: -## - -cmake_minimum_required(VERSION 3.1.0) -project(myapp) - -# Find deal.II installation -find_package(deal.II 9.2.0 QUIET REQUIRED - HINTS ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR}) - -# Check to make sure deal.II is configured with p4est -if(NOT ${DEAL_II_WITH_P4EST}) - message(FATAL_ERROR "deal.II must be installed with p4est.") -endif() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() - -# Set default build type -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) -endif() - -# Set up the debug, release, and run targets -add_custom_target(debug - COMMAND +env ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug ${CMAKE_SOURCE_DIR} - COMMAND +env ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all - COMMENT "Switch CMAKE_BUILD_TYPE to Debug" - ) -add_custom_target(release - COMMAND +env ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR} - COMMAND +env ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all - COMMENT "Switch CMAKE_BUILD_TYPE to Release" - ) -add_custom_target(run COMMAND main - COMMENT "Run with ${CMAKE_BUILD_TYPE} configuration" - ) - -# Add postprocess.cc and nucleation.cc if they exist -if(EXISTS "postprocess.cc") - add_definitions(-DPOSTPROCESS_FILE_EXISTS) -endif() -if(EXISTS "nucleation.cc") - add_definitions(-DNUCLEATION_FILE_EXISTS) -endif() - -# 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(MAIN "${CMAKE_SOURCE_DIR}/../main.cc") - -# Add main.cc for executable target -add_executable(main ${MAIN}) - -# deal.II linker -DEAL_II_SETUP_TARGET(main) - -# Link libraries for the build type -if (${CMAKE_BUILD_TYPE} STREQUAL "Release") - target_link_libraries(main ${CMAKE_SOURCE_DIR}/../../libprisms_pf.a) -elseif(${CMAKE_BUILD_TYPE} STREQUAL "DebugRelease") - target_link_libraries(main ${CMAKE_SOURCE_DIR}/../../libprisms_pf.a) -else() - target_link_libraries(main ${CMAKE_SOURCE_DIR}/../../libprisms_pf_debug.a) -endif() diff --git a/applications/steadyStateAllenCahn/ICs_and_BCs.cc b/applications/steadyStateAllenCahn/ICs_and_BCs.cc deleted file mode 100644 index 1f4b62968..000000000 --- a/applications/steadyStateAllenCahn/ICs_and_BCs.cc +++ /dev/null @@ -1,56 +0,0 @@ -// =========================================================================== -// FUNCTION FOR INITIAL CONDITIONS -// =========================================================================== - -template -void -customPDE::setInitialCondition([[maybe_unused]] const Point &p, - [[maybe_unused]] const unsigned int index, - [[maybe_unused]] double &scalar_IC, - [[maybe_unused]] Vector &vector_IC) -{ - // --------------------------------------------------------------------- - // ENTER THE INITIAL CONDITIONS HERE - // --------------------------------------------------------------------- - // Enter the function describing conditions for the fields at point "p". - // Use "if" statements to set the initial condition for each variable - // according to its variable index - - if (index == 0) - { - scalar_IC = 0.5 * (1.0 - std::tanh((p[0] - 50.0) / 1.5)); - } - else - { - scalar_IC = p[0] / 200.0; - } -} - -// =========================================================================== -// FUNCTION FOR NON-UNIFORM DIRICHLET BOUNDARY CONDITIONS -// =========================================================================== - -template -void -customPDE::setNonUniformDirichletBCs( - [[maybe_unused]] const Point &p, - [[maybe_unused]] const unsigned int index, - [[maybe_unused]] const unsigned int direction, - [[maybe_unused]] const double time, - [[maybe_unused]] double &scalar_BC, - [[maybe_unused]] Vector &vector_BC) -{ - // -------------------------------------------------------------------------- - // ENTER THE NON-UNIFORM DIRICHLET BOUNDARY CONDITIONS HERE - // -------------------------------------------------------------------------- - // Enter the function describing conditions for the fields at point "p". - // Use "if" statements to set the boundary condition for each variable - // according to its variable index. This function can be left blank if there - // are no non-uniform Dirichlet boundary conditions. For BCs that change in - // time, you can access the current time through the variable "time". The - // boundary index can be accessed via the variable "direction", which starts - // at zero and uses the same order as the BC specification in parameters.in - // (i.e. left = 0, right = 1, bottom = 2, top = 3, front = 4, back = 5). - - // ------------------------------------------------------------------------- -} diff --git a/applications/steadyStateAllenCahn/customPDE.h b/applications/steadyStateAllenCahn/customPDE.h deleted file mode 100644 index 1ef1f2663..000000000 --- a/applications/steadyStateAllenCahn/customPDE.h +++ /dev/null @@ -1,90 +0,0 @@ -#include "matrixFreePDE.h" - -using namespace dealii; - -template -class customPDE : public MatrixFreePDE -{ -public: - // Constructor - customPDE(userInputParameters _userInputs) - : MatrixFreePDE(_userInputs) - , userInputs(_userInputs) {}; - - // Function to set the initial conditions (in ICs_and_BCs.h) - void - setInitialCondition([[maybe_unused]] const Point &p, - [[maybe_unused]] const unsigned int index, - [[maybe_unused]] double &scalar_IC, - [[maybe_unused]] Vector &vector_IC) override; - - // Function to set the non-uniform Dirichlet boundary conditions (in - // ICs_and_BCs.h) - void - setNonUniformDirichletBCs([[maybe_unused]] const Point &p, - [[maybe_unused]] const unsigned int index, - [[maybe_unused]] const unsigned int direction, - [[maybe_unused]] const double time, - [[maybe_unused]] double &scalar_BC, - [[maybe_unused]] Vector &vector_BC) override; - -private: -#include "typeDefs.h" - - const userInputParameters userInputs; - - // Function to set the RHS of the governing equations for explicit time - // dependent equations (in equations.h) - void - explicitEquationRHS( - [[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] Point> q_point_loc) const override; - - // Function to set the RHS of the governing equations for all other equations - // (in equations.h) - void - nonExplicitEquationRHS( - [[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] Point> q_point_loc) const override; - - // Function to set the LHS of the governing equations (in equations.h) - void - equationLHS( - [[maybe_unused]] variableContainer> - &variable_list, - [[maybe_unused]] Point> q_point_loc) const override; - -// Function to set postprocessing expressions (in postprocess.h) -#ifdef POSTPROCESS_FILE_EXISTS - void - postProcessedFields( - [[maybe_unused]] const variableContainer> - &variable_list, - [[maybe_unused]] variableContainer> - &pp_variable_list, - [[maybe_unused]] const Point> q_point_loc) - const override; -#endif - -// Function to set the nucleation probability (in nucleation.h) -#ifdef NUCLEATION_FILE_EXISTS - double - getNucleationProbability([[maybe_unused]] variableValueContainer variable_value, - [[maybe_unused]] double dV) const override; -#endif - - // ================================================================ - // Methods specific to this subclass - // ================================================================ - - // ================================================================ - // Model constants specific to this subclass - // ================================================================ - - double MnV = userInputs.get_model_constant_double("MnV"); - double KnV = userInputs.get_model_constant_double("KnV"); - - // ================================================================ -}; diff --git a/applications/steadyStateAllenCahn/equations.cc b/applications/steadyStateAllenCahn/equations.cc deleted file mode 100644 index ca2122204..000000000 --- a/applications/steadyStateAllenCahn/equations.cc +++ /dev/null @@ -1,159 +0,0 @@ -// ================================================================================= -// Set the attributes of the primary field variables -// ================================================================================= -// This function sets attributes for each variable/equation in the app. The -// attributes are set via standardized function calls. The first parameter for -// each function call is the variable index (starting at zero). The first set of -// variable/equation attributes are the variable name (any string), the variable -// type (SCALAR/VECTOR), and the equation type (EXPLICIT_TIME_DEPENDENT/ -// TIME_INDEPENDENT/AUXILIARY). The next set of attributes describe the -// dependencies for the governing equation on the values and derivatives of the -// other variables for the value term and gradient term of the RHS and the LHS. -// The final pair of attributes determine whether a variable represents a field -// that can nucleate and whether the value of the field is needed for nucleation -// rate calculations. - -void -variableAttributeLoader::loadVariableAttributes() -{ - // Variable 0 - set_variable_name(0, "n"); - set_variable_type(0, SCALAR); - set_variable_equation_type(0, EXPLICIT_TIME_DEPENDENT); - - set_dependencies_value_term_RHS(0, "n"); - set_dependencies_gradient_term_RHS(0, "grad(n)"); - - // Variable 1 - set_variable_name(1, "psi"); - set_variable_type(1, SCALAR); - set_variable_equation_type(1, TIME_INDEPENDENT); - - set_dependencies_value_term_RHS(1, "n, psi"); - set_dependencies_gradient_term_RHS(1, "grad(psi)"); - set_dependencies_value_term_LHS(1, "n, psi, change(psi)"); - set_dependencies_gradient_term_LHS(1, "grad(change(psi))"); -} - -// ============================================================================================= -// explicitEquationRHS (needed only if one or more equation is explict time -// dependent) -// ============================================================================================= -// This function calculates the right-hand-side of the explicit time-dependent -// equations for each variable. It takes "variable_list" as an input, which is a -// list of the value and derivatives of each of the variables at a specific -// quadrature point. The (x,y,z) location of that quadrature point is given by -// "q_point_loc". The function outputs two terms to variable_list -- one -// proportional to the test function and one proportional to the gradient of the -// test function. The index for each variable in this list corresponds to the -// index given at the top of this file. - -template -void -customPDE::explicitEquationRHS( - [[maybe_unused]] variableContainer> &variable_list, - [[maybe_unused]] Point> q_point_loc) const -{ - // --- Getting the values and derivatives of the model variables --- - - // The order parameter and its derivatives - scalarvalueType n = variable_list.get_scalar_value(0); - scalargradType nx = variable_list.get_scalar_gradient(0); - - // --- Setting the expressions for the terms in the governing equations --- - - scalarvalueType fnV = (4.0 * n * (n - 1.0) * (n - 0.5)); - scalarvalueType eq_n = (n - constV(userInputs.dtValue * MnV) * fnV); - scalargradType eqx_n = (-constV(userInputs.dtValue * KnV * MnV) * nx); - - // --- Submitting the terms for the governing equations --- - - variable_list.set_scalar_value_term_RHS(0, eq_n); - variable_list.set_scalar_gradient_term_RHS(0, eqx_n); -} - -// ============================================================================================= -// nonExplicitEquationRHS (needed only if one or more equation is time -// independent or auxiliary) -// ============================================================================================= -// This function calculates the right-hand-side of all of the equations that are -// not explicit time-dependent equations. It takes "variable_list" as an input, -// which is a list of the value and derivatives of each of the variables at a -// specific quadrature point. The (x,y,z) location of that quadrature point is -// given by "q_point_loc". The function outputs two terms to variable_list -- -// one proportional to the test function and one proportional to the gradient of -// the test function. The index for each variable in this list corresponds to -// the index given at the top of this file. - -template -void -customPDE::nonExplicitEquationRHS( - [[maybe_unused]] variableContainer> &variable_list, - [[maybe_unused]] Point> q_point_loc) const -{ - // --- Getting the values and derivatives of the model variables --- - - scalarvalueType n = variable_list.get_scalar_value(0); - - scalarvalueType psi = variable_list.get_scalar_value(1); - scalargradType psix = variable_list.get_scalar_gradient(1); - - // --- Setting the expressions for the terms in the governing equations --- - - scalarvalueType W = constV(1.0); - scalarvalueType p = constV(1.5); - scalarvalueType epsilon = constV(2.0); - - scalarvalueType eq_psi = (W * (-psi * psi * psi + psi - 2.0 * p * psi * n * n)); - scalargradType eqx_psi = (-epsilon * epsilon * psix); - - // --- Submitting the terms for the governing equations --- - - variable_list.set_scalar_value_term_RHS(1, eq_psi); - variable_list.set_scalar_gradient_term_RHS(1, eqx_psi); -} - -// ============================================================================================= -// equationLHS (needed only if at least one equation is time independent) -// ============================================================================================= -// This function calculates the left-hand-side of time-independent equations. It -// takes "variable_list" as an input, which is a list of the value and -// derivatives of each of the variables at a specific quadrature point. The -// (x,y,z) location of that quadrature point is given by "q_point_loc". The -// function outputs two terms to variable_list -- one proportional to the test -// function and one proportional to the gradient of the test function -- for the -// left-hand-side of the equation. The index for each variable in this list -// corresponds to the index given at the top of this file. If there are multiple -// elliptic equations, conditional statements should be sed to ensure that the -// correct residual is being submitted. The index of the field being solved can -// be accessed by "this->currentFieldIndex". - -template -void -customPDE::equationLHS( - [[maybe_unused]] variableContainer> &variable_list, - [[maybe_unused]] Point> q_point_loc) const -{ - // --- Getting the values and derivatives of the model variables --- - - scalarvalueType n = variable_list.get_scalar_value(0); - - scalarvalueType psi = variable_list.get_scalar_value(1); - - scalarvalueType Dpsi = variable_list.get_change_in_scalar_value(1); - scalargradType Dpsix = variable_list.get_change_in_scalar_gradient(1); - - // --- Setting the expressions for the terms in the governing equations --- - - scalarvalueType W = constV(1.0); - scalarvalueType p = constV(1.5); - scalarvalueType epsilon = constV(2.0); - scalarvalueType eq_Dpsi = - (W * (3.0 * psi * psi * Dpsi - Dpsi + 2.0 * p * Dpsi * n * n)); - scalargradType eqx_Dpsi = (epsilon * epsilon * Dpsix); - - // --- Submitting the terms for the governing equations --- - - variable_list.set_scalar_value_term_LHS(1, eq_Dpsi); - variable_list.set_scalar_gradient_term_LHS(1, eqx_Dpsi); -} diff --git a/applications/steadyStateAllenCahn/formulation_allenCahn.pdf b/applications/steadyStateAllenCahn/formulation_allenCahn.pdf deleted file mode 100644 index aa82cf7b1..000000000 Binary files a/applications/steadyStateAllenCahn/formulation_allenCahn.pdf and /dev/null differ diff --git a/applications/steadyStateAllenCahn/parameters.prm b/applications/steadyStateAllenCahn/parameters.prm deleted file mode 100644 index b433c4f30..000000000 --- a/applications/steadyStateAllenCahn/parameters.prm +++ /dev/null @@ -1,122 +0,0 @@ -# ================================================================================= -# Set the number of dimensions (2 or 3 for a 2D or 3D calculation) -# ================================================================================= -set Number of dimensions = 2 - -# ================================================================================= -# Set the length of the domain in all three dimensions -# (Domain size Z ignored in 2D) -# ================================================================================= -# Each axes spans from zero to the specified length -set Domain size X = 100 -set Domain size Y = 100 -set Domain size Z = 100 - -# ================================================================================= -# Set the element parameters -# ================================================================================= -# The number of elements in each direction is 2^(refineFactor) * subdivisions -# Subdivisions Z ignored in 2D -# For optimal performance, use refineFactor primarily to determine the element size -set Subdivisions X = 1 -set Subdivisions Y = 1 -set Subdivisions Z = 1 - -set Refine factor = 8 - -# Set the polynomial degree of the element (allowed values: 1, 2, or 3) -set Element degree = 1 - -# ================================================================================= -# Set the linear solver parameters -# ================================================================================= - -subsection Linear solver parameters: psi - # Whether the tolerance value is compared to the residual (ABSOLUTE_RESIDUAL) - # or the change in the residual (RELATIVE_RESIDUAL_CHANGE) - set Tolerance type = ABSOLUTE_RESIDUAL - - # The tolerance for convergence (L2 norm) - set Tolerance value = 1e-10 - - # The maximum number of linear solver iterations per solve - set Maximum linear solver iterations = 10000 -end - -# ================================================================================= -# Set the nonlinear solver parameters -# ================================================================================= - -set Maximum nonlinear solver iterations = 100 - -subsection Nonlinear solver parameters: psi - set Tolerance type = ABSOLUTE_SOLUTION_CHANGE - set Tolerance value = 1e-5 - set Use backtracking line search damping = false - set Backtracking step size modifier = 0.5 - set Backtracking residual decrease coefficient = 1.0 - set Constant damping value = 1.0 - set Use Laplace's equation to determine the initial guess = true -end - -# ================================================================================= -# Set the time step parameters -# ================================================================================= -# The size of the time step -set Time step = 1.0e-2 - -# The simulation ends when either the number of time steps is reached or the -# simulation time is reached. -set Number of time steps = 10 - -# ================================================================================= -# Set the output parameters -# ================================================================================= -# Type of spacing between outputs ("EQUAL_SPACING", "LOG_SPACING", "N_PER_DECADE", -# or "LIST") -set Output condition = EQUAL_SPACING - -# Number of times the program outputs the fields (total number for "EQUAL_SPACING" -# and "LOG_SPACING", number per decade for "N_PER_DECADE", ignored for "LIST") -set Number of outputs = 10 - -# The number of time steps between updates being printed to the screen -set Skip print steps = 1000 - -# ================================================================================= -# Set the boundary conditions -# ================================================================================= -# Set the boundary condition for each variable, where each variable is given by -# its name, as defined in equations.h. The four boundary condition -# types are NATURAL, DIRICHLET, NON_UNIFORM_DIRICHLET and PERIODIC. If all -# of the boundaries have the same boundary condition, only one boundary condition -# type needs to be given. If multiple boundary condition types are needed, give a -# comma-separated list of the types. The order is the miniumum of x, maximum of x, -# minimum of y, maximum of y, minimum of z, maximum of z (i.e left, right, bottom, -# top in 2D and left, right, bottom, top, front, back in 3D). The value of a -# Dirichlet BC is specfied in the following way -- DIRCHILET: val -- where 'val' is -# the desired value. If the boundary condition is NON_UNIFORM_DIRICHLET, the -# boundary condition should be specified in the appropriate function in 'ICs_and_BCs.h'. -# Example 1: All periodic BCs for variable 'c' -# set Boundary condition for variable c = PERIODIC -# Example 2: Zero-derivative BCs on the left and right, Dirichlet BCs with value -# 1.5 on the top and bottom for variable 'n' in 2D -# set Boundary condition for variable n = NATURAL, NATURAL, DIRICHLET: 1.5, DIRICHLET: 1.5 - -set Boundary condition for variable n = DIRICHLET: 1.0, DIRICHLET: 0.0, NATURAL, NATURAL -set Boundary condition for variable psi = DIRICHLET: 0.0, DIRICHLET: 1.0, NATURAL, NATURAL - -# ================================================================================= -# Set the model constants -# ================================================================================= -# Set the user-defined model constants, which must have a counter-part given in -# customPDE.h. These are most often used in the residual equations in equations.h, -# but may also be used for initial conditions and nucleation calculations. The type -# options currently are DOUBLE, INT, BOOL, TENSOR, and [symmetry] ELASTIC CONSTANTS -# where [symmetry] is ISOTROPIC, TRANSVERSE, ORTHOTROPIC, or ANISOTROPIC. - -# The mobility, MnV in equations.h -set Model constant MnV = 1.0, DOUBLE - -# The gradient energy coefficient, KnV in equations.h -set Model constant KnV = 2.0, DOUBLE diff --git a/applications/steadyStateAllenCahn/tex_files/allenCahn.tex b/applications/steadyStateAllenCahn/tex_files/allenCahn.tex deleted file mode 100644 index d2b763351..000000000 --- a/applications/steadyStateAllenCahn/tex_files/allenCahn.tex +++ /dev/null @@ -1,223 +0,0 @@ -\documentclass[10pt]{article} -\usepackage{amsmath} -\usepackage{bm} -\usepackage{bbm} -\usepackage{mathrsfs} -\usepackage{graphicx} -\usepackage{wrapfig} -\usepackage{subcaption} -\usepackage{epsfig} -\usepackage{amsfonts} -\usepackage{amssymb} -\usepackage{amsmath} -\usepackage{wrapfig} -\usepackage{graphicx} -\usepackage{psfrag} -\newcommand{\sun}{\ensuremath{\odot}} % sun symbol is \sun -\let\vaccent=\v % rename builtin command \v{} to \vaccent{} -\renewcommand{\v}[1]{\ensuremath{\mathbf{#1}}} % for vectors -\newcommand{\gv}[1]{\ensuremath{\mbox{\boldmath$ #1 $}}} -\newcommand{\grad}[1]{\gv{\nabla} #1} -\renewcommand{\baselinestretch}{1.2} -\jot 5mm -\graphicspath{{./figures/}} -%text dimensions -\textwidth 6.5 in -\oddsidemargin .2 in -\topmargin -0.2 in -\textheight 8.5 in -\headheight 0.2in -\overfullrule = 0pt -\pagestyle{plain} -\def\newpar{\par\vskip 0.5cm} -\begin{document} -% -%---------------------------------------------------------------------- -% Define symbols -%---------------------------------------------------------------------- -% -\def\iso{\mathbbm{1}} -\def\half{{\textstyle{1 \over 2}}} -\def\third{{\textstyle{1 \over 3}}} -\def\fourth{{\textstyle{{1 \over 4}}}} -\def\twothird{{\textstyle {{2 \over 3}}}} -\def\ndim{{n_{\rm dim}}} -\def\nint{n_{\rm int}} -\def\lint{l_{\rm int}} -\def\nel{n_{\rm el}} -\def\nf{n_{\rm f}} -\def\DIV {\hbox{\af div}} -\def\GRAD{\hbox{\af Grad}} -\def\sym{\mathop{\rm sym}\nolimits} -\def\tr{\mathop{\rm tr}\nolimits} -\def\dev{\mathop{\rm dev}\nolimits} -\def\Dev{\mathop{\rm Dev}\nolimits} -\def\DEV{\mathop {\rm DEV}\nolimits} -\def\bfb {{\bi b}} -\def\Bnabla{\nabla} -\def\bG{{\bi G}} -\def\jmpdelu{{\lbrack\!\lbrack \Delta u\rbrack\!\rbrack}} -\def\jmpudot{{\lbrack\!\lbrack\dot u\rbrack\!\rbrack}} -\def\jmpu{{\lbrack\!\lbrack u\rbrack\!\rbrack}} -\def\jmphi{{\lbrack\!\lbrack\varphi\rbrack\!\rbrack}} -\def\ljmp{{\lbrack\!\lbrack}} -\def\rjmp{{\rbrack\!\rbrack}} -\def\sign{{\rm sign}} -\def\nn{{n+1}} -\def\na{{n+\vartheta}} -\def\nna{{n+(1-\vartheta)}} -\def\nt{{n+{1\over 2}}} -\def\nb{{n+\beta}} -\def\nbb{{n+(1-\beta)}} -%--------------------------------------------------------- -% Bold Face Math Characters: -% All In Format: \B***** . -%--------------------------------------------------------- -\def\bOne{\mbox{\boldmath$1$}} -\def\BGamma{\mbox{\boldmath$\Gamma$}} -\def\BDelta{\mbox{\boldmath$\Delta$}} -\def\BTheta{\mbox{\boldmath$\Theta$}} -\def\BLambda{\mbox{\boldmath$\Lambda$}} -\def\BXi{\mbox{\boldmath$\Xi$}} -\def\BPi{\mbox{\boldmath$\Pi$}} -\def\BSigma{\mbox{\boldmath$\Sigma$}} -\def\BUpsilon{\mbox{\boldmath$\Upsilon$}} -\def\BPhi{\mbox{\boldmath$\Phi$}} -\def\BPsi{\mbox{\boldmath$\Psi$}} -\def\BOmega{\mbox{\boldmath$\Omega$}} -\def\Balpha{\mbox{\boldmath$\alpha$}} -\def\Bbeta{\mbox{\boldmath$\beta$}} -\def\Bgamma{\mbox{\boldmath$\gamma$}} -\def\Bdelta{\mbox{\boldmath$\delta$}} -\def\Bepsilon{\mbox{\boldmath$\epsilon$}} -\def\Bzeta{\mbox{\boldmath$\zeta$}} -\def\Beta{\mbox{\boldmath$\eta$}} -\def\Btheta{\mbox{\boldmath$\theta$}} -\def\Biota{\mbox{\boldmath$\iota$}} -\def\Bkappa{\mbox{\boldmath$\kappa$}} -\def\Blambda{\mbox{\boldmath$\lambda$}} -\def\Bmu{\mbox{\boldmath$\mu$}} -\def\Bnu{\mbox{\boldmath$\nu$}} -\def\Bxi{\mbox{\boldmath$\xi$}} -\def\Bpi{\mbox{\boldmath$\pi$}} -\def\Brho{\mbox{\boldmath$\rho$}} -\def\Bsigma{\mbox{\boldmath$\sigma$}} -\def\Btau{\mbox{\boldmath$\tau$}} -\def\Bupsilon{\mbox{\boldmath$\upsilon$}} -\def\Bphi{\mbox{\boldmath$\phi$}} -\def\Bchi{\mbox{\boldmath$\chi$}} -\def\Bpsi{\mbox{\boldmath$\psi$}} -\def\Bomega{\mbox{\boldmath$\omega$}} -\def\Bvarepsilon{\mbox{\boldmath$\varepsilon$}} -\def\Bvartheta{\mbox{\boldmath$\vartheta$}} -\def\Bvarpi{\mbox{\boldmath$\varpi$}} -\def\Bvarrho{\mbox{\boldmath$\varrho$}} -\def\Bvarsigma{\mbox{\boldmath$\varsigma$}} -\def\Bvarphi{\mbox{\boldmath$\varphi$}} -\def\bone{\mathbf{1}} -\def\bzero{\mathbf{0}} -%--------------------------------------------------------- -% Bold Face Math Italic: -% All In Format: \b* . -%--------------------------------------------------------- -\def\bA{\mbox{\boldmath$ A$}} -\def\bB{\mbox{\boldmath$ B$}} -\def\bC{\mbox{\boldmath$ C$}} -\def\bD{\mbox{\boldmath$ D$}} -\def\bE{\mbox{\boldmath$ E$}} -\def\bF{\mbox{\boldmath$ F$}} -\def\bG{\mbox{\boldmath$ G$}} -\def\bH{\mbox{\boldmath$ H$}} -\def\bI{\mbox{\boldmath$ I$}} -\def\bJ{\mbox{\boldmath$ J$}} -\def\bK{\mbox{\boldmath$ K$}} -\def\bL{\mbox{\boldmath$ L$}} -\def\bM{\mbox{\boldmath$ M$}} -\def\bN{\mbox{\boldmath$ N$}} -\def\bO{\mbox{\boldmath$ O$}} -\def\bP{\mbox{\boldmath$ P$}} -\def\bQ{\mbox{\boldmath$ Q$}} -\def\bR{\mbox{\boldmath$ R$}} -\def\bS{\mbox{\boldmath$ S$}} -\def\bT{\mbox{\boldmath$ T$}} -\def\bU{\mbox{\boldmath$ U$}} -\def\bV{\mbox{\boldmath$ V$}} -\def\bW{\mbox{\boldmath$ W$}} -\def\bX{\mbox{\boldmath$ X$}} -\def\bY{\mbox{\boldmath$ Y$}} -\def\bZ{\mbox{\boldmath$ Z$}} -\def\ba{\mbox{\boldmath$ a$}} -\def\bb{\mbox{\boldmath$ b$}} -\def\bc{\mbox{\boldmath$ c$}} -\def\bd{\mbox{\boldmath$ d$}} -\def\be{\mbox{\boldmath$ e$}} -\def\bff{\mbox{\boldmath$ f$}} -\def\bg{\mbox{\boldmath$ g$}} -\def\bh{\mbox{\boldmath$ h$}} -\def\bi{\mbox{\boldmath$ i$}} -\def\bj{\mbox{\boldmath$ j$}} -\def\bk{\mbox{\boldmath$ k$}} -\def\bl{\mbox{\boldmath$ l$}} -\def\bm{\mbox{\boldmath$ m$}} -\def\bn{\mbox{\boldmath$ n$}} -\def\bo{\mbox{\boldmath$ o$}} -\def\bp{\mbox{\boldmath$ p$}} -\def\bq{\mbox{\boldmath$ q$}} -\def\br{\mbox{\boldmath$ r$}} -\def\bs{\mbox{\boldmath$ s$}} -\def\bt{\mbox{\boldmath$ t$}} -\def\bu{\mbox{\boldmath$ u$}} -\def\bv{\mbox{\boldmath$ v$}} -\def\bw{\mbox{\boldmath$ w$}} -\def\bx{\mbox{\boldmath$ x$}} -\def\by{\mbox{\boldmath$ y$}} -\def\bz{\mbox{\boldmath$ z$}} -%********************************* -%Start main paper -%********************************* -\centerline{\Large{\bf PRISMS PhaseField}} -\smallskip -\centerline{\Large{\bf Allen-Cahn Dynamics}} -\bigskip -Consider a free energy expression of the form: -\begin{equation} - \Pi(\eta, \grad \eta) = \int_{\Omega} f( \eta ) + \frac{\kappa}{2} \grad \eta \cdot \grad \eta ~dV -\end{equation} -where $\eta$ is the structural order parameter, and $\kappa$ is the gradient length scale parameter. - -\section{Variational treatment} -Considering variations on the primal field $\eta$ of the from $\eta+\epsilon w$, we have -\begin{align} -\delta \Pi &= \left. \frac{d}{d\epsilon} \int_{\Omega} f(\eta+\epsilon w) + \frac{\kappa}{2} \grad (\eta+\epsilon w) \cdot ~\grad (\eta+\epsilon w) ~dV \right\vert_{\epsilon=0} \\ -&= \int_{\Omega} w f_{,\eta} + \kappa \grad w \grad \eta ~dV \\ -&= \int_{\Omega} w \left( f_{,\eta} - \kappa \Delta \eta \right) ~dV + \int_{\partial \Omega} w \kappa \grad \eta \cdot n ~dS -\end{align} -Assuming $\kappa \grad \eta \cdot n = 0$, and using standard variational arguments on the equation $\delta \Pi =0$ we have the expression for chemical potential as -\begin{equation} - \mu = f_{,\eta} - \kappa \Delta \eta -\end{equation} - -\section{Kinetics} -Now the Parabolic PDE for Allen-Cahn dynamics is given by: -\begin{align} - \frac{\partial \eta}{\partial t} &= -M~(f_{,\eta} - \kappa \Delta \eta) -\end{align} -where $M$ is the constant mobility. -\section{Time discretization} -Considering forward Euler explicit time stepping, we have the time discretized kinetics equation: -\begin{align} - \eta^{n+1} &= \eta^{n} - \Delta t M~(f_{,\eta}^{n} - \kappa \Delta \eta^{n}) -\end{align} - -\section{Weak formulation} -In the weak formulation, considering an arbitrary variation $w$, the above equation can be expressed as a residual equation: -\begin{align} -\int_{\Omega} w \eta^{n+1} ~dV&= \int_{\Omega} w \eta^{n} - w \Delta t M~(f_{,\eta}^{n} - \kappa \Delta \eta^{n}) ~dV \\ -&= \int_{\Omega} w ( \underbrace{ \eta^{n} - \Delta t M~f_{,\eta}^{n} }_{r_{\eta}} ) + \grad w \underbrace{ (-\Delta t M \kappa)~ \cdot (\grad \eta^{n})}_{r_{\eta x}} ~dV \quad [\kappa \grad \eta \cdot n = 0 \quad \text{on} \quad \partial \Omega] -\end{align} -\vskip 0.25in -The above values of $r_{\eta}$ and $r_{\eta x}$ are used to define the residuals in the following parameters file: \\ -\textit{applications/allenCahn/parameters.h} - - -\end{document} \ No newline at end of file diff --git a/src/inputFileReader/inputFileReader.cc b/src/inputFileReader/inputFileReader.cc index 00e4f644b..7b474dcfe 100644 --- a/src/inputFileReader/inputFileReader.cc +++ b/src/inputFileReader/inputFileReader.cc @@ -555,7 +555,7 @@ inputFileReader::declare_parameters(dealii::ParameterHandler ¶meter_hand "The list of time steps to save checkpoints, used for the LIST type."); parameter_handler.declare_entry( "Number of checkpoints", - "1", + "0", dealii::Patterns::Integer(), "The number of checkpoints (or number of checkpoints per decade for the " "N_PER_DECADE type)."); diff --git a/src/matrixfree/AdaptiveRefinement.cc b/src/matrixfree/AdaptiveRefinement.cc index 4c2418af3..e618bd4ee 100644 --- a/src/matrixfree/AdaptiveRefinement.cc +++ b/src/matrixfree/AdaptiveRefinement.cc @@ -51,7 +51,7 @@ AdaptiveRefinement::adaptive_refinement_criterion() const unsigned int num_quad_points = quadrature.size(); // Set the update flags - dealii::UpdateFlags update_flags; + dealii::UpdateFlags update_flags = update_default; for (const auto &criterion : userInputs.refinement_criteria) { if (criterion.criterion_type & criterion_value) diff --git a/src/matrixfree/computeLHS.cc b/src/matrixfree/computeLHS.cc index 2606b1ade..322e51f67 100644 --- a/src/matrixfree/computeLHS.cc +++ b/src/matrixfree/computeLHS.cc @@ -35,8 +35,15 @@ MatrixFreePDE::vmult(vectorType &dst, const vectorType &src) const true); } - // Account for Dirichlet BC's - constraintsDirichletSet[currentFieldIndex]->distribute(dst); + // 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); + } + } // end log computing_timer.leave_subsection("matrixFreePDE: computeLHS"); diff --git a/src/userInputParameters/setTimeStepList.cc b/src/userInputParameters/setTimeStepList.cc index fc48cebb3..f38414cf8 100644 --- a/src/userInputParameters/setTimeStepList.cc +++ b/src/userInputParameters/setTimeStepList.cc @@ -9,7 +9,11 @@ userInputParameters::setTimeStepList( { std::vector timeStepList; - if (numberOfOutputs > 0) + if (outputSpacingType == "LIST") + { + timeStepList = userGivenTimeStepList; + } + else if (numberOfOutputs > 0) { if (outputSpacingType == "EQUAL_SPACING") { @@ -48,10 +52,6 @@ userInputParameters::setTimeStepList( } } } - else if (outputSpacingType == "LIST") - { - timeStepList = userGivenTimeStepList; - } else { // I'm not sure why this is set up this way. It seems like the intuitive diff --git a/tests/automatic_tests/application_debug_test.py b/tests/automatic_tests/application_debug_test.py new file mode 100644 index 000000000..37db86151 --- /dev/null +++ b/tests/automatic_tests/application_debug_test.py @@ -0,0 +1,248 @@ +import os +import subprocess +import shutil +import glob +from concurrent.futures import ProcessPoolExecutor + + +def does_filepath_exist(filepath): + """Function to check that a certain filepath exists + + Args: + filepath (string): The absolute filepath + + Raises: + FileNotFoundError: An error if the filepath does not exist + + Returns: + Bool: Whether the filepath exists + """ + if os.path.exists(filepath): + return True + else: + raise FileNotFoundError(f"{filepath} does not exist") + + +def get_application_path(app_name): + """Function that returns that absolute path for the specified application + + Args: + app_name (string): The application name + + Returns: + String: Absolute application path + """ + # Current directory + pwd = os.getcwd() + + # Check that we're in the automatic test directory + assert ( + "tests/automatic_tests" in pwd + ), "Current directory is not within 'tests/automatic_tests'" + + # Application path assuming file structure matches GitHub repo + app_path = pwd.replace("tests/automatic_tests", f"applications/{app_name}") + + return app_path + + +def set_timestep(number, app_dir, new_parameter_file): + """Function that write create a copy of the of the parameters.prm file + in the given application directory and set the number of timesteps + + Args: + number (int): Number of timesteps + app_dir (string): Absolute filepath for application directory + new_parameter_file (string): Name of new parameters.prm + """ + # Absolute path of the parameters file + parameter_file_path = os.path.join(app_dir, "parameters.prm") + + # Check that the filepath exists + does_filepath_exist(parameter_file_path) + + # Make a copy of the original parameters file + new_parameter_file_path = os.path.join(app_dir, new_parameter_file) + shutil.copy(parameter_file_path, new_parameter_file_path) + print(f"Copied {parameter_file_path} to {new_parameter_file_path}.") + + # Set the new number of timesteps, making sure to remove simulation end time if there + with open(new_parameter_file_path, "r") as file: + lines = file.readlines() + + set_n_timesteps = False + with open(new_parameter_file_path, "w") as file: + for line in lines: + if "set Number of time steps" in line and not set_n_timesteps: + file.write(f"set Number of time steps = {number}\n") + set_n_timesteps = True + elif "set Simulation end time" in line and not set_n_timesteps: + file.write(f"set Number of time steps = {number}\n") + set_n_timesteps = True + elif "set Simulation end time" in line and set_n_timesteps: + file.write("\n") + else: + file.write(line) + print( + f"Updated {new_parameter_file} in {app_dir} to set Number of time steps to {number}." + ) + + +def compile_and_run(app_name, new_parameter_file, test_dir): + """Function that compile and runs the application in debug mode + + Args: + app_name (string): Application name + new_parameter_file (string): Parameter file + test_dir (string): Automatic test directory + + Returns: + String: Whether the application was able to succeed or not. The first return + is the application name and the second is success or failure + """ + try: + # Navigate to tests/automatic_tests + os.chdir(test_dir) + + # Grab application path + app_dir = get_application_path(app_name) + + # Navigate to application directory + os.chdir(app_dir) + print(f"Currently in {os.getcwd()}") + + # Compile the application in debug mode + if os.path.exists("CMakeCache.txt"): + os.remove("CMakeCache.txt") + print(f"Compiling {app_dir}") + compile_result = subprocess.run( + ["cmake", "."], check=True, capture_output=True, text=True + ) + make_result = subprocess.run( + ["make", "debug"], check=True, capture_output=True, text=True + ) + + # Run the application + print(f"Running {app_dir} with parameter file {new_parameter_file}") + run_result = subprocess.run( + ["mpirun", "-n", "1", "./main", "-i", new_parameter_file], + check=True, + capture_output=True, + text=True, + ) + + # Clean up + print(f"Cleaning up {app_dir}") + os.remove("CMakeCache.txt") + os.remove("main") + if os.path.exists("integratedFields.txt"): + os.remove("integratedFields.txt") + for solution_file in glob.glob("solution-*.vtu"): + os.remove(solution_file) + for restart_file in glob.glob("restart.*"): + os.remove(restart_file) + os.remove(new_parameter_file) + + # Return success + return ( + app_name, + "Success", + compile_result.stdout + make_result.stdout + run_result.stdout, + ) + + except subprocess.CalledProcessError as exc: + error_output = exc.stderr if exc.stderr else str(exc) + return (app_name, f"Failed: {error_output}", "") + + except Exception as exc: + return (app_name, f"Failed: {str(exc)}", "") + + +def run_tests_in_parallel(application_list): + """Run each test in parallel + + Args: + application_list (list): A list of application names + + Returns: + Dict: Dictionary that track the success/failure of each application + """ + # Parameter file name + new_parameter_file = "parameters_new.prm" + + # Grab currnet directory which should be the automatic test directory + test_dir = os.getcwd() + + # Update parameter file for one timestep + for app_name in application_list: + # Grab application path + app_dir = get_application_path(app_name) + + # Set timestep + set_timestep(1, app_dir, new_parameter_file) + + # Dictionary for results + results = {} + + # Run each task in parallel + with ProcessPoolExecutor() as executor: + futures = [ + executor.submit(compile_and_run, app_name, new_parameter_file, test_dir) + for app_name in application_list + ] + for future in futures: + app_name, status, output = future.result() + results[app_name] = (status, output) + + return results + + +# Application list +application_list = [ + "CHAC_anisotropy", + "corrosion", + "CHAC_anisotropyRegularized", + "corrosion_microgalvanic", + "coupledCahnHilliardAllenCahn", + "dendriticSolidification", + "eshelbyInclusion", + "fickianDiffusion", + "grainGrowth", + "grainGrowth_dream3d", + "mechanics", + "MgNd_precipitate_single_Bppp", + "nucleationModel", + "allenCahn", + "nucleationModel_preferential", + "allenCahn_conserved", + "alloySolidification", + "precipitateEvolution", + "precipitateEvolution_pfunction", + "alloySolidification_uniform", + "spinodalDecomposition", + "anisotropyFacet", + "cahnHilliard", + "CHiMaD_benchmarks/CHiMaD_benchmark1a", + "CHiMaD_benchmarks/CHiMaD_benchmark1b", + "CHiMaD_benchmarks/CHiMaD_benchmark1c", + "CHiMaD_benchmarks/CHiMaD_benchmark2a", + "CHiMaD_benchmarks/CHiMaD_benchmark3a", + "CHiMaD_benchmarks/CHiMaD_benchmark6a", + "CHiMaD_benchmarks/CHiMaD_benchmark7a", +] + +# Run tests in parallel +results = run_tests_in_parallel(application_list) + +# Print the results +print("\n\nCompilation and Execution Results:") +passed_count = 0 + +for app_name, (status, output) in results.items(): + print(f"{app_name}: {status}") + if status == "Success": + passed_count += 1 + else: + print(f"Error details:\n{output}\n") + +print(f"\nTotal applications passed: {passed_count} out of {len(results)}")