diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0422f5d3..8000ea266 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,7 @@ variables: # integration tests - echo -e "section_start:$(date +%s):src_build_and_unit_test\r\e[0K Source Build and Unit Tests ${CI_PROJECT_NAME}" - - ${ALLOC_COMMAND} scripts/gitlab/build_and_test.sh + - ./scripts/gitlab/build_and_test.sh - echo -e "section_end:$(date +%s):src_build_and_unit_test\r\e[0K" artifacts: expire_in: 2 weeks @@ -65,10 +65,9 @@ variables: reports: junit: ${FULL_BUILD_ROOT}/${SYS_TYPE}/*/_serac_build_and_test_*/build-*/junit.xml -# This is where jobs are included for each machine +# This is where jobs are included for each system include: - - local: .gitlab/build_lassen.yml - # Note: Cannot move to ruby until users have access to eng bank - - local: .gitlab/build_quartz.yml + - local: .gitlab/build_blueos.yml + - local: .gitlab/build_toss4.yml - project: 'lc-templates/id_tokens' file: 'id_tokens.yml' diff --git a/.gitlab/build_lassen.yml b/.gitlab/build_blueos.yml similarity index 72% rename from .gitlab/build_lassen.yml rename to .gitlab/build_blueos.yml index 48d82cbf8..595c90181 100644 --- a/.gitlab/build_lassen.yml +++ b/.gitlab/build_blueos.yml @@ -1,17 +1,17 @@ #### -# This is the share configuration of jobs for lassen -.on_lassen: +# This is the share configuration of jobs for blueos +.on_blueos: variables: SCHEDULER_PARAMETERS: -nnodes ${ALLOC_NODES} -W ${ALLOC_TIME} -q pci -G ${ALLOC_BANK} tags: - batch - lassen rules: - - if: '$CI_COMMIT_BRANCH =~ /_lnone/ || $ON_LASSEN == "OFF"' #run except if ... + - if: '$CI_COMMIT_BRANCH =~ /_lnone/ || $ON_BLUEOS == "OFF"' #run except if ... when: never - when: on_success before_script: - # python3.8 is needed on lassen to avoid trampling on the x86 clingo wheel + # python3.8 is needed on blueos to avoid trampling on the x86 clingo wheel - module load python/3.8 # CMake >= 3.17 is needed for FindCUDAToolkit with caliper # We could also extract the CMake executable location from the hostconfig in common_build_functions @@ -29,32 +29,32 @@ #### # Template -.src_build_on_lassen: - extends: [.src_build_script, .on_lassen, .src_workflow] +.src_build_on_blueos: + extends: [.src_build_script, .on_blueos, .src_workflow] needs: [] -.full_build_on_lassen: - extends: [.full_build_script, .on_lassen, .full_workflow] +.full_build_on_blueos: + extends: [.full_build_script, .on_blueos, .full_workflow] needs: [] #### # Build jobs -lassen-clang_10_0_1-src: +blueos-clang_10_0_1-src: variables: COMPILER: "clang@10.0.1" HOST_CONFIG: "lassen-blueos_3_ppc64le_ib_p9-${COMPILER}.cmake" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON -DENABLE_DOCS=OFF" ALLOC_NODES: "1" ALLOC_TIME: "30" - extends: [.src_build_on_lassen, .with_cuda] + extends: [.src_build_on_blueos, .with_cuda] # Note: to reduce duplication SPEC is not defined here, if we move to more than one -# spec on lassen add it back like quartz -lassen-clang_10_0_1-full: +# spec on blueos add it back like toss4 +blueos-clang_10_0_1-full: variables: COMPILER: "clang@10.0.1" HOST_CONFIG: "lassen-blueos_3_ppc64le_ib_p9-${COMPILER}.cmake" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON -DENABLE_DOCS=OFF" ALLOC_NODES: "1" ALLOC_TIME: "55" - extends: [.full_build_on_lassen, .with_cuda] + extends: [.full_build_on_blueos, .with_cuda] diff --git a/.gitlab/build_quartz.yml b/.gitlab/build_toss4.yml similarity index 74% rename from .gitlab/build_quartz.yml rename to .gitlab/build_toss4.yml index dc4ea0563..5323535a5 100644 --- a/.gitlab/build_quartz.yml +++ b/.gitlab/build_toss4.yml @@ -1,6 +1,6 @@ #### -# This is the shared configuration of jobs for quartz -.on_quartz: +# This is the shared configuration of jobs for toss4 +.on_toss4: variables: # TODO Re-add eng bank to scheduler parameters once all users have the bank on ruby # -A ${ALLOC_BANK} @@ -9,7 +9,7 @@ - batch - ruby rules: - - if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_QUARTZ == "OFF"' #run except if ... + - if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_TOSS4 == "OFF"' #run except if ... when: never before_script: # We could also extract the CMake executable location from the hostconfig in common_build_functions @@ -19,12 +19,12 @@ #### # Templates -.src_build_on_quartz: - extends: [.src_build_script, .on_quartz, .src_workflow] +.src_build_on_toss4: + extends: [.src_build_script, .on_toss4, .src_workflow] needs: [] -.full_build_on_quartz: - extends: [.full_build_script, .on_quartz, .full_workflow] +.full_build_on_toss4: + extends: [.full_build_script, .on_toss4, .full_workflow] needs: [] before_script: # LC version of pip is ancient @@ -35,7 +35,7 @@ # Build jobs # Only run integration tests on one spec -quartz-clang_14_0_6-src: +toss4-clang_14_0_6-src: variables: COMPILER: "clang@14.0.6" HOST_CONFIG: "quartz-toss_4_x86_64_ib-${COMPILER}.cmake" @@ -43,49 +43,49 @@ quartz-clang_14_0_6-src: DO_INTEGRATION_TESTS: "yes" ALLOC_NODES: "2" ALLOC_TIME: "30" - extends: .src_build_on_quartz + extends: .src_build_on_toss4 -quartz-gcc_10_3_1-src: +toss4-gcc_10_3_1-src: variables: COMPILER: "gcc@10.3.1" HOST_CONFIG: "quartz-toss_4_x86_64_ib-${COMPILER}.cmake" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON" ALLOC_NODES: "1" ALLOC_TIME: "30" - extends: .src_build_on_quartz + extends: .src_build_on_toss4 -quartz-gcc_10_3_1-src-no-tribol: +toss4-gcc_10_3_1-src-no-tribol: variables: COMPILER: "gcc@10.3.1" HOST_CONFIG: "quartz-toss_4_x86_64_ib-${COMPILER}.cmake" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON -UTRIBOL_DIR" ALLOC_NODES: "1" ALLOC_TIME: "30" - extends: .src_build_on_quartz + extends: .src_build_on_toss4 -quartz-gcc_10_3_1-src-no-sundials: +toss4-gcc_10_3_1-src-no-sundials: variables: COMPILER: "gcc@10.3.1" HOST_CONFIG: "quartz-toss_4_x86_64_ib-${COMPILER}.cmake" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON -USUNDIALS_DIR" ALLOC_NODES: "1" ALLOC_TIME: "20" - extends: .src_build_on_quartz + extends: .src_build_on_toss4 -quartz-clang_14_0_6-full: +toss4-clang_14_0_6-full: variables: COMPILER: "clang@14.0.6" SPEC: "--spec=%${COMPILER}" ALLOC_NODES: "1" ALLOC_TIME: "45" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON" - extends: .full_build_on_quartz + extends: .full_build_on_toss4 -quartz-gcc_10_3_1-full: +toss4-gcc_10_3_1-full: variables: COMPILER: "gcc@10.3.1" SPEC: "--spec=%${COMPILER}" ALLOC_NODES: "1" ALLOC_TIME: "45" EXTRA_CMAKE_OPTIONS: "-DENABLE_BENCHMARKS=ON" - extends: .full_build_on_quartz + extends: .full_build_on_toss4 diff --git a/src/serac/physics/solid_mechanics.hpp b/src/serac/physics/solid_mechanics.hpp index eb88511d9..ab93d596b 100644 --- a/src/serac/physics/solid_mechanics.hpp +++ b/src/serac/physics/solid_mechanics.hpp @@ -1627,18 +1627,32 @@ class SolidMechanics, std::integer_se displacement_, acceleration_, *parameters_[parameter_indices].state...); }...}; + /// @brief Array functions computing the derivative of the residual with respect to each given parameter evaluated at + /// the previous value of state + /// @note This is needed so the user can ask for a specific sensitivity at runtime as opposed to it being a + /// template parameter. + std::array< + std::function{}, 0.0, shape_displacement_, displacement_, acceleration_, + *parameters_[parameter_indices].previous_state...))(double)>, + sizeof...(parameter_indices)> + d_residual_d_previous_ = {[&](double t) { + return (*residual_)(DifferentiateWRT{}, t, shape_displacement_, + displacement_, acceleration_, *parameters_[parameter_indices].previous_state...); + }...}; + /// @brief Solve the Quasi-static Newton system virtual void quasiStaticSolve(double dt) { - time_ += dt; + // warm start must be called prior to the time update so that the previous Jacobians can be used consistently + // throughout. + warmStartDisplacement(dt); + time_ += dt; // Set the ODE time point for the time-varying loads in quasi-static problems ode_time_point_ = time_; // this method is essentially equivalent to the 1-liner // u += dot(inv(J), dot(J_elim[:, dofs], (U(t + dt) - u)[dofs])); - warmStartDisplacement(); - nonlin_solver_->solve(displacement_); } @@ -1705,17 +1719,18 @@ class SolidMechanics, std::integer_se /** * @brief Sets the Dirichlet BCs for the current time and computes an initial guess for parameters and displacement */ - void warmStartDisplacement() + void warmStartDisplacement(double dt) { // Update the linearized Jacobian matrix - auto [r, drdu] = (*residual_)(ode_time_point_, shape_displacement_, differentiate_wrt(displacement_), acceleration_, - *parameters_[parameter_indices].state...); + auto [r, drdu] = (*residual_)(time_, shape_displacement_, differentiate_wrt(displacement_), acceleration_, + *parameters_[parameter_indices].previous_state...); J_ = assemble(drdu); J_e_ = bcs_.eliminateAllEssentialDofsFromMatrix(*J_); du_ = 0.0; for (auto& bc : bcs_.essentials()) { - bc.setDofs(du_, time_); + // apply the future boundary conditions, but use the most recent Jacobians stiffness. + bc.setDofs(du_, time_ + dt); } auto& constrained_dofs = bcs_.allEssentialTrueDofs(); @@ -1734,14 +1749,12 @@ class SolidMechanics, std::integer_se parameter_difference -= *parameters_[parameter_index].previous_state; // Compute a linearized estimate of the residual forces due to this change in parameter - auto drdparam = serac::get(d_residual_d_[parameter_index](ode_time_point_)); + auto drdparam = serac::get(d_residual_d_previous_[parameter_index](time_)); auto residual_update = drdparam(parameter_difference); // Flip the sign to get the RHS of the Newton update system // J^-1 du = - residual - residual_update *= -1.0; - - dr_ += residual_update; + dr_ -= residual_update; // Save the current parameter value for the next timestep *parameters_[parameter_index].previous_state = *parameters_[parameter_index].state; diff --git a/src/serac/physics/solid_mechanics_contact.hpp b/src/serac/physics/solid_mechanics_contact.hpp index a9a9a4d26..661ebed0e 100644 --- a/src/serac/physics/solid_mechanics_contact.hpp +++ b/src/serac/physics/solid_mechanics_contact.hpp @@ -218,15 +218,16 @@ class SolidMechanicsContact, return; } - time_ += dt; + // this method is essentially equivalent to the 1-liner + // u += dot(inv(J), dot(J_elim[:, dofs], (U(t + dt) - u)[dofs])); + // warm start for contact needs to include the previous stiffness terms associated with contact + // otherwise the system will interpenetrate instantly on warm-starting. + warmStartDisplacement(dt); + time_ += dt; // Set the ODE time point for the time-varying loads in quasi-static problems ode_time_point_ = time_; - // this method is essentially equivalent to the 1-liner - // u += dot(inv(J), dot(J_elim[:, dofs], (U(t + dt) - u)[dofs])); - warmStartDisplacement(); - // In general, the solution vector is a stacked (block) vector: // | displacement | // | contact pressure |