feat(nonlinear-static-newton-raphson): step 0 - cli-output-lease-and-derived-names
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,132 @@
|
|||||||
|
# ninja log v7
|
||||||
|
107 1367 8092384218864831 src/fesa/CMakeFiles/fesa_solver.dir/build_info.cpp.obj cbb74df2cfe16446
|
||||||
|
97 1760 8092384218802669 src/fesa/CMakeFiles/fesa_solver.dir/assembly/parallel_for.cpp.obj 6d361d78b8ddb1e6
|
||||||
|
132 2029 8092384219120278 src/fesa/CMakeFiles/fesa_solver.dir/core/status.cpp.obj d9066190c54698e1
|
||||||
|
127 2129 8092384218979200 src/fesa/CMakeFiles/fesa_solver.dir/core/diagnostic.cpp.obj a5cabe8b0504c8b6
|
||||||
|
122 2167 8092384218979200 src/fesa/CMakeFiles/fesa_solver.dir/core/ascii.cpp.obj c1314f837b92110e
|
||||||
|
63 2464 8092384218329431 _deps/googletest-build/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.obj bd6626bb67644ce5
|
||||||
|
112 2521 8092384218924680 src/fesa/CMakeFiles/fesa_solver.dir/constraints/essential_constraint_policy.cpp.obj 839def0f97ba4345
|
||||||
|
67 2557 8092384218488485 src/fesa/CMakeFiles/fesa_solver.dir/analysis/analysis_model.cpp.obj 61c968a4b6f63aff
|
||||||
|
72 2575 8092384218488485 src/fesa/CMakeFiles/fesa_solver.dir/analysis/analysis_state.cpp.obj 7fe12c916f130467
|
||||||
|
117 2585 8092384218979200 src/fesa/CMakeFiles/fesa_solver.dir/constraints/prescribed_displacement.cpp.obj cf4a7839ef2889be
|
||||||
|
92 2604 8092384218727988 src/fesa/CMakeFiles/fesa_solver.dir/assembly/load_assembler.cpp.obj a9a88a41a899d830
|
||||||
|
102 2671 8092384218842800 src/fesa/CMakeFiles/fesa_solver.dir/assembly/sparse_assembler.cpp.obj e370471d9b7f46eb
|
||||||
|
82 2748 8092384218645949 src/fesa/CMakeFiles/fesa_solver.dir/app/fesa_application.cpp.obj b131425fcf446caf
|
||||||
|
136 2761 8092384219192725 src/fesa/CMakeFiles/fesa_solver.dir/elements/element_factory.cpp.obj c53943f91b42e499
|
||||||
|
141 3032 8092384219211547 src/fesa/CMakeFiles/fesa_solver.dir/elements/euler_beam_3d.cpp.obj 8d8a96d17efb1fbd
|
||||||
|
87 3044 8092384218668902 src/fesa/CMakeFiles/fesa_solver.dir/app/output_paths.cpp.obj 2f4555a69a891bf2
|
||||||
|
77 3054 8092384218488485 src/fesa/CMakeFiles/fesa_solver.dir/analysis/linear_static_analysis.cpp.obj 96370aed2a86ae09
|
||||||
|
1369 4357 8092384231534591 src/fesa/CMakeFiles/fesa_solver.dir/elements/mitc4_shell.cpp.obj 4497417f368343ba
|
||||||
|
2029 4511 8092384238129153 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/domain_builder.cpp.obj f82b7186c8b1d417
|
||||||
|
2167 4531 8092384239513629 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/domain_mapper.cpp.obj 78013a69808c94d7
|
||||||
|
1761 4592 8092384235437686 src/fesa/CMakeFiles/fesa_solver.dir/fem/dof_manager.cpp.obj be7398345e5a9ad
|
||||||
|
2465 4609 8092384242481563 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/input_reader.cpp.obj 209f6a2dba784f60
|
||||||
|
2558 4634 8092384243411066 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/step_definition_mapper.cpp.obj e2bf727de4df328f
|
||||||
|
2575 4654 8092384243589363 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/topology_mapper.cpp.obj 35a7cf559a2383f0
|
||||||
|
2522 4978 8092384243054401 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/material_property_mapper.cpp.obj e3d7c5c1826acfd0
|
||||||
|
58 4997 8092384218329431 _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.obj 5f59395ac6fe27d6
|
||||||
|
2672 5237 8092384244558583 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_primitives.cpp.obj a94f3e6278bb7040
|
||||||
|
2605 5250 8092384243885657 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_model_writer.cpp.obj 54d576166219ebe3
|
||||||
|
2762 5307 8092384245447369 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_results_writer.cpp.obj b086f45ee057095d
|
||||||
|
2585 5660 8092384243687256 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_atomic_file.cpp.obj acf4093ec1ca0dab
|
||||||
|
3045 5693 8092384248271192 src/fesa/CMakeFiles/fesa_solver.dir/loads/concentrated_nodal_load.cpp.obj b738f2f3ef238897
|
||||||
|
3032 5716 8092384248152286 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_self_check.cpp.obj 61e23edf9fd3defe
|
||||||
|
2749 5755 8092384245329453 src/fesa/CMakeFiles/fesa_solver.dir/io/hdf5/hdf5_result_writer.cpp.obj 76edfaf76dda1150
|
||||||
|
5008 5765 8092384267920473 lib/gtest.lib 3ad571dfafc7ee18
|
||||||
|
3054 5812 8092384248369539 src/fesa/CMakeFiles/fesa_solver.dir/materials/isotropic_linear_elastic_material.cpp.obj ec18800579e40b2f
|
||||||
|
2129 6343 8092384239119443 src/fesa/CMakeFiles/fesa_solver.dir/io/abaqus/domain_mapping_context.cpp.obj 541cf582d5d72f1d
|
||||||
|
4978 6880 8092384267621712 src/fesa/CMakeFiles/fesa_solver.dir/properties/general_beam_section.cpp.obj 14abd1111f7f07ba
|
||||||
|
5813 6922 8092384275957474 lib/gtest_main.lib 1fea6bfefff1654b
|
||||||
|
4532 7019 8092384263153824 src/fesa/CMakeFiles/fesa_solver.dir/math/sparse_matrix.cpp.obj 43c886855039f11b
|
||||||
|
4635 7086 8092384264181273 src/fesa/CMakeFiles/fesa_solver.dir/model/shell_geometry.cpp.obj 64372c6247c9d1fe
|
||||||
|
4654 7099 8092384264379650 src/fesa/CMakeFiles/fesa_solver.dir/model/source_target_resolver.cpp.obj f0d949f736370376
|
||||||
|
5238 7149 8092384270209372 src/fesa/CMakeFiles/fesa_solver.dir/properties/shell_section.cpp.obj b4b7f64079a1b357
|
||||||
|
4512 7175 8092384262955435 src/fesa/CMakeFiles/fesa_solver.dir/math/matrix.cpp.obj 90a5827630c77ffa
|
||||||
|
4358 7188 8092384261413268 src/fesa/CMakeFiles/fesa_solver.dir/math/dense_blas_internal.cpp.obj 1d155025fdc36e32
|
||||||
|
4592 7436 8092384263746888 src/fesa/CMakeFiles/fesa_solver.dir/math/vector.cpp.obj 31eb0e6e052791f4
|
||||||
|
5308 7496 8092384270902468 src/fesa/CMakeFiles/fesa_solver.dir/results/beam_result_recovery.cpp.obj 8dbf5a7584b82d05
|
||||||
|
4610 7578 8092384263925156 src/fesa/CMakeFiles/fesa_solver.dir/model/domain.cpp.obj 327270abdb77ada5
|
||||||
|
5694 7594 8092384274770343 src/fesa/CMakeFiles/fesa_solver.dir/results/recovery_candidate.cpp.obj 36f81aba1565e4cd
|
||||||
|
5251 7882 8092384270347432 src/fesa/CMakeFiles/fesa_solver.dir/results/analysis_state_commit.cpp.obj f591f5f73fa893d
|
||||||
|
5756 7931 8092384275383077 src/fesa/CMakeFiles/fesa_solver.dir/results/shell_result_recovery.cpp.obj d6de270523c88b62
|
||||||
|
5661 7969 8092384274433391 src/fesa/CMakeFiles/fesa_solver.dir/results/global_equilibrium_recovery.cpp.obj dc54637dec7c2fe
|
||||||
|
5717 8847 8092384275008914 src/fesa/CMakeFiles/fesa_solver.dir/results/result_recovery.cpp.obj dcfbfce0a69b5131
|
||||||
|
5765 9159 8092384275484616 src/fesa/CMakeFiles/fesa_solver.dir/solvers/linear/mkl_pardiso_solver.cpp.obj c7d3578377b60ab4
|
||||||
|
6356 9177 8092384281377735 tests/CMakeFiles/fesa_unit_tests.dir/unit/build_info_test.cpp.obj cc2d626fb4f55428
|
||||||
|
7087 9322 8092384288690125 tests/CMakeFiles/fesa_unit_tests.dir/unit/assembly/parallel_for_test.cpp.obj 64cd58a46d8c2ed0
|
||||||
|
6881 9633 8092384286632996 tests/CMakeFiles/fesa_unit_tests.dir/unit/analysis/analysis_test.cpp.obj 629ae05c2a17e2a2
|
||||||
|
7176 10116 8092384289581651 tests/CMakeFiles/fesa_unit_tests.dir/unit/app/output_paths_test.cpp.obj 190d4f41b24a7775
|
||||||
|
9160 10155 8092384309439240 src/fesa/fesa_solver.lib 834cb49484ed4975
|
||||||
|
7578 10308 8092384293615881 tests/CMakeFiles/fesa_unit_tests.dir/unit/core/diagnostic_test.cpp.obj 382faf72525f5dbd
|
||||||
|
7497 10354 8092384292804797 tests/CMakeFiles/fesa_unit_tests.dir/unit/core/ascii_test.cpp.obj 4c8e3757a2b86a10
|
||||||
|
7594 10413 8092384293774107 tests/CMakeFiles/fesa_unit_tests.dir/unit/core/source_identity_test.cpp.obj 2f8c538d6bbcf9a6
|
||||||
|
7019 10542 8092384288017054 tests/CMakeFiles/fesa_unit_tests.dir/unit/analysis/analysis_state_test.cpp.obj 4eceb64a57a9abdc
|
||||||
|
6922 10553 8092384287049746 tests/CMakeFiles/fesa_unit_tests.dir/unit/analysis/analysis_model_test.cpp.obj 40c473ba9bc9973e
|
||||||
|
7883 10959 8092384296644544 tests/CMakeFiles/fesa_unit_tests.dir/unit/core/status_test.cpp.obj ab6dc42cc2881a67
|
||||||
|
7100 10971 8092384288828228 tests/CMakeFiles/fesa_unit_tests.dir/unit/assembly/load_assembler_test.cpp.obj fd58472fadea8d92
|
||||||
|
7189 11213 8092384289719698 tests/CMakeFiles/fesa_unit_tests.dir/unit/constraints/boundary_condition_test.cpp.obj 6d8a23b383677aae
|
||||||
|
7437 11353 8092384292190435 tests/CMakeFiles/fesa_unit_tests.dir/unit/constraints/essential_constraints_test.cpp.obj fc4706d7a106f2b0
|
||||||
|
7150 11433 8092384289323046 tests/CMakeFiles/fesa_unit_tests.dir/unit/assembly/sparse_assembler_test.cpp.obj 1d73050ff822ef16
|
||||||
|
7970 11517 8092384297528284 tests/CMakeFiles/fesa_unit_tests.dir/unit/elements/euler_beam_3d_test.cpp.obj 4757a86932e814d5
|
||||||
|
7932 12441 8092384297154255 tests/CMakeFiles/fesa_unit_tests.dir/unit/elements/element_factory_test.cpp.obj 1646374b1d49e4ea
|
||||||
|
9634 12565 8092384314168466 tests/CMakeFiles/fesa_unit_tests.dir/unit/math/matrix_test.cpp.obj 1c0388a2cb34a977
|
||||||
|
10309 12712 8092384320925938 tests/CMakeFiles/fesa_unit_tests.dir/unit/math/vector_test.cpp.obj 537626a817bb764a
|
||||||
|
8848 12728 8092384306313035 tests/CMakeFiles/fesa_unit_tests.dir/unit/elements/mitc4_shell_test.cpp.obj 2f4e47f40acc7795
|
||||||
|
10156 12796 8092384319383650 tests/CMakeFiles/fesa_unit_tests.dir/unit/math/vector3_test.cpp.obj 7940001bdaf8e4fe
|
||||||
|
9322 13452 8092384311062628 tests/CMakeFiles/fesa_unit_tests.dir/unit/math/dense_blas_internal_test.cpp.obj f2f846d2a426012d
|
||||||
|
9177 13464 8092384309597453 tests/CMakeFiles/fesa_unit_tests.dir/unit/fem/dof_manager_test.cpp.obj 6004da54fb433c80
|
||||||
|
10117 13583 8092384318989204 tests/CMakeFiles/fesa_unit_tests.dir/unit/math/sparse_matrix_test.cpp.obj f75bb2f18a5bd303
|
||||||
|
10542 13638 8092384323262138 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/abaqus/input_reader_test.cpp.obj 54d4660fb8524142
|
||||||
|
10554 13838 8092384323380087 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/abaqus/input_syntax_test.cpp.obj 14036fa417a21f26
|
||||||
|
10354 14002 8092384321383068 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/abaqus/domain_mapping_components_test.cpp.obj 8b6d55d5290b3dcf
|
||||||
|
10414 14961 8092384321975774 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/abaqus/domain_mapper_test.cpp.obj 4256f1932890204e
|
||||||
|
11214 14967 8092384329967026 tests/CMakeFiles/fesa_unit_tests.dir/unit/loads/load_test.cpp.obj 41fecb4ac4aefc2d
|
||||||
|
11434 15018 8092384332164407 tests/CMakeFiles/fesa_unit_tests.dir/unit/model/model_types_test.cpp.obj 167fe5a77a5994eb
|
||||||
|
11517 15025 8092384332997863 tests/CMakeFiles/fesa_unit_tests.dir/unit/model/shell_geometry_test.cpp.obj 785d2d3084addad4
|
||||||
|
12566 15363 8092384343501584 tests/CMakeFiles/fesa_unit_tests.dir/unit/materials/material_test.cpp.obj 1b5d607a45cc656b
|
||||||
|
11354 15565 8092384331373052 tests/CMakeFiles/fesa_unit_tests.dir/unit/model/domain_test.cpp.obj 4e4ba6955bfefa4
|
||||||
|
10972 15603 8092384327552836 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/hdf5/hdf5_writer_components_test.cpp.obj 7b26f2ede20a2e21
|
||||||
|
12442 15702 8092384342237335 tests/CMakeFiles/fesa_unit_tests.dir/unit/model/source_target_resolver_test.cpp.obj 7dee827d528c74d3
|
||||||
|
12713 15742 8092384344954378 tests/CMakeFiles/fesa_unit_tests.dir/unit/properties/element_property_test.cpp.obj 8473fe9452582ea0
|
||||||
|
13465 15869 8092384352483655 tests/CMakeFiles/fesa_unit_tests.dir/unit/results/results_writer_test.cpp.obj d9deb24734dfc76
|
||||||
|
10960 16310 8092384327434560 tests/CMakeFiles/fesa_unit_tests.dir/unit/io/hdf5/hdf5_results_writer_test.cpp.obj 562b8f04b2dcdc01
|
||||||
|
13584 16592 8092384353669318 tests/CMakeFiles/fesa_unit_tests.dir/unit/solvers/linear/linear_solver_test.cpp.obj 60444f53e28a5449
|
||||||
|
12728 16604 8092384345112691 tests/CMakeFiles/fesa_unit_tests.dir/unit/results/result_records_test.cpp.obj 750f53bc9d3bf3f1
|
||||||
|
13639 16746 8092384354224529 tests/CMakeFiles/fesa_unit_tests.dir/unit/solvers/linear/mkl_pardiso_solver_test.cpp.obj b761afa1036f4978
|
||||||
|
14003 16836 8092384357866571 tests/CMakeFiles/fesa_integration_tests.dir/integration/app/fesa_application_test.cpp.obj 83061b0b6e67b7d2
|
||||||
|
12797 17156 8092384345803861 tests/CMakeFiles/fesa_unit_tests.dir/unit/results/result_recovery_components_test.cpp.obj 83ac2cda76cf82a
|
||||||
|
13839 17161 8092384356222006 tests/CMakeFiles/fesa_integration_tests.dir/integration/analysis/linear_static_analysis_test.cpp.obj 2637ca1438adff43
|
||||||
|
13452 17652 8092384352365561 tests/CMakeFiles/fesa_unit_tests.dir/unit/results/result_recovery_test.cpp.obj 16815e6d5b74928a
|
||||||
|
17162 19481 8092384412470224 tests/fesa_integration_tests.exe d976ae10942a92cd
|
||||||
|
17162 19481 8092384412470224 tests/fesa_integration_tests_d537bc73_tests.cmake d976ae10942a92cd
|
||||||
|
17162 19481 8092384412470224 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests_d537bc73_tests.cmake d976ae10942a92cd
|
||||||
|
17652 19869 8092384416412729 tests/fesa_unit_tests.exe c7f61799ccaff6df
|
||||||
|
17652 19869 8092384416412729 tests/fesa_unit_tests_576e7e9d_tests.cmake c7f61799ccaff6df
|
||||||
|
17652 19869 8092384416412729 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_unit_tests_576e7e9d_tests.cmake c7f61799ccaff6df
|
||||||
|
57 907 8092384649865117 src/fesa/CMakeFiles/fesa_cli.dir/app/main.cpp.obj db4c7e4d98d0b37a
|
||||||
|
62 1025 8092384649865117 tests/CMakeFiles/fesa_reference_tests.dir/reference/reference_tolerance_policy.cpp.obj 4d4567dc725e04bf
|
||||||
|
67 1957 8092384649929171 tests/CMakeFiles/fesa_reference_tests.dir/reference/reference_tolerance_policy_test.cpp.obj df1c2a7b89dbaab5
|
||||||
|
87 2236 8092384650156206 tests/CMakeFiles/fesa_reference_tests.dir/reference/mitc4_reference_comparison.cpp.obj d5641bbf190f8212
|
||||||
|
98 2282 8092384650262486 tests/CMakeFiles/fesa_reference_tests.dir/reference/mitc4_reference_cases_test.cpp.obj 724d2e009b4467de
|
||||||
|
82 2448 8092384650085756 tests/CMakeFiles/fesa_reference_tests.dir/reference/b33_reference_comparison_test.cpp.obj fe2325128628efc1
|
||||||
|
92 2498 8092384650202184 tests/CMakeFiles/fesa_reference_tests.dir/reference/mitc4_reference_comparison_test.cpp.obj 536ec854d4427ddc
|
||||||
|
72 2767 8092384649929171 tests/CMakeFiles/fesa_reference_tests.dir/reference/reference_comparison.cpp.obj c9b25f54d0e8d98f
|
||||||
|
908 2795 8092384658379739 src/fesa/fesa.exe 1f8f56fa7a9b4ffe
|
||||||
|
76 2814 8092384649929171 tests/CMakeFiles/fesa_reference_tests.dir/reference/reference_comparison_test.cpp.obj 20f54b6ae2255260
|
||||||
|
2814 4306 8092384692235536 tests/fesa_reference_tests.exe c70eaec9df33bb90
|
||||||
|
2814 4306 8092384692235536 tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
2814 4306 8092384692235536 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
53 1720 8092385992962344 tests/CMakeFiles/fesa_reference_tests.dir/reference/mitc4_reference_cases_test.cpp.obj 724d2e009b4467de
|
||||||
|
57 1772 8092387178958005 tests/CMakeFiles/fesa_reference_tests.dir/reference/b33_reference_comparison_test.cpp.obj fe2325128628efc1
|
||||||
|
51 2086 8092387178799897 tests/CMakeFiles/fesa_reference_tests.dir/reference/reference_comparison.cpp.obj c9b25f54d0e8d98f
|
||||||
|
2086 2967 8092387207983024 tests/fesa_reference_tests.exe c70eaec9df33bb90
|
||||||
|
2086 2967 8092387207983024 tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
2086 2967 8092387207983024 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
47 1627 8092387468833159 tests/CMakeFiles/fesa_reference_tests.dir/reference/mitc4_reference_cases_test.cpp.obj 724d2e009b4467de
|
||||||
|
1627 2458 8092387492815552 tests/fesa_reference_tests.exe c70eaec9df33bb90
|
||||||
|
1627 2458 8092387492815552 tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
1627 2458 8092387492815552 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake c70eaec9df33bb90
|
||||||
|
31 1687 8092388278143624 tests/CMakeFiles/fesa_integration_tests.dir/integration/app/fesa_application_test.cpp.obj 83061b0b6e67b7d2
|
||||||
|
1688 2540 8092388303138660 tests/fesa_integration_tests.exe d976ae10942a92cd
|
||||||
|
1688 2540 8092388303138660 tests/fesa_integration_tests_d537bc73_tests.cmake d976ae10942a92cd
|
||||||
|
1688 2540 8092388303138660 C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests_d537bc73_tests.cmake d976ae10942a92cd
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
|
||||||
|
####### Any changes to this file will be overwritten by the next CMake run ####
|
||||||
|
####### The input file was Config.cmake.in ########
|
||||||
|
|
||||||
|
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
|
||||||
|
|
||||||
|
macro(set_and_check _var _file)
|
||||||
|
set(${_var} "${_file}")
|
||||||
|
if(NOT EXISTS "${_file}")
|
||||||
|
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(check_required_components _NAME)
|
||||||
|
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||||
|
if(NOT ${_NAME}_${comp}_FOUND)
|
||||||
|
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||||
|
set(${_NAME}_FOUND FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
if ()
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG )
|
||||||
|
find_dependency(Threads)
|
||||||
|
endif()
|
||||||
|
if (OFF)
|
||||||
|
find_dependency(absl)
|
||||||
|
find_dependency(re2)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/GTestTargets.cmake")
|
||||||
|
check_required_components("")
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
# This is a basic version file for the Config-mode of find_package().
|
||||||
|
# It is used by write_basic_package_version_file() as input file for configure_file()
|
||||||
|
# to create a version-file which can be installed along a config.cmake file.
|
||||||
|
#
|
||||||
|
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
|
||||||
|
# the requested version string are exactly the same and it sets
|
||||||
|
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
|
||||||
|
# The variable CVF_VERSION must be set before calling configure_file().
|
||||||
|
|
||||||
|
set(PACKAGE_VERSION "1.16.0")
|
||||||
|
|
||||||
|
if (PACKAGE_FIND_VERSION_RANGE)
|
||||||
|
# Package version must be in the requested version range
|
||||||
|
if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN)
|
||||||
|
OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX)
|
||||||
|
OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX)))
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
else()
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
else()
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||||
|
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||||
|
set(PACKAGE_VERSION_EXACT TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||||
|
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||||
|
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
|
||||||
|
math(EXPR installedBits "8 * 8")
|
||||||
|
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||||
|
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
libdir=C:/Program Files (x86)/FESA/lib
|
||||||
|
includedir=C:/Program Files (x86)/FESA/include
|
||||||
|
|
||||||
|
Name: gmock
|
||||||
|
Description: GoogleMock (without main() function)
|
||||||
|
Version: 1.16.0
|
||||||
|
URL: https://github.com/google/googletest
|
||||||
|
Requires: gtest = 1.16.0
|
||||||
|
Libs: -L${libdir} -lgmock
|
||||||
|
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=0
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
libdir=C:/Program Files (x86)/FESA/lib
|
||||||
|
includedir=C:/Program Files (x86)/FESA/include
|
||||||
|
|
||||||
|
Name: gmock_main
|
||||||
|
Description: GoogleMock (with main() function)
|
||||||
|
Version: 1.16.0
|
||||||
|
URL: https://github.com/google/googletest
|
||||||
|
Requires: gmock = 1.16.0
|
||||||
|
Libs: -L${libdir} -lgmock_main
|
||||||
|
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=0
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
libdir=C:/Program Files (x86)/FESA/lib
|
||||||
|
includedir=C:/Program Files (x86)/FESA/include
|
||||||
|
|
||||||
|
Name: gtest
|
||||||
|
Description: GoogleTest (without main() function)
|
||||||
|
Version: 1.16.0
|
||||||
|
URL: https://github.com/google/googletest
|
||||||
|
Libs: -L${libdir} -lgtest
|
||||||
|
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=0
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
libdir=C:/Program Files (x86)/FESA/lib
|
||||||
|
includedir=C:/Program Files (x86)/FESA/include
|
||||||
|
|
||||||
|
Name: gtest_main
|
||||||
|
Description: GoogleTest (with main() function)
|
||||||
|
Version: 1.16.0
|
||||||
|
URL: https://github.com/google/googletest
|
||||||
|
Requires: gtest = 1.16.0
|
||||||
|
Libs: -L${libdir} -lgtest_main
|
||||||
|
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=0
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,106 @@
|
|||||||
|
*Heading
|
||||||
|
** Job name: Job-1 Model name: Model-1
|
||||||
|
** Generated by: Abaqus/CAE Learning Edition 2024
|
||||||
|
*Preprint, echo=NO, model=NO, history=NO, contact=NO
|
||||||
|
**
|
||||||
|
** PARTS
|
||||||
|
**
|
||||||
|
*Part, name=PART-1_1
|
||||||
|
*Node
|
||||||
|
1, 0., 0., 0.
|
||||||
|
2, 1., 0., 0.
|
||||||
|
3, 2., 0., 0.
|
||||||
|
4, 3., 0., 0.
|
||||||
|
5, 4., 0., 0.
|
||||||
|
6, 5., 0., 0.
|
||||||
|
7, 6., 0., 0.
|
||||||
|
8, 7., 0., 0.
|
||||||
|
9, 8., 0., 0.
|
||||||
|
10, 9., 0., 0.
|
||||||
|
11, 10., 0., 0.
|
||||||
|
*Element, type=B33
|
||||||
|
1, 1, 2
|
||||||
|
2, 2, 3
|
||||||
|
3, 3, 4
|
||||||
|
4, 4, 5
|
||||||
|
5, 5, 6
|
||||||
|
6, 6, 7
|
||||||
|
7, 7, 8
|
||||||
|
8, 8, 9
|
||||||
|
9, 9, 10
|
||||||
|
10, 10, 11
|
||||||
|
*Elset, elset=Set-1, generate
|
||||||
|
1, 10, 1
|
||||||
|
*Elset, elset=Set-2, generate
|
||||||
|
1, 10, 1
|
||||||
|
*Elset, elset=Set-3, generate
|
||||||
|
1, 10, 1
|
||||||
|
*Elset, elset=Set-4, generate
|
||||||
|
1, 10, 1
|
||||||
|
** Section: Section-1 Profile: Profile-1
|
||||||
|
*Beam General Section, elset=Set-1, material=Material-1, section=GENERAL
|
||||||
|
1., 0.0833333, 0., 0.0833333, 0.140833
|
||||||
|
0.,1.,0.
|
||||||
|
*End Part
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** ASSEMBLY
|
||||||
|
**
|
||||||
|
*Assembly, name=Assembly
|
||||||
|
**
|
||||||
|
*Instance, name=PART-1_1-1, part=PART-1_1
|
||||||
|
*End Instance
|
||||||
|
**
|
||||||
|
*Nset, nset=Set-3, instance=PART-1_1-1
|
||||||
|
1,
|
||||||
|
*Nset, nset=Set-4, instance=PART-1_1-1
|
||||||
|
11,
|
||||||
|
*End Assembly
|
||||||
|
**
|
||||||
|
** MATERIALS
|
||||||
|
**
|
||||||
|
*Material, name=Material-1
|
||||||
|
*Elastic
|
||||||
|
2.1e+11, 0.3
|
||||||
|
**
|
||||||
|
** BOUNDARY CONDITIONS
|
||||||
|
**
|
||||||
|
** Name: BC-1 Type: Displacement/Rotation
|
||||||
|
*Boundary
|
||||||
|
Set-3, 1, 1
|
||||||
|
Set-3, 2, 2
|
||||||
|
Set-3, 3, 3
|
||||||
|
Set-3, 4, 4
|
||||||
|
Set-3, 5, 5
|
||||||
|
Set-3, 6, 6
|
||||||
|
** ----------------------------------------------------------------
|
||||||
|
**
|
||||||
|
** STEP: Step-1
|
||||||
|
**
|
||||||
|
*Step, name=Step-1, nlgeom=NO
|
||||||
|
*Static
|
||||||
|
1., 1., 1e-05, 1.
|
||||||
|
**
|
||||||
|
** LOADS
|
||||||
|
**
|
||||||
|
** Name: Load-1 Type: Concentrated force
|
||||||
|
*Cload
|
||||||
|
Set-4, 3, -1e+06
|
||||||
|
**
|
||||||
|
** OUTPUT REQUESTS
|
||||||
|
**
|
||||||
|
*Restart, write, frequency=0
|
||||||
|
**
|
||||||
|
** FIELD OUTPUT: F-Output-1
|
||||||
|
**
|
||||||
|
*Output, field
|
||||||
|
*Node Output
|
||||||
|
CF, RF, TF, U
|
||||||
|
*Element Output, directions=YES
|
||||||
|
LE, NFORC, NFORCSO, PE, PEEQ, PEMAG, S, SF
|
||||||
|
*Contact Output, variable=PRESELECT
|
||||||
|
**
|
||||||
|
** HISTORY OUTPUT: H-Output-1
|
||||||
|
**
|
||||||
|
*Output, history, variable=PRESELECT
|
||||||
|
*End Step
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,164 @@
|
|||||||
|
*Heading
|
||||||
|
** Job name: shell Model name: Model-1
|
||||||
|
** Generated by: Abaqus/CAE Learning Edition 2024
|
||||||
|
*Preprint, echo=NO, model=NO, history=NO, contact=NO
|
||||||
|
**
|
||||||
|
** PARTS
|
||||||
|
**
|
||||||
|
*Part, name=Part-1
|
||||||
|
*Node
|
||||||
|
1, 0., -5., 0.
|
||||||
|
2, 0., 0., 0.
|
||||||
|
3, -5., 0., 0.
|
||||||
|
4, -5., -5., 0.
|
||||||
|
5, 0., 5., 0.
|
||||||
|
6, 5., 0., 0.
|
||||||
|
7, 5., 5., 0.
|
||||||
|
8, -5., 5., 0.
|
||||||
|
9, 5., -5., 0.
|
||||||
|
10, 0., -3.33333325, 0.
|
||||||
|
11, 0., -1.66666663, 0.
|
||||||
|
12, -1.66666663, 0., 0.
|
||||||
|
13, -3.33333325, 0., 0.
|
||||||
|
14, -5., -1.66666663, 0.
|
||||||
|
15, -5., -3.33333325, 0.
|
||||||
|
16, -3.33333325, -5., 0.
|
||||||
|
17, -1.66666663, -5., 0.
|
||||||
|
18, 0., 3.33333325, 0.
|
||||||
|
19, 0., 1.66666663, 0.
|
||||||
|
20, 1.66666663, 0., 0.
|
||||||
|
21, 3.33333325, 0., 0.
|
||||||
|
22, 5., 1.66666663, 0.
|
||||||
|
23, 5., 3.33333325, 0.
|
||||||
|
24, 3.33333325, 5., 0.
|
||||||
|
25, 1.66666663, 5., 0.
|
||||||
|
26, -1.66666663, 5., 0.
|
||||||
|
27, -3.33333325, 5., 0.
|
||||||
|
28, -5., 3.33333325, 0.
|
||||||
|
29, -5., 1.66666663, 0.
|
||||||
|
30, 1.66666663, -5., 0.
|
||||||
|
31, 3.33333325, -5., 0.
|
||||||
|
32, 5., -3.33333325, 0.
|
||||||
|
33, 5., -1.66666663, 0.
|
||||||
|
34, -1.66666663, -3.33333325, 0.
|
||||||
|
35, -1.66666663, -1.66666663, 0.
|
||||||
|
36, -3.33333325, -3.33333325, 0.
|
||||||
|
37, -3.33333325, -1.66666663, 0.
|
||||||
|
38, 1.66666663, 3.33333325, 0.
|
||||||
|
39, 1.66666663, 1.66666663, 0.
|
||||||
|
40, 3.33333325, 3.33333325, 0.
|
||||||
|
41, 3.33333325, 1.66666663, 0.
|
||||||
|
42, -1.66666663, 1.66666663, 0.
|
||||||
|
43, -1.66666663, 3.33333325, 0.
|
||||||
|
44, -3.33333325, 1.66666663, 0.
|
||||||
|
45, -3.33333325, 3.33333325, 0.
|
||||||
|
46, 1.66666663, -1.66666663, 0.
|
||||||
|
47, 1.66666663, -3.33333325, 0.
|
||||||
|
48, 3.33333325, -1.66666663, 0.
|
||||||
|
49, 3.33333325, -3.33333325, 0.
|
||||||
|
*Element, type=S4
|
||||||
|
1, 1, 10, 34, 17
|
||||||
|
2, 10, 11, 35, 34
|
||||||
|
3, 11, 2, 12, 35
|
||||||
|
4, 17, 34, 36, 16
|
||||||
|
5, 34, 35, 37, 36
|
||||||
|
6, 35, 12, 13, 37
|
||||||
|
7, 16, 36, 15, 4
|
||||||
|
8, 36, 37, 14, 15
|
||||||
|
9, 37, 13, 3, 14
|
||||||
|
10, 5, 18, 38, 25
|
||||||
|
11, 18, 19, 39, 38
|
||||||
|
12, 19, 2, 20, 39
|
||||||
|
13, 25, 38, 40, 24
|
||||||
|
14, 38, 39, 41, 40
|
||||||
|
15, 39, 20, 21, 41
|
||||||
|
16, 24, 40, 23, 7
|
||||||
|
17, 40, 41, 22, 23
|
||||||
|
18, 41, 21, 6, 22
|
||||||
|
19, 2, 19, 42, 12
|
||||||
|
20, 19, 18, 43, 42
|
||||||
|
21, 18, 5, 26, 43
|
||||||
|
22, 12, 42, 44, 13
|
||||||
|
23, 42, 43, 45, 44
|
||||||
|
24, 43, 26, 27, 45
|
||||||
|
25, 13, 44, 29, 3
|
||||||
|
26, 44, 45, 28, 29
|
||||||
|
27, 45, 27, 8, 28
|
||||||
|
28, 2, 11, 46, 20
|
||||||
|
29, 11, 10, 47, 46
|
||||||
|
30, 10, 1, 30, 47
|
||||||
|
31, 20, 46, 48, 21
|
||||||
|
32, 46, 47, 49, 48
|
||||||
|
33, 47, 30, 31, 49
|
||||||
|
34, 21, 48, 33, 6
|
||||||
|
35, 48, 49, 32, 33
|
||||||
|
36, 49, 31, 9, 32
|
||||||
|
*Nset, nset=Set-1, generate
|
||||||
|
1, 49, 1
|
||||||
|
*Elset, elset=Set-1, generate
|
||||||
|
1, 36, 1
|
||||||
|
** Section: Section-1
|
||||||
|
*Shell Section, elset=Set-1, material=Material-1
|
||||||
|
0.5, 5
|
||||||
|
*End Part
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** ASSEMBLY
|
||||||
|
**
|
||||||
|
*Assembly, name=Assembly
|
||||||
|
**
|
||||||
|
*Instance, name=Part-1-1, part=Part-1
|
||||||
|
*End Instance
|
||||||
|
**
|
||||||
|
*Nset, nset=Set-1, instance=Part-1-1
|
||||||
|
2,
|
||||||
|
*Nset, nset=Set-2, instance=Part-1-1
|
||||||
|
1, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 17, 22, 23, 24, 25
|
||||||
|
26, 27, 28, 29, 30, 31, 32, 33
|
||||||
|
*Elset, elset=Set-2, instance=Part-1-1
|
||||||
|
1, 4, 7, 8, 9, 10, 13, 16, 17, 18, 21, 24, 25, 26, 27, 30
|
||||||
|
33, 34, 35, 36
|
||||||
|
*End Assembly
|
||||||
|
**
|
||||||
|
** MATERIALS
|
||||||
|
**
|
||||||
|
*Material, name=Material-1
|
||||||
|
*Elastic
|
||||||
|
2.1e+11, 0.3
|
||||||
|
**
|
||||||
|
** BOUNDARY CONDITIONS
|
||||||
|
**
|
||||||
|
** Name: BC-1 Type: Displacement/Rotation
|
||||||
|
*Boundary
|
||||||
|
Set-2, 1, 1
|
||||||
|
Set-2, 2, 2
|
||||||
|
Set-2, 3, 3
|
||||||
|
Set-2, 4, 4
|
||||||
|
Set-2, 5, 5
|
||||||
|
Set-2, 6, 6
|
||||||
|
** ----------------------------------------------------------------
|
||||||
|
**
|
||||||
|
** STEP: Step-1
|
||||||
|
**
|
||||||
|
*Step, name=Step-1, nlgeom=NO
|
||||||
|
*Static
|
||||||
|
1., 1., 1e-05, 1.
|
||||||
|
**
|
||||||
|
** LOADS
|
||||||
|
**
|
||||||
|
** Name: Load-1 Type: Concentrated force
|
||||||
|
*Cload
|
||||||
|
Set-1, 3, -100000.
|
||||||
|
**
|
||||||
|
** OUTPUT REQUESTS
|
||||||
|
**
|
||||||
|
*Restart, write, frequency=0
|
||||||
|
**
|
||||||
|
** FIELD OUTPUT: F-Output-1
|
||||||
|
**
|
||||||
|
*Output, field, variable=PRESELECT
|
||||||
|
**
|
||||||
|
** HISTORY OUTPUT: H-Output-1
|
||||||
|
**
|
||||||
|
*Output, history, variable=PRESELECT
|
||||||
|
*End Step
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,164 @@
|
|||||||
|
*Heading
|
||||||
|
** Job name: shell Model name: Model-1
|
||||||
|
** Generated by: Abaqus/CAE Learning Edition 2024
|
||||||
|
*Preprint, echo=NO, model=NO, history=NO, contact=NO
|
||||||
|
**
|
||||||
|
** PARTS
|
||||||
|
**
|
||||||
|
*Part, name=Part-1
|
||||||
|
*Node
|
||||||
|
1, 0., -5., 0.
|
||||||
|
2, 0., 0., 0.
|
||||||
|
3, -5., 0., 0.
|
||||||
|
4, -5., -5., 0.
|
||||||
|
5, 0., 5., 0.
|
||||||
|
6, 5., 0., 0.
|
||||||
|
7, 5., 5., 0.
|
||||||
|
8, -5., 5., 0.
|
||||||
|
9, 5., -5., 0.
|
||||||
|
10, 0., -3.33333325, 0.
|
||||||
|
11, 0., -1.66666663, 0.
|
||||||
|
12, -1.66666663, 0., 0.
|
||||||
|
13, -3.33333325, 0., 0.
|
||||||
|
14, -5., -1.66666663, 0.
|
||||||
|
15, -5., -3.33333325, 0.
|
||||||
|
16, -3.33333325, -5., 0.
|
||||||
|
17, -1.66666663, -5., 0.
|
||||||
|
18, 0., 3.33333325, 0.
|
||||||
|
19, 0., 1.66666663, 0.
|
||||||
|
20, 1.66666663, 0., 0.
|
||||||
|
21, 3.33333325, 0., 0.
|
||||||
|
22, 5., 1.66666663, 0.
|
||||||
|
23, 5., 3.33333325, 0.
|
||||||
|
24, 3.33333325, 5., 0.
|
||||||
|
25, 1.66666663, 5., 0.
|
||||||
|
26, -1.66666663, 5., 0.
|
||||||
|
27, -3.33333325, 5., 0.
|
||||||
|
28, -5., 3.33333325, 0.
|
||||||
|
29, -5., 1.66666663, 0.
|
||||||
|
30, 1.66666663, -5., 0.
|
||||||
|
31, 3.33333325, -5., 0.
|
||||||
|
32, 5., -3.33333325, 0.
|
||||||
|
33, 5., -1.66666663, 0.
|
||||||
|
34, -1.66666663, -3.33333325, 0.
|
||||||
|
35, -1.66666663, -1.66666663, 0.
|
||||||
|
36, -3.33333325, -3.33333325, 0.
|
||||||
|
37, -3.33333325, -1.66666663, 0.
|
||||||
|
38, 1.66666663, 3.33333325, 0.
|
||||||
|
39, 1.66666663, 1.66666663, 0.
|
||||||
|
40, 3.33333325, 3.33333325, 0.
|
||||||
|
41, 3.33333325, 1.66666663, 0.
|
||||||
|
42, -1.66666663, 1.66666663, 0.
|
||||||
|
43, -1.66666663, 3.33333325, 0.
|
||||||
|
44, -3.33333325, 1.66666663, 0.
|
||||||
|
45, -3.33333325, 3.33333325, 0.
|
||||||
|
46, 1.66666663, -1.66666663, 0.
|
||||||
|
47, 1.66666663, -3.33333325, 0.
|
||||||
|
48, 3.33333325, -1.66666663, 0.
|
||||||
|
49, 3.33333325, -3.33333325, 0.
|
||||||
|
*Element, type=S4
|
||||||
|
1, 1, 10, 34, 17
|
||||||
|
2, 10, 11, 35, 34
|
||||||
|
3, 11, 2, 12, 35
|
||||||
|
4, 17, 34, 36, 16
|
||||||
|
5, 34, 35, 37, 36
|
||||||
|
6, 35, 12, 13, 37
|
||||||
|
7, 16, 36, 15, 4
|
||||||
|
8, 36, 37, 14, 15
|
||||||
|
9, 37, 13, 3, 14
|
||||||
|
10, 5, 18, 38, 25
|
||||||
|
11, 18, 19, 39, 38
|
||||||
|
12, 19, 2, 20, 39
|
||||||
|
13, 25, 38, 40, 24
|
||||||
|
14, 38, 39, 41, 40
|
||||||
|
15, 39, 20, 21, 41
|
||||||
|
16, 24, 40, 23, 7
|
||||||
|
17, 40, 41, 22, 23
|
||||||
|
18, 41, 21, 6, 22
|
||||||
|
19, 2, 19, 42, 12
|
||||||
|
20, 19, 18, 43, 42
|
||||||
|
21, 18, 5, 26, 43
|
||||||
|
22, 12, 42, 44, 13
|
||||||
|
23, 42, 43, 45, 44
|
||||||
|
24, 43, 26, 27, 45
|
||||||
|
25, 13, 44, 29, 3
|
||||||
|
26, 44, 45, 28, 29
|
||||||
|
27, 45, 27, 8, 28
|
||||||
|
28, 2, 11, 46, 20
|
||||||
|
29, 11, 10, 47, 46
|
||||||
|
30, 10, 1, 30, 47
|
||||||
|
31, 20, 46, 48, 21
|
||||||
|
32, 46, 47, 49, 48
|
||||||
|
33, 47, 30, 31, 49
|
||||||
|
34, 21, 48, 33, 6
|
||||||
|
35, 48, 49, 32, 33
|
||||||
|
36, 49, 31, 9, 32
|
||||||
|
*Nset, nset=Set-1, generate
|
||||||
|
1, 49, 1
|
||||||
|
*Elset, elset=Set-1, generate
|
||||||
|
1, 36, 1
|
||||||
|
** Section: Section-1
|
||||||
|
*Shell Section, elset=Set-1, material=Material-1
|
||||||
|
0.5, 5
|
||||||
|
*End Part
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** ASSEMBLY
|
||||||
|
**
|
||||||
|
*Assembly, name=Assembly
|
||||||
|
**
|
||||||
|
*Instance, name=Part-1-1, part=Part-1
|
||||||
|
*End Instance
|
||||||
|
**
|
||||||
|
*Nset, nset=Set-1, instance=Part-1-1
|
||||||
|
2,
|
||||||
|
*Nset, nset=Set-2, instance=Part-1-1
|
||||||
|
1, 3, 4, 5, 6, 7, 8, 9, 14, 15, 16, 17, 22, 23, 24, 25
|
||||||
|
26, 27, 28, 29, 30, 31, 32, 33
|
||||||
|
*Elset, elset=Set-2, instance=Part-1-1
|
||||||
|
1, 4, 7, 8, 9, 10, 13, 16, 17, 18, 21, 24, 25, 26, 27, 30
|
||||||
|
33, 34, 35, 36
|
||||||
|
*End Assembly
|
||||||
|
**
|
||||||
|
** MATERIALS
|
||||||
|
**
|
||||||
|
*Material, name=Material-1
|
||||||
|
*Elastic
|
||||||
|
2.1e+11, 0.3
|
||||||
|
**
|
||||||
|
** BOUNDARY CONDITIONS
|
||||||
|
**
|
||||||
|
** Name: BC-1 Type: Displacement/Rotation
|
||||||
|
*Boundary
|
||||||
|
Set-2, 1, 1
|
||||||
|
Set-2, 2, 2
|
||||||
|
Set-2, 3, 3
|
||||||
|
Set-2, 4, 4
|
||||||
|
Set-2, 5, 5
|
||||||
|
Set-2, 6, 6
|
||||||
|
** ----------------------------------------------------------------
|
||||||
|
**
|
||||||
|
** STEP: Step-1
|
||||||
|
**
|
||||||
|
*Step, name=Step-1, nlgeom=NO
|
||||||
|
*Static
|
||||||
|
1., 1., 1e-05, 1.
|
||||||
|
**
|
||||||
|
** LOADS
|
||||||
|
**
|
||||||
|
** Name: Load-1 Type: Concentrated force
|
||||||
|
*Cload
|
||||||
|
Set-1, 3, -100000.
|
||||||
|
**
|
||||||
|
** OUTPUT REQUESTS
|
||||||
|
**
|
||||||
|
*Restart, write, frequency=0
|
||||||
|
**
|
||||||
|
** FIELD OUTPUT: F-Output-1
|
||||||
|
**
|
||||||
|
*Output, field, variable=PRESELECT
|
||||||
|
**
|
||||||
|
** HISTORY OUTPUT: H-Output-1
|
||||||
|
**
|
||||||
|
*Output, history, variable=PRESELECT
|
||||||
|
*End Step
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"tests": 13,
|
||||||
|
"name": "AllTests",
|
||||||
|
"testsuites": [
|
||||||
|
{
|
||||||
|
"name": "LinearStaticCli",
|
||||||
|
"tests": 8,
|
||||||
|
"testsuite": [
|
||||||
|
{
|
||||||
|
"name": "FactorizesBeforeLoadAndSolvesWithoutRefactorization",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 306
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FactorizesBeforeRejectingAnInvalidLoad",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 328
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RealPipelineHandlesAnalyticalAndNonzeroPrescription",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 352
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DefaultOutputUsesInputSiblingDerivedName",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 356
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ReturnsEveryExactExitCodeAndOrderedDiagnostic",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 371
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OutputSubstringRejectionLeavesDerivedFilesUnchanged",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 413
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BusyOutputLeaseLeavesDerivedFilesUnchanged",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 443
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OutputRequestsDoNotFilterMandatoryResults",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 468
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mitc4ShellCli",
|
||||||
|
"tests": 5,
|
||||||
|
"testsuite": [
|
||||||
|
{
|
||||||
|
"name": "UsesExistingLifecycleAndExactlyOneFactorization",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 389
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "AppliesKfcForNonzeroPrescribedDisplacement",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 412
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "RejectsSingularAndAcceptsZeroByZeroFreeSystem",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 450
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DoesNotWriteAnInvalidRecoveryCandidate",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\analysis\\linear_static_analysis_test.cpp",
|
||||||
|
"line": 486
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WritesShellHdf5ThroughTheExistingApplicationRoute",
|
||||||
|
"file": "C:\\git\\FESADev\\.worktrees\\nonlinear-static-newton-raphson\\tests\\integration\\app\\fesa_application_test.cpp",
|
||||||
|
"line": 505
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
include("C:/Program Files/CMake/share/cmake-4.4/Modules/GoogleTestAddTests.cmake")
|
||||||
|
gtest_discover_tests_impl(
|
||||||
|
TEST_EXECUTABLE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe]==]
|
||||||
|
TEST_EXECUTOR [==[]==]
|
||||||
|
TEST_WORKING_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
TEST_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_PROPERTIES [==[LABELS]==] [==[linear-static-3d-euler-beam;integration]==]
|
||||||
|
TEST_PREFIX [==[]==]
|
||||||
|
TEST_SUFFIX [==[]==]
|
||||||
|
TEST_FILTER [==[]==]
|
||||||
|
NO_PRETTY_TYPES [==[FALSE]==]
|
||||||
|
NO_PRETTY_VALUES [==[FALSE]==]
|
||||||
|
TEST_LIST [==[fesa_integration_tests_TESTS]==]
|
||||||
|
CTEST_FILE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests_d537bc73_tests.cmake]==]
|
||||||
|
TEST_DISCOVERY_TIMEOUT [==[5]==]
|
||||||
|
TEST_DISCOVERY_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_XML_OUTPUT_DIR [==[]==]
|
||||||
|
TEST_JSON_OUTPUT_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
if(EXISTS "C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests_d537bc73_tests.cmake")
|
||||||
|
include("C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests_d537bc73_tests.cmake")
|
||||||
|
else()
|
||||||
|
add_test(fesa_integration_tests_NOT_BUILT fesa_integration_tests_NOT_BUILT)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
add_test([=[LinearStaticCli.FactorizesBeforeLoadAndSolvesWithoutRefactorization]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.FactorizesBeforeLoadAndSolvesWithoutRefactorization]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.FactorizesBeforeLoadAndSolvesWithoutRefactorization]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:306]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.FactorizesBeforeRejectingAnInvalidLoad]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.FactorizesBeforeRejectingAnInvalidLoad]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.FactorizesBeforeRejectingAnInvalidLoad]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:328]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.RealPipelineHandlesAnalyticalAndNonzeroPrescription]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.RealPipelineHandlesAnalyticalAndNonzeroPrescription]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.RealPipelineHandlesAnalyticalAndNonzeroPrescription]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:352]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.DefaultOutputUsesInputSiblingDerivedName]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.DefaultOutputUsesInputSiblingDerivedName]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.DefaultOutputUsesInputSiblingDerivedName]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:356]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:371]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.OutputSubstringRejectionLeavesDerivedFilesUnchanged]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.OutputSubstringRejectionLeavesDerivedFilesUnchanged]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.OutputSubstringRejectionLeavesDerivedFilesUnchanged]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:413]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.BusyOutputLeaseLeavesDerivedFilesUnchanged]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.BusyOutputLeaseLeavesDerivedFilesUnchanged]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.BusyOutputLeaseLeavesDerivedFilesUnchanged]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:443]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[LinearStaticCli.OutputRequestsDoNotFilterMandatoryResults]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=LinearStaticCli.OutputRequestsDoNotFilterMandatoryResults]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[LinearStaticCli.OutputRequestsDoNotFilterMandatoryResults]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:468]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ShellCli.UsesExistingLifecycleAndExactlyOneFactorization]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=Mitc4ShellCli.UsesExistingLifecycleAndExactlyOneFactorization]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ShellCli.UsesExistingLifecycleAndExactlyOneFactorization]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:389]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ShellCli.AppliesKfcForNonzeroPrescribedDisplacement]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=Mitc4ShellCli.AppliesKfcForNonzeroPrescribedDisplacement]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ShellCli.AppliesKfcForNonzeroPrescribedDisplacement]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:412]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ShellCli.RejectsSingularAndAcceptsZeroByZeroFreeSystem]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=Mitc4ShellCli.RejectsSingularAndAcceptsZeroByZeroFreeSystem]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ShellCli.RejectsSingularAndAcceptsZeroByZeroFreeSystem]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:450]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ShellCli.DoesNotWriteAnInvalidRecoveryCandidate]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=Mitc4ShellCli.DoesNotWriteAnInvalidRecoveryCandidate]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ShellCli.DoesNotWriteAnInvalidRecoveryCandidate]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\analysis\linear_static_analysis_test.cpp:486]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ShellCli.WritesShellHdf5ThroughTheExistingApplicationRoute]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_integration_tests.exe [==[--gtest_filter=Mitc4ShellCli.WritesShellHdf5ThroughTheExistingApplicationRoute]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ShellCli.WritesShellHdf5ThroughTheExistingApplicationRoute]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\integration\app\fesa_application_test.cpp:505]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;integration]]
|
||||||
|
)
|
||||||
|
set(fesa_integration_tests_TESTS [==[LinearStaticCli.FactorizesBeforeLoadAndSolvesWithoutRefactorization]==] [==[LinearStaticCli.FactorizesBeforeRejectingAnInvalidLoad]==] [==[LinearStaticCli.RealPipelineHandlesAnalyticalAndNonzeroPrescription]==] [==[LinearStaticCli.DefaultOutputUsesInputSiblingDerivedName]==] [==[LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic]==] [==[LinearStaticCli.OutputSubstringRejectionLeavesDerivedFilesUnchanged]==] [==[LinearStaticCli.BusyOutputLeaseLeavesDerivedFilesUnchanged]==] [==[LinearStaticCli.OutputRequestsDoNotFilterMandatoryResults]==] [==[Mitc4ShellCli.UsesExistingLifecycleAndExactlyOneFactorization]==] [==[Mitc4ShellCli.AppliesKfcForNonzeroPrescribedDisplacement]==] [==[Mitc4ShellCli.RejectsSingularAndAcceptsZeroByZeroFreeSystem]==] [==[Mitc4ShellCli.DoesNotWriteAnInvalidRecoveryCandidate]==] [==[Mitc4ShellCli.WritesShellHdf5ThroughTheExistingApplicationRoute]==])
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
include("C:/Program Files/CMake/share/cmake-4.4/Modules/GoogleTestAddTests.cmake")
|
||||||
|
gtest_discover_tests_impl(
|
||||||
|
TEST_EXECUTABLE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe]==]
|
||||||
|
TEST_EXECUTOR [==[]==]
|
||||||
|
TEST_WORKING_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
TEST_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_PROPERTIES [==[LABELS]==] [==[linear-static-3d-euler-beam;reference]==]
|
||||||
|
TEST_PREFIX [==[]==]
|
||||||
|
TEST_SUFFIX [==[]==]
|
||||||
|
TEST_FILTER [==[]==]
|
||||||
|
NO_PRETTY_TYPES [==[FALSE]==]
|
||||||
|
NO_PRETTY_VALUES [==[FALSE]==]
|
||||||
|
TEST_LIST [==[fesa_reference_tests_TESTS]==]
|
||||||
|
CTEST_FILE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake]==]
|
||||||
|
TEST_DISCOVERY_TIMEOUT [==[5]==]
|
||||||
|
TEST_DISCOVERY_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_XML_OUTPUT_DIR [==[]==]
|
||||||
|
TEST_JSON_OUTPUT_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
if(EXISTS "C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake")
|
||||||
|
include("C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests_ac7cf2f0_tests.cmake")
|
||||||
|
else()
|
||||||
|
add_test(fesa_reference_tests_NOT_BUILT fesa_reference_tests_NOT_BUILT)
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
add_test([=[ReferenceTolerancePolicy.AppliesRelativeAndNearZeroThresholdsAtTheirInclusiveBoundaries]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceTolerancePolicy.AppliesRelativeAndNearZeroThresholdsAtTheirInclusiveBoundaries]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceTolerancePolicy.AppliesRelativeAndNearZeroThresholdsAtTheirInclusiveBoundaries]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_tolerance_policy_test.cpp:28]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceTolerancePolicy.RejectsFamiliesWhoseScaleRelativeRmsExceedsOnePercent]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceTolerancePolicy.RejectsFamiliesWhoseScaleRelativeRmsExceedsOnePercent]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceTolerancePolicy.RejectsFamiliesWhoseScaleRelativeRmsExceedsOnePercent]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_tolerance_policy_test.cpp:56]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceTolerancePolicy.FailsClosedForZeroScaleNonzeroErrorWithoutNonfiniteMetrics]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceTolerancePolicy.FailsClosedForZeroScaleNonzeroErrorWithoutNonfiniteMetrics]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceTolerancePolicy.FailsClosedForZeroScaleNonzeroErrorWithoutNonfiniteMetrics]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_tolerance_policy_test.cpp:73]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceTolerancePolicy.KeepsWarningOnlyFamilyExceedanceOutOfBlockingVerdict]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceTolerancePolicy.KeepsWarningOnlyFamilyExceedanceOutOfBlockingVerdict]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceTolerancePolicy.KeepsWarningOnlyFamilyExceedanceOutOfBlockingVerdict]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_tolerance_policy_test.cpp:95]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceTolerancePolicy.RejectsNonfiniteInputsBeforeToleranceEvaluation]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceTolerancePolicy.RejectsNonfiniteInputsBeforeToleranceEvaluation]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceTolerancePolicy.RejectsNonfiniteInputsBeforeToleranceEvaluation]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_tolerance_policy_test.cpp:108]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceComparisonContract.PrecheckRejectsMissingSchemaDuplicateAndNonfiniteRows]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceComparisonContract.PrecheckRejectsMissingSchemaDuplicateAndNonfiniteRows]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceComparisonContract.PrecheckRejectsMissingSchemaDuplicateAndNonfiniteRows]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_comparison_test.cpp:426]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceComparisonContract.AppliesSharedFamilyScaleAndNearZeroBranchesWithoutAnAbsoluteGate]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceComparisonContract.AppliesSharedFamilyScaleAndNearZeroBranchesWithoutAnAbsoluteGate]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceComparisonContract.AppliesSharedFamilyScaleAndNearZeroBranchesWithoutAnAbsoluteGate]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_comparison_test.cpp:538]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceComparisonContract.ReportsEveryRowAndAggregateMetricDeterministically]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceComparisonContract.ReportsEveryRowAndAggregateMetricDeterministically]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceComparisonContract.ReportsEveryRowAndAggregateMetricDeterministically]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_comparison_test.cpp:593]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceComparisonContract.PreservesSectionEndpointIdentityWithoutStationNormalization]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceComparisonContract.PreservesSectionEndpointIdentityWithoutStationNormalization]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceComparisonContract.PreservesSectionEndpointIdentityWithoutStationNormalization]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_comparison_test.cpp:663]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[ReferenceComparisonContract.MapsEachSectionCsvComponentToItsDirectEndpointResultant]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=ReferenceComparisonContract.MapsEachSectionCsvComponentToItsDirectEndpointResultant]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[ReferenceComparisonContract.MapsEachSectionCsvComponentToItsDirectEndpointResultant]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\reference_comparison_test.cpp:687]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[B33ReferenceComparison.GeneratesAuthoritativeHdf5AndComparisonEvidence]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=B33ReferenceComparison.GeneratesAuthoritativeHdf5AndComparisonEvidence]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[B33ReferenceComparison.GeneratesAuthoritativeHdf5AndComparisonEvidence]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\b33_reference_comparison_test.cpp:148]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.MapsTrimmedHeaderAndSixComponentsBySourceIdentity]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.MapsTrimmedHeaderAndSixComponentsBySourceIdentity]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.MapsTrimmedHeaderAndSixComponentsBySourceIdentity]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:478]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.RejectsInvalidInventoryBeforeNumericComparison]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.RejectsInvalidInventoryBeforeNumericComparison]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.RejectsInvalidInventoryBeforeNumericComparison]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:511]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.SharesTranslationScaleAcrossUComponentsAndUsesNearZeroBranches]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.SharesTranslationScaleAcrossUComponentsAndUsesNearZeroBranches]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.SharesTranslationScaleAcrossUComponentsAndUsesNearZeroBranches]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:594]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.RotationExceedanceWarnsWithoutBlockingTranslationVerdict]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.RotationExceedanceWarnsWithoutBlockingTranslationVerdict]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.RotationExceedanceWarnsWithoutBlockingTranslationVerdict]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:641]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.RotationRmsExceedanceWarnsWhenEveryRotationRowPasses]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.RotationRmsExceedanceWarnsWhenEveryRotationRowPasses]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.RotationRmsExceedanceWarnsWhenEveryRotationRowPasses]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:667]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.RotationRowAndRmsExceedancesProduceSeparateWarnings]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.RotationRowAndRmsExceedancesProduceSeparateWarnings]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.RotationRowAndRmsExceedancesProduceSeparateWarnings]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:689]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.ReportsMetricsVectorsWorstRowAndJsonDeterministically]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.ReportsMetricsVectorsWorstRowAndJsonDeterministically]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.ReportsMetricsVectorsWorstRowAndJsonDeterministically]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:709]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4ReferenceComparison.RequiresOnlyDeclaredInputCsvAndHdf5]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4ReferenceComparison.RequiresOnlyDeclaredInputCsvAndHdf5]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4ReferenceComparison.RequiresOnlyDeclaredInputCsvAndHdf5]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_comparison_test.cpp:757]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4S4Reference.PreservesS4AndWritesCommonMitc4Metadata]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4S4Reference.PreservesS4AndWritesCommonMitc4Metadata]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4S4Reference.PreservesS4AndWritesCommonMitc4Metadata]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_cases_test.cpp:177]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
add_test([=[Mitc4S4Reference.PassesBlockingUAndReportsEveryUrRow]=] C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_reference_tests.exe [==[--gtest_filter=Mitc4S4Reference.PassesBlockingUAndReportsEveryUrRow]==] --gtest_also_run_disabled_tests)
|
||||||
|
set_tests_properties([=[Mitc4S4Reference.PassesBlockingUAndReportsEveryUrRow]=]
|
||||||
|
PROPERTIES
|
||||||
|
|
||||||
|
DEF_SOURCE_LINE [==[C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson\tests\reference\mitc4_reference_cases_test.cpp:187]==]
|
||||||
|
WORKING_DIRECTORY [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]
|
||||||
|
[[LABELS]] [[linear-static-3d-euler-beam;reference]]
|
||||||
|
)
|
||||||
|
set(fesa_reference_tests_TESTS [==[ReferenceTolerancePolicy.AppliesRelativeAndNearZeroThresholdsAtTheirInclusiveBoundaries]==] [==[ReferenceTolerancePolicy.RejectsFamiliesWhoseScaleRelativeRmsExceedsOnePercent]==] [==[ReferenceTolerancePolicy.FailsClosedForZeroScaleNonzeroErrorWithoutNonfiniteMetrics]==] [==[ReferenceTolerancePolicy.KeepsWarningOnlyFamilyExceedanceOutOfBlockingVerdict]==] [==[ReferenceTolerancePolicy.RejectsNonfiniteInputsBeforeToleranceEvaluation]==] [==[ReferenceComparisonContract.PrecheckRejectsMissingSchemaDuplicateAndNonfiniteRows]==] [==[ReferenceComparisonContract.AppliesSharedFamilyScaleAndNearZeroBranchesWithoutAnAbsoluteGate]==] [==[ReferenceComparisonContract.ReportsEveryRowAndAggregateMetricDeterministically]==] [==[ReferenceComparisonContract.PreservesSectionEndpointIdentityWithoutStationNormalization]==] [==[ReferenceComparisonContract.MapsEachSectionCsvComponentToItsDirectEndpointResultant]==] [==[B33ReferenceComparison.GeneratesAuthoritativeHdf5AndComparisonEvidence]==] [==[Mitc4ReferenceComparison.MapsTrimmedHeaderAndSixComponentsBySourceIdentity]==] [==[Mitc4ReferenceComparison.RejectsInvalidInventoryBeforeNumericComparison]==] [==[Mitc4ReferenceComparison.SharesTranslationScaleAcrossUComponentsAndUsesNearZeroBranches]==] [==[Mitc4ReferenceComparison.RotationExceedanceWarnsWithoutBlockingTranslationVerdict]==] [==[Mitc4ReferenceComparison.RotationRmsExceedanceWarnsWhenEveryRotationRowPasses]==] [==[Mitc4ReferenceComparison.RotationRowAndRmsExceedancesProduceSeparateWarnings]==] [==[Mitc4ReferenceComparison.ReportsMetricsVectorsWorstRowAndJsonDeterministically]==] [==[Mitc4ReferenceComparison.RequiresOnlyDeclaredInputCsvAndHdf5]==] [==[Mitc4S4Reference.PreservesS4AndWritesCommonMitc4Metadata]==] [==[Mitc4S4Reference.PassesBlockingUAndReportsEveryUrRow]==])
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
include("C:/Program Files/CMake/share/cmake-4.4/Modules/GoogleTestAddTests.cmake")
|
||||||
|
gtest_discover_tests_impl(
|
||||||
|
TEST_EXECUTABLE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_unit_tests.exe]==]
|
||||||
|
TEST_EXECUTOR [==[]==]
|
||||||
|
TEST_WORKING_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
TEST_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_PROPERTIES [==[LABELS]==] [==[linear-static-3d-euler-beam;unit]==]
|
||||||
|
TEST_PREFIX [==[]==]
|
||||||
|
TEST_SUFFIX [==[]==]
|
||||||
|
TEST_FILTER [==[]==]
|
||||||
|
NO_PRETTY_TYPES [==[FALSE]==]
|
||||||
|
NO_PRETTY_VALUES [==[FALSE]==]
|
||||||
|
TEST_LIST [==[fesa_unit_tests_TESTS]==]
|
||||||
|
CTEST_FILE [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_unit_tests_576e7e9d_tests.cmake]==]
|
||||||
|
TEST_DISCOVERY_TIMEOUT [==[5]==]
|
||||||
|
TEST_DISCOVERY_EXTRA_ARGS [==[]==]
|
||||||
|
TEST_XML_OUTPUT_DIR [==[]==]
|
||||||
|
TEST_JSON_OUTPUT_DIR [==[C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests]==]
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
if(EXISTS "C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_unit_tests_576e7e9d_tests.cmake")
|
||||||
|
include("C:/git/FESADev/.worktrees/nonlinear-static-newton-raphson/.harness/build-ninja/tests/fesa_unit_tests_576e7e9d_tests.cmake")
|
||||||
|
else()
|
||||||
|
add_test(fesa_unit_tests_NOT_BUILT fesa_unit_tests_NOT_BUILT)
|
||||||
|
endif()
|
||||||
File diff suppressed because one or more lines are too long
@@ -3,16 +3,16 @@
|
|||||||
## 1. Metadata and Feature Scope
|
## 1. Metadata and Feature Scope
|
||||||
|
|
||||||
- feature_id: `nonlinear-static-newton-raphson`
|
- feature_id: `nonlinear-static-newton-raphson`
|
||||||
- workflow_state: `needs-formulation`
|
- workflow_state: `needs-implementation`
|
||||||
- owner_agent: `coordinator-agent`
|
- owner_agent: `coordinator-agent`
|
||||||
- request_date: `2026-08-18`
|
- request_date: `2026-08-18`
|
||||||
- last_updated: `2026-08-23` (Stage 2 사용자 명시 승인; Stage 3 Formulation Agent dispatch 준비)
|
- last_updated: `2026-08-24` (REWORK-004 corrected; no-push Harness rerun authorized)
|
||||||
- process_classification: `architectural`
|
- process_classification: `architectural`
|
||||||
- requested_capability: Newton–Raphson 방법을 사용하는 새 nonlinear static analysis procedure
|
- requested_capability: Newton–Raphson 방법을 사용하는 새 nonlinear static analysis procedure
|
||||||
- proposed_scope_boundary: 첫 release는 initial configuration 기준 Total Lagrangian, materially linear + geometrically nonlinear MITC4로 제한한다. 요구조건 인터뷰와 8단계 evidence gate를 먼저 완료하며, 승인 전에는 상세 수치·I/O·구현 범위를 확정하거나 기존 linear-static lifecycle을 변경하지 않는다.
|
- proposed_scope_boundary: 첫 release는 initial configuration 기준 Total Lagrangian, materially linear + geometrically nonlinear MITC4로 제한한다. 요구조건 인터뷰와 8단계 evidence gate를 먼저 완료하며, 승인 전에는 상세 수치·I/O·구현 범위를 확정하거나 기존 linear-static lifecycle을 변경하지 않는다.
|
||||||
- naming_note: 사용자 표현 `Newton-Rhapson`은 표준 명칭 `Newton–Raphson`으로 정규화했다.
|
- naming_note: 사용자 표현 `Newton-Rhapson`은 표준 명칭 `Newton–Raphson`으로 정규화했다.
|
||||||
- current_goal: 승인된 `requirements.md`와 사용자 승인된 `research.md`를 입력으로 Stage 3의 구현 가능한 `formulation.md` 계약을 Formulation Agent에게서 확보하고 독립 evidence audit을 수행한다.
|
- current_goal: Stage 6 no-push Harness/Implementation rerun is authorized for Executor-selected Step 0 and subsequent approved phase progression under the corrected `codex exec --disable unified_exec` runner envelope.
|
||||||
- constraints: 승인된 physics/scope/tolerance/authoritative output/public compatibility를 보존한다. Stage 3는 O-ROT/O-MAP/O-DRILL/O-MOM/O-BC를 구현 가능한 수학 계약으로 해소하되 HDF5/I/O schema, reference artifact, C++/tests/CMake, phase/Harness 또는 Stage 4 판단으로 확장하지 않는다. Abaqus/Midas 내부 동등성을 주장하지 않는다.
|
- constraints: 승인된 Stage 1-5 hashes, physics/scope/tolerance/authoritative output/public compatibility, `rho_M <= 1e-12`, fixed-global source identity, no drilling load channel과 Stage 6 materialization evidence를 보존한다. The authorized rerun envelope is Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, child launch PATH filtering of `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` and `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, `workspace-write`, implementation-agent `gpt-5.6-terra`/`xhigh`, hooks retained, no-push, no `danger-full-access`, and runner-retained `--disable unified_exec`. Do not edit feature contracts/reference artifacts/tolerance policies, run Abaqus/Nastran/reference solvers, or advance Physics/Release until `implementation-report.md`, `build-test.md`, `reference-comparison.md` and passing implementation evidence exist.
|
||||||
- repository_audit: 기존 worktree에는 `.codex/agents/*.toml`과 `AGENTS.md`의 사용자 변경이 있으며 이를 보존한다.
|
- repository_audit: 기존 worktree에는 `.codex/agents/*.toml`과 `AGENTS.md`의 사용자 변경이 있으며 이를 보존한다.
|
||||||
|
|
||||||
## 2. Eight-Stage Worklist
|
## 2. Eight-Stage Worklist
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
| 1. Requirements | `requirement-agent` | `passed` | `docs/nonlinear-static-newton-raphson/requirements.md` | `<=400` lines, 24 canonical shall requirements, exact 24-row Matrix, approved semantic loss 0, Stage-1 user question 0 | Approved compact content 395 lines; approval metadata 2 lines, current 397; 24↔24 exact ID sets, duplicate/missing/orphan 0, OQ/questions/trivia/placeholders 0; core semantics and NSNR-083 public precedence retained; forbidden changes 0; user explicitly approved on 2026-08-23. | 없음 | 40 |
|
| 1. Requirements | `requirement-agent` | `passed` | `docs/nonlinear-static-newton-raphson/requirements.md` | `<=400` lines, 24 canonical shall requirements, exact 24-row Matrix, approved semantic loss 0, Stage-1 user question 0 | Approved compact content 395 lines; approval metadata 2 lines, current 397; 24↔24 exact ID sets, duplicate/missing/orphan 0, OQ/questions/trivia/placeholders 0; core semantics and NSNR-083 public precedence retained; forbidden changes 0; user explicitly approved on 2026-08-23. | 없음 | 40 |
|
||||||
| 2. Research | `research-agent` | `passed` | `docs/nonlinear-static-newton-raphson/research.md` | 필요한 이론·benchmark·source reliability·applicability limit가 충분함 | Owner/Coordinator pass와 2026-08-23 사용자 명시 승인; 10 required sections, S1–S17, 12 benchmark candidates, 11 research-relevant requirement IDs, 14 unique open issues; nonlinear stored reference gap explicit; SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`; forbidden changes 0. | 없음 | 1 |
|
| 2. Research | `research-agent` | `passed` | `docs/nonlinear-static-newton-raphson/research.md` | 필요한 이론·benchmark·source reliability·applicability limit가 충분함 | Owner/Coordinator pass와 2026-08-23 사용자 명시 승인; 10 required sections, S1–S17, 12 benchmark candidates, 11 research-relevant requirement IDs, 14 unique open issues; nonlinear stored reference gap explicit; SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`; forbidden changes 0. | 없음 | 1 |
|
||||||
| 3. Formulation | `formulation-agent` | `in-progress` | `docs/nonlinear-static-newton-raphson/formulation.md` | strong/weak form, kinematics, tangent/residual, integration, state/recovery가 구현 가능한 계약이며 O-ROT/O-MAP/O-DRILL/O-MOM/O-BC가 승인 scope 안에서 해소됨 | Stage 3 bounded dispatch 준비; approved requirements SHA-256 `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`, approved research SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`. | Formulation Agent 반환 evidence 대기 | 1 |
|
| 3. Formulation | `formulation-agent` | `passed` | `docs/nonlinear-static-newton-raphson/formulation.md` | strong/weak form, kinematics, tangent/residual, integration, state/recovery가 구현 가능한 계약이며 O-ROT/O-MAP/O-DRILL/O-MOM/O-BC가 승인 scope 안에서 해소됨 | Rework attempt 2 owner/Coordinator pass와 사용자 명시 승인: reaction force/generalized moment/spatial moment symbols와 dimensions가 rotation matrix `R_I`와 분리됨; immutable fixed-global source, `rho_M <= 1e-12` admissibility, exact projected physical-work covector, `DP`/`DJ_l`/map-Hessian residual-tangent identity가 §§4.4/5/11.2–11.3/13.1/13.4/17에서 일치함; 18 sections와 7 closures 보존; SHA-256 `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`. | 없음 | 2 |
|
||||||
| 4. Numerical/reference review | `numerical-review-agent` | `pending` | `docs/nonlinear-static-newton-raphson/numerical-review.md`; `docs/nonlinear-static-newton-raphson/reference-model.md` | 두 문서가 함께 `pass-for-io-definition`이며 수치 안정성과 exact reference contract가 준비됨 | 없음 | Stage 3 사용자 승인 필요 | 0 |
|
| 4. Numerical/reference review | `numerical-review-agent` | `passed` | `docs/nonlinear-static-newton-raphson/numerical-review.md`; `docs/nonlinear-static-newton-raphson/reference-model.md` | 두 문서가 함께 `pass-for-io-definition`이며 수치 안정성과 exact reference contract가 준비됨 | Corrected owner return, Coordinator audit pass and user explicit approval: status `pass-for-io-definition`; approved formulation hash matched; shellNL/shell artifacts inspected read-only with row counts `49/49/288`, duplicate required wide keys 0 and nonfinite required values 0; stress CSVs are optional read-only inspection/order evidence only; `RM3` excluded; required external comparison uses displacement, reaction force and physical spatial `RM1/RM2`; exact prechecks and `docs/TOLERANCE.md` policy retained. Current hashes: numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`, reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`. | 없음 | 2 |
|
||||||
| 5. I/O definition | `io-definition-agent` | `pending` | `docs/nonlinear-static-newton-raphson/io.md` | Abaqus subset, semantic mapping, HDF5 schema, diagnostics, CSV projection이 승인됨 | 없음 | Stage 4 사용자 승인 필요 | 0 |
|
| 5. I/O definition | `io-definition-agent` | `passed` | `docs/nonlinear-static-newton-raphson/io.md` | Abaqus subset, semantic mapping, HDF5 schema, diagnostics, CSV projection이 승인됨 | Bounded rework owner status `ready-for-coordinator-review`, SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`; Coordinator audit passed and user explicitly approved the same hash. REWORK-002 defects are corrected: every argv token containing literal `--output` fails pre-input/pre-log/pre-output with one `cli-usage` diagnostic; `nsnr-log-v1` uses UTF-8 no BOM/LF/TAB fixed fields with four-channel gates, typed thresholds, branch identity, early-failure `not-evaluated(reason)`, round-trip numerics and escaping; log open/write/flush/close is fail-closed with zero-byte non-Newton success logs; exact `VARIABLE=PRESELECT` output requests are ignored-with-warning; lexical path/stem derivation, single-writer/candidate collision rules, HDF5 schema v1, reference projection, stress/RM3 exclusions and `docs/TOLERANCE.md` policy are preserved. | 없음 | 2 |
|
||||||
| 6. Implementation | `implementation-planning-agent`; `implementation-agent` | `pending` | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `docs/nonlinear-static-newton-raphson/implementation-report.md`; `docs/nonlinear-static-newton-raphson/build-test.md`; `docs/nonlinear-static-newton-raphson/reference-comparison.md` | 상세 인터뷰와 계획 승인 후 TDD, MSVC/x64/Debug CMake/CTest, blocking reference comparison이 통과함 | 없음 | Stage 5 사용자 승인과 implementation-planning interview 필요 | 0 |
|
| 6. Implementation | `implementation-planning-agent`; `implementation-agent` | `in-progress` | `docs/nonlinear-static-newton-raphson/implementation-plan.md`; `docs/nonlinear-static-newton-raphson/implementation-report.md`; `docs/nonlinear-static-newton-raphson/build-test.md`; `docs/nonlinear-static-newton-raphson/reference-comparison.md`; `docs/nonlinear-static-newton-raphson/corrections.md` | 상세 인터뷰와 계획 승인 후 TDD, MSVC/x64/Debug CMake/CTest, blocking reference comparison이 통과함 | REWORK-004 Correction Agent returned `corrected-for-implementation-rerun`; `scripts/execute.py` now invokes `codex exec --disable unified_exec --json ...`, `tests/test_execute.py` asserts adjacent `("--disable", "unified_exec")` while preserving `gpt-5.6-terra`/`xhigh`, and `corrections.md` SHA-256 is `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`. Owner/root evidence: RED targeted missing-pair assertion exit 1, GREEN targeted 1 passed, focused `tests/test_execute.py` 10/10, full pytest 23 passed/1 pre-existing `xhigh` vs `extra high`, MSVC Debug build exit 0, discovery 214, full CTest 214/214. | Stage 6 implementation evidence docs still absent; await no-push Harness rerun | 10 |
|
||||||
| 7. Physics evaluation | `physics-evaluation-agent` | `pending` | `docs/nonlinear-static-newton-raphson/physics-evaluation.md` | equilibrium, reaction, direction, path/history, energy, symmetry, model coverage가 `pass-for-release-agent`임 | 없음 | Stage 6 passing evidence 필요 | 0 |
|
| 7. Physics evaluation | `physics-evaluation-agent` | `pending` | `docs/nonlinear-static-newton-raphson/physics-evaluation.md` | equilibrium, reaction, direction, path/history, energy, symmetry, model coverage가 `pass-for-release-agent`임 | 없음 | Stage 6 passing evidence 필요 | 0 |
|
||||||
| 8. Release readiness | `release-agent` | `pending` | `docs/nonlinear-static-newton-raphson/release.md` | `ready-for-release` recommendation과 acceptance traceability가 완전함 | 없음 | Stage 7 passing evidence 필요 | 0 |
|
| 8. Release readiness | `release-agent` | `pending` | `docs/nonlinear-static-newton-raphson/release.md` | `ready-for-release` recommendation과 acceptance traceability가 완전함 | 없음 | Stage 7 passing evidence 필요 | 0 |
|
||||||
|
|
||||||
@@ -33,33 +33,55 @@
|
|||||||
### Active Dispatch Package
|
### Active Dispatch Package
|
||||||
|
|
||||||
- feature_id: `nonlinear-static-newton-raphson`
|
- feature_id: `nonlinear-static-newton-raphson`
|
||||||
- current_dispatch: `stage-3-formulation-attempt-1`
|
- current_dispatch: `stage-6-no-push-harness-implementation-rerun`
|
||||||
- target_sub_agent: `formulation-agent`
|
- target_sub_agent: `implementation-agent` via Harness Executor (`python scripts/execute.py nonlinear-static-newton-raphson`; root launch required)
|
||||||
- required_inputs:
|
- required_inputs:
|
||||||
- `docs/nonlinear-static-newton-raphson/requirements.md` (`approved`; user approval date `2026-08-23`; SHA-256 `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`).
|
- User explicit execution request on `2026-08-24`: `Harness/Implementation를 실행해주세요.`
|
||||||
- `docs/nonlinear-static-newton-raphson/research.md` (`passed`; user explicitly approved Stage 2 on `2026-08-23`; SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`).
|
- Attempt 1 failure evidence: no-push Harness command `python scripts/execute.py nonlinear-static-newton-raphson`; `codex exec --json --sandbox workspace-write ...` timed out at `1800.7s`; `_invoke_codex` raised uncaught `subprocess.TimeoutExpired`; no Step 0 source/test edits, no `step0-output.json`, no `MAX_RETRIES` handling.
|
||||||
- `AGENTS.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`, `docs/TOLERANCE.md`, `docs/SOLVER_AGENT_DESIGN.md`.
|
- Bounded Harness repair evidence: Implementation Agent changed only `scripts/execute.py` and `tests/test_execute.py`; TDD RED 3 expected failures, GREEN 3 passed; focused `tests/test_execute.py` 10/10 passed; full pytest 23 passed/1 pre-existing HEAD contract failure `xhigh` actual vs `extra high` expected.
|
||||||
- `docs/linear-static-mitc4-shell/formulation.md`의 approved linear 계약과 §15 gap inventory. §15는 nonlinear 해답으로 복사하지 않는다.
|
- Repair behavior now required: Codex timeout returns structured exit `124` and reaches `MAX_RETRIES`; runner reads `.codex/agents/implementation-agent.toml` and passes `gpt-5.6-terra` plus `xhigh` settings to `codex exec`.
|
||||||
- expected_outputs: `docs/nonlinear-static-newton-raphson/formulation.md`
|
- Root independent review evidence: no new defect found; focused `tests/test_execute.py` 10/10 reproduced; full suite reproduced the same single pre-existing `xhigh` vs `extra high` mismatch.
|
||||||
- acceptance_gate: Formulation Agent가 `fesa-formulation-spec`을 사용하여 strong/weak form, fixed-initial-reference TL kinematics, finite committed/trial triad와 objective update, exact `24 global -> 20 physical + 4 drill` residual/tangent 및 map Hessian, objective numerical drilling potential/Hessian, fixed-global dead force/moment work, prescribed finite-rotation BC path, integration, state/commit/rollback, recovery와 verification identities를 구현 가능하게 정의한다. O-ROT/O-MAP/O-DRILL/O-MOM/O-BC는 unresolved placeholder 없이 승인 범위 안에서 해소되고, requirement traceability와 explicit assumptions/limits가 있다.
|
- Attempt 2 failure evidence: repaired Executor wrote `phases/nonlinear-static-newton-raphson/step0-output.json` with `exitCode` 124 and stderr `Codex timed out after 1800 seconds.`; stdout shows the Implementation Agent completed a turn but every nested command execution remained `status=in_progress`.
|
||||||
- stop_condition: `formulation.md`와 output paths/status/evidence summary/blockers만 Coordinator에 반환한다. Peer/Stage 4를 dispatch하거나 C++/tests/CMake/I/O schema/reference artifact/tolerance/phases/Harness를 생성·변경·실행하지 않는다. 승인된 scope/physics/tolerance/authoritative output/public compatibility를 변경할 필요가 있으면 문서에 임의 반영하지 말고 blocker로 반환한다.
|
- Runtime blocker evidence: nested commands hung for skill file reads, `Get-Date`, `cmd.exe /d /c echo test`, and `exit 0`; root classifies the cause as nested Codex Windows shell tool execution hang, not model delay, build, source, sandbox/auth, or the repaired Executor timeout/no-retry path.
|
||||||
- missing_evidence: Formulation Agent 소유 `formulation.md`, self-audit, O-ROT/O-MAP/O-DRILL/O-MOM/O-BC closure map과 acceptance-gate evidence.
|
- Active process evidence from root: Executor auto-started another internal retry at `2026-08-24T02:58:35+09:00` under `python execute.py` PID 13820 / `codex` PID 7704; root terminated those unauthorized retry PIDs and verified none remain.
|
||||||
|
- Root decision after blocked-no-auto-retry: authorize one bounded Correction Agent diagnostic/rework cycle because the repeated implementation failure is infrastructure/runtime, not physics/source/build.
|
||||||
|
- Correction Agent return: status `blocked`, output `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `C9F93AC99225725C88BB7F0BABC8F7D75D3E05082070090328203DB3776BEFE6`, no runner/test edits from correction, no safe documented CLI flag workaround proven.
|
||||||
|
- User/root runtime update evidence: standalone Codex CLI updated `0.147.0 -> 0.149.1` under `CODEX_HOME=C:\Users\baram\.codex`; `codex doctor --json` reported current/consistent installation.
|
||||||
|
- User/root bounded smoke evidence: baseline still fails through inaccessible WindowsApps `pwsh`, direct `codex sandbox` elevated/unelevated `cmd echo` exits 0, and nested smoke passes only when launch env filters `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` plus `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, aligns `CODEX_HOME`, retains `workspace-write` and hooks, uses implementation-agent `gpt-5.6-terra`/`xhigh`, and passes `--disable unified_exec`; output was exactly `CODEX_SHELL_SMOKE_OK\r\n`.
|
||||||
|
- REWORK-004 Correction Agent return: status `corrected-for-implementation-rerun`; changed only `scripts/execute.py`, `tests/test_execute.py`, `docs/nonlinear-static-newton-raphson/corrections.md`; no Harness phase, C++ source, CMake, reference solver, commit or push.
|
||||||
|
- Coordinator audit: current `scripts/execute.py` lines 300-315 pass exact adjacent args `--disable`, `unified_exec` immediately after `codex exec`; current test `test_invoke_codex_uses_implementation_agent_command_contract` asserts the pair while preserving `gpt-5.6-terra` and `model_reasoning_effort="xhigh"`.
|
||||||
|
- `AGENTS.md`, `docs/SOLVER_AGENT_DESIGN.md`, `docs/HARNESS.md`, `docs/HARNESS_WORKFLOW.md`, `.agents/skills/harness/SKILL.md`, `.codex/hooks.json`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md` SHA-256 `BF4FC7A5CFDEEC19D62A36E1DF7CC34C0B9F614FA0A0FD8D0A321ADC73E69580`
|
||||||
|
- `phases/index.json` SHA-256 `F8BE89D579C303410BD1D2CD17AF33FCAD72BF68D9E10C3F644A39D1AA7331FB`
|
||||||
|
- `phases/nonlinear-static-newton-raphson/index.json` SHA-256 `439B67E1DED442D828EB5C31DAB35D28F32DBA6F66537512CAFFB5616956C137`
|
||||||
|
- Executor-selected initial current Step: `phases/nonlinear-static-newton-raphson/step0.md`, Step 0 `cli-output-lease-and-derived-names`, status `pending`
|
||||||
|
- Approved Stage 1-5 hashes: requirements `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`; research `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`; formulation `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`; numerical-review `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`; reference-model `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`; io `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`.
|
||||||
|
- Preserved materialization evidence: exactly one pending phase entry, 13/13 pending steps, Step 0 remains pending, no implementation evidence docs yet.
|
||||||
|
- expected_outputs:
|
||||||
|
- Executor-managed no-push phase execution from Step 0, with branch/pending selection/retry/timestamps/commits/advancement owned only by `scripts/execute.py`.
|
||||||
|
- Each Implementation Agent session performs only its Executor-selected current Step `RED -> observed failure -> minimal GREEN -> VERIFY`, updates only that Step status payload, and stops.
|
||||||
|
- Final Stage 6 evidence remains `docs/nonlinear-static-newton-raphson/implementation-report.md`, `docs/nonlinear-static-newton-raphson/build-test.md`, and `docs/nonlinear-static-newton-raphson/reference-comparison.md` after the approved phase reaches its final verification Step.
|
||||||
|
- acceptance_gate: Root is explicitly authorized to run no-push `python scripts/execute.py nonlinear-static-newton-raphson` in the isolated worktree using Codex `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, a child PATH filtered of `C:\Program Files\WindowsApps\Microsoft.PowerShell_*` and `C:\Users\baram\AppData\Local\Microsoft\WindowsApps`, `workspace-write`, hooks retained, implementation-agent `gpt-5.6-terra`/`xhigh`, and no `danger-full-access`. Passing Stage 6 still requires successful Implementation phase execution plus Coordinator audit of `implementation-report.md`, `build-test.md`, `reference-comparison.md`, full MSVC x64 Debug build/CTest, blocking reference comparison and no forbidden reference/upstream/tolerance mutation.
|
||||||
|
- stop_condition: If nested shell execution hangs or cannot complete under the exact corrected runner and approved launch envelope, stop as `blocked` with the new evidence; do not broaden to `danger-full-access`, do not run Abaqus/Nastran/reference solvers, do not generate/modify reference CSVs, and do not advance Physics/Release.
|
||||||
|
- missing_evidence: No-push Harness rerun result and Stage 6 implementation evidence docs remain absent.
|
||||||
|
|
||||||
### Latest Sub-Agent Return
|
### Latest Sub-Agent Return
|
||||||
|
|
||||||
- target_sub_agent: `research-agent`
|
- target_sub_agent: `correction-agent`
|
||||||
- output_paths: `docs/nonlinear-static-newton-raphson/research.md`
|
- output_paths:
|
||||||
- status: `passed` (owner); `needs-rework` (user review gate)
|
- `docs/nonlinear-static-newton-raphson/corrections.md`
|
||||||
|
- status: `corrected-for-implementation-rerun` (owner); Coordinator decision `passed-for-implementation-rerun`
|
||||||
- evidence_summary:
|
- evidence_summary:
|
||||||
- 17 external sources cover original MITC4/TL theory, finite rotation, objective/consistent linearization, Full Newton, V&V/MMS and nonlinear shell benchmarks.
|
- `corrections.md` SHA-256 is `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`.
|
||||||
- B-01–B-06 invariant/software checks, B-07F/B-07M large-rotation cantilevers, public NAFEMS 3DNLG-1/9 candidates, locking characterization and shell-MMS gap are separated by applicability.
|
- `scripts/execute.py` SHA-256 is `E36A78E5C0AE7E91361B1AB6B995D2E8CF51569C0E0804D57F54711AFEFFB806`; `tests/test_execute.py` SHA-256 is `1E368382ABA21F5FBAC344E15E1E600B6BDAF4C4528431E4D1A757AA09D54CDE`.
|
||||||
- `reference/shell/` and `reference/shellR/` are explicitly retained as `nlgeom=NO` linear evidence; exact stored nonlinear input/CSV remains an honest Numerical Review gap.
|
- Runner command contract now starts `codex exec --disable unified_exec --json ...` and still passes `--model gpt-5.6-terra`, `--config model_reasoning_effort="xhigh"`, `--sandbox workspace-write`, `--dangerously-bypass-hook-trust`, `--cd <repo>`.
|
||||||
- Objective 24-DOF mapping/drilling, nodal-moment work, prescribed finite-rotation path, invariant tolerances and fixed-step benchmark traversability are routed downstream without inventing contracts.
|
- TDD evidence: targeted RED failed on missing adjacent pair with exit 1; targeted GREEN passed; focused `tests/test_execute.py` 10/10; full pytest remains 23 passed/1 pre-existing `xhigh` vs `extra high`; MSVC Debug build exit 0; CTest discovery 214; full CTest 214/214.
|
||||||
|
- Correction did not run Harness phase, edit C++/CMake/reference artifacts, run reference solvers, commit or push.
|
||||||
- blockers:
|
- blockers:
|
||||||
- User Stage-2 review/approval only.
|
- 없음 for runner-option correction; Stage 6 implementation evidence is still pending.
|
||||||
- self_audit_findings: Coordinator independently confirmed 10 required sections, exact S1–S17 inventory, 12 benchmark sections with artifact/gap/target/cannot-verify/limits/review questions, 11 research-relevant requirement IDs, 14 unique open issues, all local evidence paths present and nonlinear reference artifact hits 0. SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`.
|
- self_audit_findings: Coordinator verified the correction report hash, audited current runner args and regression assertion, checked phase index pending statuses, did not run phase/build/tests/reference solvers, and updated only this isolated worktree `coordination.md`.
|
||||||
- return_contract_check: output path, owner status, source/benchmark coverage, downstream gaps, blockers and ownership confirmation present.
|
- return_contract_check: output path, corrected status, evidence summary, blockers and changed-file assertion are present.
|
||||||
- acceptance_evidence_check: all owner and Coordinator Research evidence gates pass; Stage 2 remains `needs-rework` solely for explicit user approval.
|
- acceptance_evidence_check: REWORK-004 is closed; Stage 6 is eligible for no-push Harness rerun, but no implementation pass evidence exists yet.
|
||||||
|
|
||||||
### Compact Migration Evidence
|
### Compact Migration Evidence
|
||||||
|
|
||||||
@@ -145,15 +167,47 @@
|
|||||||
| 2026-08-23 | Research Agent return and Coordinator audit | `needs-rework` | `research.md` owner pass; Coordinator verified 10 sections, S1–S17, 12 complete benchmark candidates, 11 requirement IDs, 14 unique open issues, local evidence existence, nonlinear stored reference hits 0 and forbidden changes 0 | `needs-user-decision` | Present Stage-2 artifact for explicit user approval |
|
| 2026-08-23 | Research Agent return and Coordinator audit | `needs-rework` | `research.md` owner pass; Coordinator verified 10 sections, S1–S17, 12 complete benchmark candidates, 11 requirement IDs, 14 unique open issues, local evidence existence, nonlinear stored reference hits 0 and forbidden changes 0 | `needs-user-decision` | Present Stage-2 artifact for explicit user approval |
|
||||||
| 2026-08-23 | Research explicit user approval | `passed` | User explicitly approved `research.md`; Research Agent and Coordinator evidence already passed; approved artifact SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE` | `needs-formulation` | Dispatch Formulation Agent for bounded Stage 3 evidence |
|
| 2026-08-23 | Research explicit user approval | `passed` | User explicitly approved `research.md`; Research Agent and Coordinator evidence already passed; approved artifact SHA-256 `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE` | `needs-formulation` | Dispatch Formulation Agent for bounded Stage 3 evidence |
|
||||||
| 2026-08-23 | Formulation dispatch attempt 1 | `in-progress` | Approved Stage-1/2 baselines and project contracts audited; bounded package requires O-ROT/O-MAP/O-DRILL/O-MOM/O-BC closure without downstream contract changes | `needs-formulation` | Await Formulation Agent return and independently audit Stage-3 evidence |
|
| 2026-08-23 | Formulation dispatch attempt 1 | `in-progress` | Approved Stage-1/2 baselines and project contracts audited; bounded package requires O-ROT/O-MAP/O-DRILL/O-MOM/O-BC closure without downstream contract changes | `needs-formulation` | Await Formulation Agent return and independently audit Stage-3 evidence |
|
||||||
|
| 2026-08-23 | Formulation Agent return and Coordinator audit | `needs-rework` | `formulation.md` owner pass/`ready-for-numerical-review`; Coordinator verified 18 required sections, exact 7/7 formulation closure IDs, complete 24-coordinate residual/tangent term inventory, state/integration/recovery/verification/traceability sections, balanced math/fence structure, upstream hash preservation and forbidden changes 0; output SHA-256 `516EB692619C6AAB1AD09061A671697BB7C1B821B0B60BC5A2831CA5D09E131D` | `needs-user-decision` | Present Stage-3 artifact for explicit user approval; do not dispatch Stage 4 |
|
||||||
|
| 2026-08-23 | Formulation independent consistency review | `needs-rework` | §13.4 uses rotation matrix symbol `R_I` as reaction force, creating dimensional collision; §§4.4/5/11.2 mix tolerance-based source-moment admissibility with exact tangency/projection work statements. Both are bounded formulation-document defects and first normalized attempts. | `needs-formulation` | Same Formulation Agent targeted rework attempt 2; preserve scope/threshold/public meaning |
|
||||||
|
| 2026-08-23 | Formulation bounded rework attempt 2 return and Coordinator audit | `needs-rework` | Owner pass; reaction force/generalized moment/spatial moment 기호·단위가 rotation matrix `R_I`와 분리되고 force/moment balance가 corrected. Immutable fixed-global source, unchanged `rho_M <= 1e-12`, exact projected work covector, removed director component/no drill channel, `DP`/`DJ_l`/map-Hessian을 포함한 chart/global residual-tangent identity가 일치함. 18 sections/7 closures, upstream hashes와 forbidden-change boundary 보존; SHA-256 `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`. | `needs-user-decision` | Present corrected Stage-3 artifact for explicit user approval; do not dispatch Stage 4 |
|
||||||
|
| 2026-08-23 | Formulation explicit user approval | `passed` | Task payload states the user explicitly approved `docs/nonlinear-static-newton-raphson/formulation.md`; approved SHA-256 `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0` retained. | `needs-numerical-review` | Dispatch `numerical-review-agent` only |
|
||||||
|
| 2026-08-23 | Numerical/reference dispatch attempt 1 | `blocked` | Coordinator prepared bounded Stage 4 package, but no collaboration `spawn_agent` tool is exposed in this agent environment; `tool_search` found no dispatch tool; `codex exec` fallback was interrupted, is not a visible child-agent dispatch, and produced no Stage 4 outputs. | `blocked` | Expose/route the valid `numerical-review-agent` collaboration dispatch, then rerun Stage 4 owner task |
|
||||||
|
| 2026-08-23 | Numerical/reference owner return | `needs-rework` | Root-dispatched `numerical-review-agent` returned both outputs with owner status `pass-for-io-definition`, shellNL/shell read-only inventory, row prechecks and blockers none. Coordinator/root audit found a blocking cross-report contradiction on stress CSV and `RM3` comparison disposition, so acceptance evidence is not coherent. | `needs-numerical-review` | Same `numerical-review-agent` bounded reconciliation; do not dispatch I/O |
|
||||||
|
| 2026-08-23 | Numerical/reference corrected return | `passed` | Corrected current reports have owner status `pass-for-io-definition`; stress CSVs are optional read-only inspection/order evidence only, `RM3` is excluded, and required external comparison is displacement, reaction force and physical spatial `RM1/RM2`. Coordinator verified required sections, exact paths, no concrete HDF5 dataset paths and no forbidden file-change scope. | `needs-user-decision` | Present Stage 4 artifacts for explicit user approval; do not dispatch I/O |
|
||||||
|
| 2026-08-23 | Numerical/reference explicit user approval | `passed` | User explicitly approved Stage 4 documents and requested next gate; approved hashes retained for requirements, research, formulation, numerical-review and reference-model. | `needs-io-definition` | Prepare bounded `io-definition-agent` dispatch package |
|
||||||
|
| 2026-08-23 | I/O Definition dispatch package | `in-progress` | Coordinator prepared Stage 5 package requiring `fesa-io-contract`, exact Stage 1-4 inputs, corrected reference disposition, authoritative `results.h5`, and only `docs/nonlinear-static-newton-raphson/io.md` output. | `needs-io-definition` | Root profile dispatch to `io-definition-agent`; await owner return |
|
||||||
|
| 2026-08-23 | I/O Definition owner return and Coordinator audit | `needs-rework` | Owner returned `io.md` status `ready-for-coordinator-review`, SHA-256 `75D702301D6285F151D913DCD0351F4AD302C4C24A004DD5841A576592D675FC`, blockers none. Coordinator confirmed blocking defects in `--output` substring rejection, Newton iteration log schema, `VARIABLE=PRESELECT` ignored output request acceptance and repository-wide non-Newton log lifecycle. | `needs-io-definition` | Same `io-definition-agent` bounded correction; do not start Implementation Planning |
|
||||||
|
| 2026-08-23 | I/O Definition bounded rework return and Coordinator audit | `passed` | Owner returned corrected `io.md` status `ready-for-coordinator-review`, SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28`, blockers none. Coordinator verified REWORK-002 closure, DECISION-028/029/030 output lifecycle/path/log evidence, HDF5/reference/tolerance preservation and no stale narrow `--output` rule. | `needs-user-decision` | Present Stage 5 artifact for explicit user approval; do not start Implementation Planning |
|
||||||
|
| 2026-08-23 | I/O Definition explicit user approval | `passed` | User explicitly approved `docs/nonlinear-static-newton-raphson/io.md` SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28` and requested the next Implementation Planning gate. | `needs-implementation-plan` | Prepare bounded `implementation-planning-agent` draft package only |
|
||||||
|
| 2026-08-23 | Implementation Planning draft dispatch package | `in-progress` | Coordinator prepared Stage 6 planning package requiring `fesa-cpp-msvc-tdd` and project-local `harness`, approved Stage 1-5 hashes, exact reference/tolerance disposition and draft-only stop condition. | `needs-implementation-plan` | Root profile dispatch to `implementation-planning-agent`; await draft/interview return |
|
||||||
|
| 2026-08-23 | Implementation Planning draft owner return and Coordinator audit | `passed` | Owner returned draft status `draft-ready-for-user-review`, slug `nonlinear-static-newton-raphson`, Steps `0..12`, no files changed, no interview issue/blocker. Coordinator verified requirements/category mapping, TDD/Harness step shape, prepared-analysis orchestration boundary, exact reference/tolerance preservation and no forbidden execution or file creation. | `needs-user-decision` | Present Stage 6 draft for explicit user approval or bounded rework request; do not materialize files yet |
|
||||||
|
| 2026-08-24 | Implementation Planning draft explicit user approval | `passed` | User explicitly approved the 13-Step draft and requested `implementation-plan.md` plus pending Harness phase file creation. | `needs-implementation-plan` | Prepare bounded materialization package for `implementation-planning-agent` only |
|
||||||
|
| 2026-08-24 | Implementation Planning materialization dispatch package | `in-progress` | Coordinator authorized only `implementation-plan.md`, append pending phase entry, create phase index and `step0.md`..`step12.md` pending with no executor timestamps; source/tests/CMake/upstream/reference/tolerance/evidence docs and Harness/build/test execution remain forbidden. | `needs-implementation-plan` | Root profile dispatch to `implementation-planning-agent`; await materialization return |
|
||||||
|
| 2026-08-24 | Implementation Planning materialization owner return and Coordinator audit | `passed` | `implementation-plan.md`, `phases/index.json`, phase index and `step0.md`..`step12.md` are materialized after user approval. Coordinator/root audit passed phase uniqueness, 13/13 pending steps without executor metadata, 151 root assertions, reference hashes/row counts and no unauthorized evidence docs/execution/source/test/CMake/reference edits. | `ready-for-implementation` | Await separate explicit Harness/implementation execution request; do not run Executor automatically |
|
||||||
|
| 2026-08-24 | Harness/Implementation execution authorization and dispatch package | `in-progress` | User explicitly requested Harness/Implementation execution. Coordinator verified materialized phase still has Step 0 `cli-output-lease-and-derived-names` as the first pending Step, preserved Stage 1-5 hashes and materialization evidence, and prepared no-push `scripts/execute.py nonlinear-static-newton-raphson` dispatch. | `needs-implementation` | Run no-push Harness executor; await Implementation/Harness return before any physics/release transition |
|
||||||
|
| 2026-08-24 | Harness/Implementation execution attempt 1 | `needs-rework` | No-push Harness attempt failed before Step 0 evidence: `codex exec --json --sandbox workspace-write ...` timed out at `1800.7s`; `_invoke_codex` raised uncaught `subprocess.TimeoutExpired`; no source/test edits, `step0-output.json`, `MAX_RETRIES`, or Step evidence. Normalized classification `harness-uncaught-step-codex-timeout-no-retry` attempt 1. | `needs-implementation` | Bounded Harness repair before retry; do not route to Correction Agent for first clear harness failure |
|
||||||
|
| 2026-08-24 | Harness repair after attempt 1 | `passed` | Implementation Agent repaired Harness timeout/profile handling in `scripts/execute.py` with tests in `tests/test_execute.py`; RED 3 expected failures, GREEN 3 passed, focused 10/10 passed, full pytest 23 passed/1 pre-existing `xhigh` vs `extra high` mismatch. Root review found no new defect and reproduced the same evidence. No phase execution, phase/source/CMake/reference/evidence docs edit, or reference solver activity. | `needs-implementation` | Retry no-push Harness attempt 2 for Executor-selected Step 0 in workspace-write; if the same normalized timeout recurs, stop automatic rework and route to `needs-user-decision` or `blocked` |
|
||||||
|
| 2026-08-24 | Harness/Implementation execution attempt 2 | `blocked` | Repaired Executor produced `step0-output.json` with `exitCode` 124 and stderr `Codex timed out after 1800 seconds.`. The Implementation Agent turn completed, but every nested shell `command_execution` remained `status=in_progress` even for `Get-Date`, `cmd echo`, and `exit 0`; Step 0 stayed pending with no production/test changes. Root cause is `harness-nested-codex-windows-shell-tool-execution-hang` attempt 2. | `blocked` | Stop remaining automatic retries; no workaround/further Harness execution until explicit user/root decision or external runtime fix |
|
||||||
|
| 2026-08-24 | Root correction-cycle authorization | `in-progress` | Root authorized one bounded Correction Agent diagnostic/rework cycle for the repeated infrastructure/runtime failure; unauthorized retry PIDs have been terminated and none remain. Coordinator prepared a correction package limited to no-op/tool smoke reproduction, local Codex CLI/config option inspection, documented flag hypothesis testing, and optional TDD runner changes in `scripts/execute.py`/`tests/test_execute.py`. | `needs-correction` | Root profile dispatch to `correction-agent` is required because this Coordinator runtime exposes no callable `spawn_agent` tool |
|
||||||
|
| 2026-08-24 | Correction Agent return and Coordinator audit | `blocked` | Correction Agent returned `blocked` and created only `docs/nonlinear-static-newton-raphson/corrections.md` SHA-256 `C9F93AC99225725C88BB7F0BABC8F7D75D3E05082070090328203DB3776BEFE6`. Baseline smoke reproduced no nested shell completion; `--disable code_mode_host` failed closed; `--enable unified_exec` hung; combined flags failed closed. Root verified no nonlinear Harness/Codex processes remain, all 13 steps pending, Python 23 passed/1 pre-existing failure, MSVC build exit 0, discovery 214 and CTest 214/214. | `blocked` | No further Harness retry until external Codex runtime update/repair plus bounded shell smoke success |
|
||||||
|
| 2026-08-24 | Codex `0.149.1` smoke pass and runner preflight | `needs-rework` | User/root authorized Codex CLI update, bounded smoke and Harness rerun. Smoke passed only with aligned `CODEX_HOME`, filtered WindowsApps PATH entries and `--disable unified_exec`; current `scripts/execute.py` does not pass that flag to nested `codex exec`, while local `codex exec --help` confirms `--disable <FEATURE>` support. | `needs-correction` | Dispatch bounded runner-option correction before any no-push Harness phase rerun |
|
||||||
|
| 2026-08-24 | REWORK-004 Correction return and Coordinator audit | `passed` | Correction returned `corrected-for-implementation-rerun`; runner now passes adjacent `--disable`, `unified_exec` after `codex exec`; regression test asserts the command contract; `corrections.md` SHA-256 `82572437689B41323B6533C2361F2F12BF07B5ED305825AA84C56AEEDC729930`; focused tests 10/10, full pytest only known pre-existing mismatch, MSVC build and 214/214 CTest pass per owner/root evidence. | `needs-implementation` | Root is authorized to run no-push `python scripts/execute.py nonlinear-static-newton-raphson` with Codex `0.149.1`, aligned `CODEX_HOME`, filtered child PATH, `workspace-write`, hooks retained and no `danger-full-access` |
|
||||||
|
|
||||||
- current_dispatch: `stage-3-formulation-attempt-1`
|
- current_dispatch: `stage-6-no-push-harness-implementation-rerun`
|
||||||
- current_workflow_state: `needs-formulation`
|
- current_workflow_state: `needs-implementation`
|
||||||
- next_gate_requires_user_approval: `false` (owner evidence audit 선행)
|
- next_gate_requires_user_approval: `false` (user/root already authorized Codex update, bounded smoke and Harness rerun)
|
||||||
|
|
||||||
## 5. Risk, Blocker, and User-Decision Register
|
## 5. Risk, Blocker, and User-Decision Register
|
||||||
|
|
||||||
| id | type | description | owner | status |
|
| id | type | description | owner | status |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
|
| BLOCKER-001 | dispatch | Stage 4 requires a valid `numerical-review-agent` child dispatch. Root supplied the valid profile dispatch and owner return, so this runtime-tooling blocker no longer blocks the gate. | `coordinator-agent` / runtime tooling | closed |
|
||||||
|
| REWORK-001 | report-contract | Stage 4 returned evidence had a cross-report contradiction on stress CSV and `RM3` comparison disposition. Corrected reports now consistently treat stress CSVs as optional read-only inspection/order evidence only and exclude `RM3` from comparison. | `numerical-review-agent` | closed |
|
||||||
|
| REWORK-002 | io-contract | Stage 5 `io.md` bounded correction completed: public CLI `--output` substring rejection, Newton iteration log schema, exact `VARIABLE=PRESELECT` ignored-with-warning handling, repository-wide non-Newton log lifecycle, DECISION-028/029/030 path/log lifecycle and collision semantics are now recorded in `io.md`. | `io-definition-agent` | closed |
|
||||||
|
| REWORK-003 | harness | Stage 6 attempt 1 timeout/no-retry defect is repaired in Harness infrastructure: timeouts now return structured exit `124` through `MAX_RETRIES`, and implementation-agent profile settings are passed to Codex. Same normalized failure attempt count remains 1; attempt 2 is authorized and same-class recurrence stops automatic rework. | `implementation-agent` via Harness Executor | closed |
|
||||||
|
| BLOCKER-002 | harness-runtime | Nested Codex Windows shell tool execution hung inside Implementation/Correction Codex sessions. It is mitigated for the authorized rerun by Codex CLI `0.149.1`, aligned `CODEX_HOME`, filtered WindowsApps PATH entries, smoke success with exact `CODEX_SHELL_SMOKE_OK` output, and REWORK-004 runner retention of `--disable unified_exec`. Reopen only if the same hang recurs under the exact approved envelope. | external Codex runtime / user-root decision | mitigated |
|
||||||
|
| BLOCKER-003 | dispatch-runtime | This Coordinator runtime exposed no callable `spawn_agent` tool, but root successfully performed the required Correction Agent profile dispatch. | coordinator/root tooling | closed |
|
||||||
|
| REWORK-004 | harness | Corrected: `scripts/execute.py` now passes adjacent `--disable`, `unified_exec` immediately after `codex exec`; `tests/test_execute.py` asserts this while preserving terra/xhigh routing; `corrections.md` records RED/GREEN/VERIFY and no Harness phase/source C++/CMake/reference edits. | `correction-agent` | closed |
|
||||||
| RISK-001 | architecture | 기존 `LinearStaticAnalysis` private lifecycle은 단일 factorization/substitution과 final frame만 소유하므로 nonlinear increment/iteration/state commit을 삽입하면 ADR 경계를 위반한다. | `coordinator-agent` routing | open |
|
| RISK-001 | architecture | 기존 `LinearStaticAnalysis` private lifecycle은 단일 factorization/substitution과 final frame만 소유하므로 nonlinear increment/iteration/state commit을 삽입하면 ADR 경계를 위반한다. | `coordinator-agent` routing | open |
|
||||||
| RISK-002 | scope | `Newton–Raphson`은 solution algorithm이고 geometric/material/contact nonlinearity 범위를 단독으로 결정하지 않는다. | `requirement-agent` | mitigated by DECISION-001 |
|
| RISK-002 | scope | `Newton–Raphson`은 solution algorithm이고 geometric/material/contact nonlinearity 범위를 단독으로 결정하지 않는다. | `requirement-agent` | mitigated by DECISION-001 |
|
||||||
| RISK-003 | contract | 현재 `Element`는 displacement-dependent residual/consistent tangent/trial state 계약이 없고 `AnalysisState`는 nonlinear history를 소유하지 않는다. | downstream formulation/architecture gates | open |
|
| RISK-003 | contract | 현재 `Element`는 displacement-dependent residual/consistent tangent/trial state 계약이 없고 `AnalysisState`는 nonlinear history를 소유하지 않는다. | downstream formulation/architecture gates | open |
|
||||||
@@ -193,13 +247,19 @@
|
|||||||
| DECISION-032 | user process decision | `requirements.md`를 핵심 Stage-1 계약으로 압축하고 OQ chronology, diagnostic/path/concurrency trivia와 반복 handoff를 제거한다. Minor details는 downstream specialist convention/evidence로 정하며 approved scope/physics/tolerance/public compatibility를 바꿀 때만 사용자 결정을 다시 요청한다. | user via Coordinator | closed |
|
| DECISION-032 | user process decision | `requirements.md`를 핵심 Stage-1 계약으로 압축하고 OQ chronology, diagnostic/path/concurrency trivia와 반복 handoff를 제거한다. Minor details는 downstream specialist convention/evidence로 정하며 approved scope/physics/tolerance/public compatibility를 바꿀 때만 사용자 결정을 다시 요청한다. | user via Coordinator | closed |
|
||||||
| DECISION-033 | design approval | Target 363 lines, 24 canonical requirements와 24-row Matrix, approved semantic-loss 0의 compact rewrite design. | user via Coordinator | closed |
|
| DECISION-033 | design approval | Target 363 lines, 24 canonical requirements와 24-row Matrix, approved semantic-loss 0의 compact rewrite design. | user via Coordinator | closed |
|
||||||
| DECISION-034 | user process decision | Requirement Agent는 approved physics/scope/tolerance/authoritative-output/public compatibility를 바꾸는 essential decision만 사용자에게 묻고, specialist detail은 owning downstream stage가 repository evidence와 conventional FEM practice로 정한다. Equivalence claim은 금지한다. | user via Coordinator; `.codex/agents/requirement-agent.toml` | closed |
|
| DECISION-034 | user process decision | Requirement Agent는 approved physics/scope/tolerance/authoritative-output/public compatibility를 바꾸는 essential decision만 사용자에게 묻고, specialist detail은 owning downstream stage가 repository evidence와 conventional FEM practice로 정한다. Equivalence claim은 금지한다. | user via Coordinator; `.codex/agents/requirement-agent.toml` | closed |
|
||||||
|
| DECISION-035 | user approval | User explicitly approved Stage 5 `docs/nonlinear-static-newton-raphson/io.md` SHA-256 `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28` and requested Implementation Planning. | user via Coordinator | closed |
|
||||||
|
| DECISION-036 | user approval | User explicitly approved the Stage 6 Implementation Planning 13-Step draft on `2026-08-24` and authorized creation of `implementation-plan.md` plus pending Harness phase files. | user via Coordinator | closed |
|
||||||
|
| DECISION-037 | user approval | User explicitly requested no-push Harness/Implementation execution for materialized phase `nonlinear-static-newton-raphson` on `2026-08-24`. | user via Coordinator | closed |
|
||||||
|
| DECISION-038 | user/root runtime approval | User/root authorized Codex CLI update, shell smoke and no-push Harness rerun. Accepted runtime envelope is Codex CLI `0.149.1`, `CODEX_HOME=C:\Users\baram\.codex`, launch-env-only WindowsApps PATH filtering, `workspace-write`, hooks retained, implementation-agent `gpt-5.6-terra`/`xhigh`, no `danger-full-access`, and `--disable unified_exec`. | user/root via Coordinator | closed |
|
||||||
|
| USER-DECISION-001 | user decision | Stage 6 Implementation Planning draft Steps `0..12` were approved on `2026-08-24`; materialization is authorized for `implementation-planning-agent`. | user via Coordinator | closed |
|
||||||
|
|
||||||
## 6. Rework-Loop Control and Stop Condition
|
## 6. Rework-Loop Control and Stop Condition
|
||||||
|
|
||||||
- normalized_failure_attempts: `requirements-next-question-routing-mismatch`: 1; `requirements-output-failure-atomicity-scope-ambiguity`: 1; `requirements-compact-public-contract-omission`: 1
|
- normalized_failure_attempts: `requirements-next-question-routing-mismatch`: 1; `requirements-output-failure-atomicity-scope-ambiguity`: 1; `requirements-compact-public-contract-omission`: 1; `formulation-equilibrium-reaction-symbol-collision`: 1; `formulation-moment-admissibility-work-inconsistency`: 1; `numerical-review-cross-report-disposition-contradiction`: 1; `io-contract-public-cli-log-output-request-gap`: 1; `harness-nested-codex-windows-shell-tool-execution-hang`: 2
|
||||||
- automatic_rework_limit: 동일 normalized failure classification `2`회
|
- automatic_rework_limit: 동일 normalized failure classification `2`회
|
||||||
- correction_agent_policy: 명확한 implementation failure는 먼저 `implementation-agent`에 반환하고, 반복되거나 원인이 불명확할 때만 `correction-agent`를 dispatch한다.
|
- correction_agent_policy: 명확한 implementation failure는 먼저 `implementation-agent`에 반환하고, 반복되거나 원인이 불명확할 때만 `correction-agent`를 dispatch한다.
|
||||||
- stop_condition: 동일 classification이 두 번이면 자동 rework를 중단하고 workflow를 `needs-user-decision` 또는 `blocked`로 전환한다.
|
- stop_condition: 동일 classification이 두 번이면 자동 rework를 중단하고 workflow를 `needs-user-decision` 또는 `blocked`로 전환한다.
|
||||||
|
- correction_cycle_authorization: Root-authorized REWORK-004 correction returned `corrected-for-implementation-rerun`; no further correction is active. If the same nested shell hang recurs under the exact corrected runner and approved launch envelope, stop as `blocked` rather than broadening privileges.
|
||||||
|
|
||||||
## 7. Final Workflow Closure
|
## 7. Final Workflow Closure
|
||||||
|
|
||||||
@@ -209,11 +269,11 @@
|
|||||||
|
|
||||||
## 8. No-Change Assertion
|
## 8. No-Change Assertion
|
||||||
|
|
||||||
- source_code: 변경 없음
|
- source_code: production solver source 변경 없음; earlier Harness repair and REWORK-004 owners modified only `scripts/execute.py` within runner scope.
|
||||||
- tests: 변경 없음
|
- tests: production C++ tests 변경 없음; earlier Harness repair and REWORK-004 owners modified only `tests/test_execute.py` within Harness Python test scope.
|
||||||
- CMake: 변경 없음
|
- CMake: 변경 없음
|
||||||
- reference_artifacts: 생성·수정·rename 없음
|
- reference_artifacts: 생성·수정·rename 없음
|
||||||
- tolerance_policies: 변경 없음
|
- tolerance_policies: 변경 없음
|
||||||
- phase_files: 생성 없음
|
- phase_files: user-approved planning owner가 `phases/index.json` pending entry와 `phases/nonlinear-static-newton-raphson/index.json`, `step0.md`..`step12.md`를 materialize함; Executor attempt 2 generated `phases/nonlinear-static-newton-raphson/step0-output.json`; Step 0 remains pending and Coordinator did not edit phase files.
|
||||||
- Harness: 실행하지 않음
|
- Harness: Implementation Agent bounded repair와 REWORK-004는 `scripts/execute.py`와 `tests/test_execute.py`에 한정됨; REWORK-004 did not run nonlinear Harness phase, commit or push. Coordinator did not run Harness/phase/build/test; root no-push rerun is now authorized under the approved corrected envelope.
|
||||||
- feature_documents: `coordination.md`, `requirements.md`, `research.md`만 생성됨
|
- feature_documents: 이번 coordinator update에서는 isolated worktree의 `coordination.md`만 갱신함; Correction Agent가 `docs/nonlinear-static-newton-raphson/corrections.md`를 갱신했고 `implementation-report.md`, `build-test.md`, `reference-comparison.md`는 아직 생성되지 않음
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
# Nonlinear Static Newton-Raphson Correction Report
|
||||||
|
|
||||||
|
## 1. Metadata
|
||||||
|
|
||||||
|
| key | value |
|
||||||
|
| --- | --- |
|
||||||
|
| feature_id | `nonlinear-static-newton-raphson` |
|
||||||
|
| source failure report | `docs/nonlinear-static-newton-raphson/coordination.md`; `phases/nonlinear-static-newton-raphson/step0-output.json` |
|
||||||
|
| source implementation plan | `docs/nonlinear-static-newton-raphson/implementation-plan.md` |
|
||||||
|
| status | `corrected-for-implementation-rerun` |
|
||||||
|
| owner_agent | `correction-agent` |
|
||||||
|
| date | `2026-08-24` |
|
||||||
|
|
||||||
|
`implementation-report.md`, `build-test.md`, `reference-comparison.md`는 아직 생성되지 않았으므로 현재 Coordinator failure evidence와 Executor의 `step0-output.json`을 source failure report로 사용했다.
|
||||||
|
|
||||||
|
Sections 2-6의 Codex `0.147.0` 내용은 initial correction history이며, current REWORK-004 status와 증거는 Sections 7-9가 supersede한다.
|
||||||
|
|
||||||
|
## 2. Failure Triage
|
||||||
|
|
||||||
|
- classification: `harness`
|
||||||
|
- normalized classification: `harness-nested-codex-windows-shell-tool-execution-hang`
|
||||||
|
- first failed command:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
codex exec --json --model gpt-5.6-terra --config 'model_reasoning_effort="xhigh"' --sandbox workspace-write --dangerously-bypass-hook-trust --cd C:\git\FESADev\.worktrees\nonlinear-static-newton-raphson -
|
||||||
|
```
|
||||||
|
|
||||||
|
- failed target or test: nested shell smoke `cmd.exe /d /c echo CODEX_SHELL_SMOKE_OK`
|
||||||
|
- evidence tail: baseline diagnostic는 45초 안에 종료되지 않았다. JSONL에는 `item.started`, `type=command_execution`, `status=in_progress`가 기록됐지만 대응하는 completion event와 `CODEX_SHELL_SMOKE_OK` 출력이 없었다. 진단 root PID `11292`와 관찰된 descendant PID tree를 `taskkill /PID 11292 /T /F`로 종료한 뒤 `remainingPids=[]`를 확인했다.
|
||||||
|
- historical evidence: `step0-output.json`도 exit code `124`, stderr `Codex timed out after 1800 seconds.`를 기록했고 `Get-Date`, `cmd.exe /d /c echo test`, `exit 0` 등의 nested command가 `status=in_progress`에 머물렀다.
|
||||||
|
|
||||||
|
## 3. Root Cause Summary
|
||||||
|
|
||||||
|
실패 경계는 repaired Python Executor의 timeout/retry 처리나 FESA C++ 구현이 아니라 local `codex-cli 0.147.0`의 nested command execution runtime이다. 같은 worktree에서 direct PowerShell과 `cmd.exe`는 정상 실행되고, focused Harness Python test도 통과하며, runner-equivalent Codex baseline만 nested shell completion을 반환하지 않았다.
|
||||||
|
|
||||||
|
Local CLI help는 `--disable <FEATURE>`와 `--enable <FEATURE>`를 문서화하고, `codex features list`는 `code_mode_host`를 `stable true`, `shell_tool`을 `stable true`, `unified_exec`를 `stable false`, `hooks`를 `stable true`로 보고했다. 다음 좁은 가설을 한 변수씩 검사했다.
|
||||||
|
|
||||||
|
| variant | result | command completion evidence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| baseline | 45.318초 timeout 후 exact PID tree cleanup | `item.started/status=in_progress`; completion 및 echo output 없음 |
|
||||||
|
| `--disable code_mode_host` | exit `0`, 33.322초 | shell 미실행; stderr `code-mode host is disabled`; completion event 없음 |
|
||||||
|
| `--enable unified_exec` | 45.299초 timeout 후 exact PID tree cleanup | completion event 및 echo output 없음 |
|
||||||
|
| `--disable code_mode_host --enable unified_exec` | exit `0`, 25.922초 | shell 미실행; 동일한 fail-closed host-disabled error |
|
||||||
|
|
||||||
|
따라서 `--disable code_mode_host`는 shell execution을 복구하지 않고 tool host를 fail-closed로 제거한다. `unified_exec`도 단독 또는 조합에서 실제 shell completion을 만들지 못했다. Codex 내부 결함의 더 세부 원인은 repository evidence로 확정할 수 없으며, 안전한 documented runner flag workaround는 입증되지 않았다. 이는 implementation defect, test defect 또는 CMake registration issue가 아니라 external Codex runtime blocker다.
|
||||||
|
|
||||||
|
## 4. Correction Scope
|
||||||
|
|
||||||
|
- changed source files: `scripts/execute.py` (`codex exec` argv에 adjacent `--disable`, `unified_exec` 추가)
|
||||||
|
- changed header files: 없음
|
||||||
|
- changed test files: `tests/test_execute.py` (Implementation Agent command contract regression assertion 추가)
|
||||||
|
- changed CMake files: 없음
|
||||||
|
- changed report files: `docs/nonlinear-static-newton-raphson/corrections.md`
|
||||||
|
- excluded upstream contract files: `requirements.md`, `research.md`, `formulation.md`, `numerical-review.md`, `reference-model.md`, `io.md`, `implementation-plan.md`
|
||||||
|
- excluded artifacts/policies: phase definition/index, production C++, reference inputs/CSV, `docs/TOLERANCE.md`
|
||||||
|
|
||||||
|
초기 correction cycle에서는 safe workaround가 입증되지 않아 runner/test를 변경하지 않았다. 이후 user/root가 Codex `0.149.1`의 bounded smoke로 `--disable unified_exec` runtime envelope를 입증했고, REWORK-004에서 그 pair만 TDD로 추가했다. 기존 Harness-repair 변경과 다른 owner의 dirty-worktree 변경은 그대로 보존했다.
|
||||||
|
|
||||||
|
## 5. Verification Evidence
|
||||||
|
|
||||||
|
| purpose | command | result |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| installed CLI | `codex --version` | exit `0`; `codex-cli 0.147.0` |
|
||||||
|
| documented options | `codex exec --help`; `codex features list` | exit `0`; `--enable/--disable`, `code_mode_host`, `unified_exec`, `shell_tool`, `hooks` 확인 |
|
||||||
|
| targeted reproduction | runner-equivalent `codex exec ... --sandbox workspace-write ...` + one echo tool request | 45초 timeout; command started, completion/output 없음; exact tree cleanup 후 remaining PID 0 |
|
||||||
|
| focused Harness Python | `uv run --with pytest python -m pytest -v -rs tests/test_execute.py` | exit `0`; 10 passed |
|
||||||
|
| full Harness Python | `uv run --with pytest python -m pytest -v -rs` | exit `1`; 23 passed, 1 failed |
|
||||||
|
| MSVC Debug build | `cmake --build .harness/build --config Debug` | exit `0`; solver/CLI/unit/integration/reference targets built |
|
||||||
|
| CTest discovery | `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | exit `0`; 214 tests discovered |
|
||||||
|
| full CTest | `ctest --test-dir .harness/build -C Debug --output-on-failure` | exit `0`; 214/214 passed |
|
||||||
|
|
||||||
|
`.harness/config.json`은 없었다. Existing `.harness/build/CMakeCache.txt`는 `Visual Studio 18 2026`, `x64`, approved local GoogleTest/MKL/TBB/HDF5 paths를 사용하므로 Harness auto-detected build tree를 재사용했다.
|
||||||
|
|
||||||
|
Full Python failure는 pre-existing out-of-scope contract mismatch다: `test_agent_toml_and_limited_skill_yaml_schemas_are_parseable`가 actual `xhigh`와 expected `extra high`를 비교한다. Dispatch 지시에 따라 이 test, `AGENTS.md`, agent profile을 변경하지 않았다.
|
||||||
|
|
||||||
|
Stop hook은 Harness Step 실행을 금지한 이번 correction session에서 별도 Codex Step 종료 evidence를 생성하지 않았다. Hook entry point의 수동 실행은 project contract가 금지하므로 대신 config-resolved full MSVC build와 full CTest를 직접 실행해 결과를 위에 기록했다.
|
||||||
|
|
||||||
|
## 6. Traceability
|
||||||
|
|
||||||
|
| requirement id | task id | test id | failing command | corrected file | acceptance criterion |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| `FESA-REQ-NSNR-083` | Step 0 `cli-output-lease-and-derived-names` | `CORR-HARNESS-SMOKE-001` | runner-equivalent `codex exec` invoking `cmd.exe /d /c echo CODEX_SHELL_SMOKE_OK` | 없음 | workspace-write, hooks, `gpt-5.6-terra`/`xhigh`, no-push, no `danger-full-access`를 유지한 실제 shell completion과 exact echo output; 실패 |
|
||||||
|
| `FESA-REQ-NSNR-083` | Step 0 `cli-output-lease-and-derived-names` | `CORR-HARNESS-SMOKE-002` | same smoke with `--disable code_mode_host` | 없음 | shell completion 복구; 실패 (`code-mode host is disabled`) |
|
||||||
|
|
||||||
|
Runner correction acceptance criterion이 충족되지 않았으므로 Implementation Step 0의 `NSNR-CLI-*` RED/GREEN은 시작되지 않았고 Step 0 status는 `pending`으로 유지된다.
|
||||||
|
|
||||||
|
## 7. Handoff Recommendation
|
||||||
|
|
||||||
|
- recommendation: Coordinator Agent를 통해 Implementation Agent에 `needs-implementation-rerun` 요청.
|
||||||
|
- corrected runner contract: nested command는 `codex exec --disable unified_exec --json ...` 순서로 실행된다.
|
||||||
|
- preserved execution contract: Coordinator가 관리하는 rerun launch environment는 Codex `0.149.1`, aligned `CODEX_HOME`, approved WindowsApps PATH filtering, `workspace-write`, project hooks, `gpt-5.6-terra`, `xhigh`, no-push, no `danger-full-access`를 유지해야 한다.
|
||||||
|
- scope boundary: 이 correction은 runner option gate만 복구했다. Harness phase, Implementation Step 0, reference comparison 또는 physics success를 주장하지 않는다.
|
||||||
|
|
||||||
|
## 8. Stop Condition
|
||||||
|
|
||||||
|
- repeated failure: normalized classification attempt `2`는 초기 Codex `0.147.0` failure history로 보존한다.
|
||||||
|
- external mitigation: user/root의 Codex `0.149.1` bounded smoke와 `DECISION-038`이 새 좁은 runner correction을 승인했다.
|
||||||
|
- correction result: required adjacent `--disable unified_exec` pair와 regression test가 GREEN이다.
|
||||||
|
- residual blocker: runner correction 자체 blocker는 없음. Full Python suite의 pre-existing `xhigh` actual 대 `extra high` expected mismatch는 변경하지 않았다.
|
||||||
|
- upstream ambiguity/reference artifact gap: 없음; reference artifact는 읽기/수정/생성하지 않았다.
|
||||||
|
- final stop: correction-owned edits와 검증이 끝났으므로 여기서 중단하고, phase rerun 판단과 실행은 Coordinator/Implementation Agent에 반환한다.
|
||||||
|
|
||||||
|
## 9. REWORK-004 TDD And Verification Evidence
|
||||||
|
|
||||||
|
### Failure and Minimal Correction
|
||||||
|
|
||||||
|
- classification: `harness`
|
||||||
|
- implementation defect: Codex `0.149.1`에서 통과한 runtime envelope의 `--disable unified_exec` option을 `scripts/execute.py`가 nested `codex exec`에 전달하지 않았다.
|
||||||
|
- RED test: `test_invoke_codex_uses_implementation_agent_command_contract`
|
||||||
|
- minimal GREEN: command vector에서 `"codex", "exec"` 바로 뒤에 `"--disable", "unified_exec"` 두 argument만 추가했다.
|
||||||
|
- preserved behavior: `workspace-write` default/validated override, `--dangerously-bypass-hook-trust`, `gpt-5.6-terra`, `model_reasoning_effort="xhigh"`, 1800-second structured timeout, no-push default, `danger-full-access` 비사용 정책은 변경하지 않았다.
|
||||||
|
|
||||||
|
### RED / GREEN / VERIFY
|
||||||
|
|
||||||
|
| stage | command | exit | duration | evidence tail |
|
||||||
|
| --- | --- | ---: | ---: | --- |
|
||||||
|
| RED | `uv run --with pytest python -m pytest -v -rs tests/test_execute.py::test_invoke_codex_uses_implementation_agent_command_contract` | `1` | 1.2초 | `assert ('--disable', 'unified_exec') in adjacent_arguments`; 1 failed |
|
||||||
|
| GREEN | same targeted command | `0` | 1.1초 | 1 passed |
|
||||||
|
| focused VERIFY | `uv run --with pytest python -m pytest -v -rs tests/test_execute.py` | `0` | 1.1초 | 10 passed |
|
||||||
|
| full Harness Python | `uv run --with pytest python -m pytest -v -rs` | `1` | 1.3초 | 23 passed, 1 pre-existing failure |
|
||||||
|
| MSVC Debug build | `cmake --build .harness/build --config Debug` | `0` | 3.8초 | solver/CLI/unit/integration/reference targets built |
|
||||||
|
| CTest discovery | `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | `0` | 0.7초 | 214 tests discovered |
|
||||||
|
| full CTest | `ctest --test-dir .harness/build -C Debug --output-on-failure` | `0` | 10.2초 | 214/214 passed |
|
||||||
|
|
||||||
|
Full Python failure는 기존 `test_agent_toml_and_limited_skill_yaml_schemas_are_parseable`의 `assert 'xhigh' == 'extra high'` 한 건이다. REWORK-004의 command-contract test를 포함한 `tests/test_execute.py`는 10/10 통과하며, dispatch 경계에 따라 pre-existing mismatch를 수정하지 않았다.
|
||||||
|
|
||||||
|
### REWORK-004 Traceability
|
||||||
|
|
||||||
|
| requirement id | task id | test id | corrected files | acceptance criterion |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `FESA-REQ-NSNR-083` | Harness runner correction `REWORK-004`; blocks Step 0 `cli-output-lease-and-derived-names` | `test_invoke_codex_uses_implementation_agent_command_contract` | `scripts/execute.py`; `tests/test_execute.py` | nested Codex argv가 adjacent `--disable`, `unified_exec`를 포함하면서 Terra/xhigh routing을 보존함; passed |
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,252 @@
|
|||||||
|
# Nonlinear Static Newton-Raphson Implementation Plan
|
||||||
|
|
||||||
|
> For Harness workers: this plan is an approved Stage 6 planning artifact. It authorizes planning files only. It does not authorize `scripts/execute.py`, C++ implementation, build, CTest, reference solver execution, or evidence-document creation.
|
||||||
|
|
||||||
|
**Goal:** `nonlinear-static-newton-raphson` 기능을 C++17/MSVC/CMake/CTest TDD 순서로 구현하고, 승인된 nonlinear MITC4 Newton-Raphson 절차, HDF5 schema v1, log lifecycle, shellNL/shell reference comparison을 검증한다.
|
||||||
|
|
||||||
|
**Architecture:** App layer가 argv 검증, lexical output path derivation, move-only `OutputWriteLease`, log open/close와 final HDF5 writer 호출 순서를 소유한다. 입력 parse/map은 정확히 한 번 수행하고, `StepDefinition::ProcedureKind()`로 linear와 nonlinear procedure executor를 분리한다. `LinearStaticAnalysis`의 기존 private lifecycle에는 nonlinear 조건문을 넣지 않고, 기존 linear numerical/HDF5 의미는 repository-wide output name/log lifecycle 변경만 제외하고 보존한다.
|
||||||
|
|
||||||
|
**Tech Stack:** C++17, MSVC on Windows, CMake, CTest, GoogleTest, Intel oneAPI MKL/TBB, HDF5, Abaqus `.inp` approved subset, Python 3 Harness scripts.
|
||||||
|
|
||||||
|
**Spec:** `docs/nonlinear-static-newton-raphson/{requirements,research,formulation,numerical-review,reference-model,io}.md`
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
| key | value |
|
||||||
|
| --- | --- |
|
||||||
|
| feature_id | `nonlinear-static-newton-raphson` |
|
||||||
|
| status | `approved-planning-files-materialized` |
|
||||||
|
| owner_agent | `implementation-planning-agent` |
|
||||||
|
| date | `2026-08-24` |
|
||||||
|
| approval | User approved the final 13-Step draft on `2026-08-24`; Coordinator recorded `DECISION-036`. |
|
||||||
|
| source_requirement | `docs/nonlinear-static-newton-raphson/requirements.md` |
|
||||||
|
| source_research | `docs/nonlinear-static-newton-raphson/research.md` |
|
||||||
|
| source_formulation | `docs/nonlinear-static-newton-raphson/formulation.md` |
|
||||||
|
| source_numerical_review | `docs/nonlinear-static-newton-raphson/numerical-review.md` |
|
||||||
|
| source_reference_models | `docs/nonlinear-static-newton-raphson/reference-model.md` |
|
||||||
|
| source_io_definition | `docs/nonlinear-static-newton-raphson/io.md` |
|
||||||
|
|
||||||
|
## Approved Upstream Hashes
|
||||||
|
|
||||||
|
| document | SHA-256 |
|
||||||
|
| --- | --- |
|
||||||
|
| `requirements.md` | `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2` |
|
||||||
|
| `research.md` | `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE` |
|
||||||
|
| `formulation.md` | `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0` |
|
||||||
|
| `numerical-review.md` | `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01` |
|
||||||
|
| `reference-model.md` | `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3` |
|
||||||
|
| `io.md` | `DBB959A68F17D67CA2B42569610B9C1B595A8BFB5502BC194B7E62B656031B28` |
|
||||||
|
|
||||||
|
## Readiness Check
|
||||||
|
|
||||||
|
- Upstream document status: Stage 1 requirements approved, Stage 2 research passed, Stage 3 formulation ready for numerical review and approved downstream, Stage 4 numerical/reference review passed for I/O definition, Stage 5 I/O definition approved.
|
||||||
|
- Missing decisions: none.
|
||||||
|
- Missing required comparison files: none for declared blocking/reference families.
|
||||||
|
- Planning can proceed: yes.
|
||||||
|
- `.harness/config.json`: absent during planning inspection. Each Step must recheck at execution time and use it first if it appears.
|
||||||
|
|
||||||
|
## Global Constraints
|
||||||
|
|
||||||
|
- Use `RED -> observed failure -> minimal GREEN -> focused VERIFY -> full CTest` in every implementation Step.
|
||||||
|
- C++ production edits require related C++ tests in the same Step.
|
||||||
|
- Do not edit requirements, research, formulation, numerical review, reference-model, I/O, tolerance, or reference artifacts.
|
||||||
|
- Do not run Abaqus, Nastran, or any reference solver.
|
||||||
|
- Do not create `implementation-report.md`, `build-test.md`, or `reference-comparison.md` before Step 12 produces actual command evidence.
|
||||||
|
- Do not run Harness from this planning approval. `scripts/execute.py` requires a separate explicit request.
|
||||||
|
- Implementation and Harness execution remain unauthorized by this materialized plan until the user separately requests Executor execution.
|
||||||
|
- Preserve source label/instance identity, deterministic row order, deterministic diagnostics, finite checks, and docs/TOLERANCE.md exactly.
|
||||||
|
- Preserve `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. For shellNL, preserve constrained `RF1/RF2`, `RF3`, physical spatial `RM1/RM2` blocking, and exclude `RM3` plus stress from numeric comparison.
|
||||||
|
|
||||||
|
## Repository Seam Map
|
||||||
|
|
||||||
|
| area | current seam | implementation direction |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| CLI/app | `src/fesa/app/fesa_application.cpp` currently accepts `[--output <results.h5>]` and constructs `LinearStaticAnalysis`. | Add output path derivation and `OutputWriteLease`, reject any argv token containing `--output`, own log/HDF5 lifecycle. |
|
||||||
|
| Analysis request | `include/fesa/analysis/analysis.h` contains `input_path` and `output_path`. | Add `log_path`; Step 10 introduces prepared analysis flow for single parse/map and delayed HDF5 finalization. |
|
||||||
|
| Linear lifecycle | `LinearStaticAnalysis::Run()` currently parses/maps and writes HDF5 inside `RecoverAndWrite()`. | Refactor into `PrepareAnalysisInput`, `LinearStaticProcedureExecutor`, and final writer call after log close; keep linear numerical behavior. |
|
||||||
|
| Domain | `StaticStepDefinition` in `include/fesa/model/model_types.h`; `StepDefinition` in `include/fesa/model/domain.h`. | Store procedure identity, `NLGEOM`, raw four `*STATIC` values and provenance. Do not store derived factor sequence or PRESELECT state. |
|
||||||
|
| Parser mapping | `src/fesa/io/abaqus/domain_mapping_context.cpp`, `step_definition_mapper.cpp`. | Accept nonlinear static subset, warning no-op PRESELECT, reject unsupported procedure fail-closed. |
|
||||||
|
| MITC4 | `include/fesa/elements/mitc4_shell.h`, `src/fesa/elements/mitc4_shell.cpp` are linear small-rotation. | Add separate nonlinear MITC4 files with `Create(...)` from four nodes, four initial frames, `ShellSection`, and `LinearElasticMaterial`; element kernels compute internal residual/tangent/recovery only. |
|
||||||
|
| Loads/control | Current loads are assembled for linear static RHS. | Step 5 owns global-once fixed CLOAD external vector `f_ext` and exact external load tangent `K_ext`, including projected moment `J_l`/map-Hessian terms, with no incident-element multiplication. Step 5 also owns exact convergence constants: relative `1.0e-2`, zero-scale `1.0e-3` with channel-specific units. Step 10 forms `r = f_int - f_ext` and `K_T = K_int - K_ext`. |
|
||||||
|
| Source identity | `SourceEntityId { instance_name, source_label, source_label_text }` and `EntityIndex` exist in `include/fesa/core/source_identity.h`; nodes are stored in stable Domain order. | Step 8 baseline uses both `EntityIndex` and full `SourceEntityId`, requires one node baseline per Domain node in stable internal order, rejects label-only or mismatched identities, and preserves identity into HDF5/reference mapping. |
|
||||||
|
| Solver | `MklPardisoSolver` uses SPD `mtype=2` and upper-triangle copy. | Preserve unchanged; add `TangentSolver` and MKL unsymmetric full CSR `mtype=11`. |
|
||||||
|
| Results writer | `ResultsWriter` is the backend-neutral linear writer; `Hdf5ResultsWriter` writes schema-v0 single-frame linear output. | Add `NonlinearResultsWriter` backend-neutral boundary and `NonlinearHdf5ResultsWriter` schema-v1 implementation with delayed finalization after log close. |
|
||||||
|
| Tests | `fesa_unit_tests`, `fesa_integration_tests`, `fesa_reference_tests` use executable-wide labels. | Add focused test sources and use `ctest -R` regex; do not globally relabel existing tests as nonlinear. |
|
||||||
|
|
||||||
|
## Work Breakdown
|
||||||
|
|
||||||
|
| Step | name | dependency | primary responsibility |
|
||||||
|
| ---: | --- | --- | --- |
|
||||||
|
| 0 | `cli-output-lease-and-derived-names` | none | CLI output derivation, `--output` substring rejection, RAII output lease, app-owned log/HDF5 lifecycle entry. |
|
||||||
|
| 1 | `nonlinear-static-domain-contract` | 0 | Domain/parser semantic contract for `NLGEOM=YES`, raw `*STATIC`, PRESELECT warning no-op. |
|
||||||
|
| 2 | `finite-rotation-state` | 1 | SO(3) finite rotation state, left Jacobian, branch/invariant validation. |
|
||||||
|
| 3 | `nonlinear-mitc4-kinematics-and-recovery` | 1,2 | TL MITC4 nonlinear kinematics and recovery rows. |
|
||||||
|
| 4 | `nonlinear-mitc4-residual-and-tangent` | 2,3 | Same-trial internal residual and internal consistent tangent with recovery. |
|
||||||
|
| 5 | `load-boundary-path-and-convergence-gates` | 1-4 | Fixed factor path, proportional load/BC path, global-once fixed-load `f_ext`/`K_ext` with approved subtraction signs, `rho_M`, typed four-channel convergence with constants owned by evaluator. |
|
||||||
|
| 6 | `backend-neutral-tangent-solver` | 4 | Separate nonsymmetric tangent solver boundary and MKL adapter. |
|
||||||
|
| 7 | `newton-iteration-log-writer` | 0,5 | Exact 39-field Newton text log writer. |
|
||||||
|
| 8 | `nonlinear-state-commit-rollback` | 3-7 | Factor-zero baseline construction with `EntityIndex` plus `SourceEntityId`, trial/committed nonlinear state, accepted frames, rollback/preservation. |
|
||||||
|
| 9 | `nonlinear-hdf5-schema-v1-writer` | 8 | Nonlinear HDF5 schema v1 writer using `std::vector<Diagnostic>`. |
|
||||||
|
| 10 | `prepared-analysis-flow-and-full-procedure` | 0-9 | Single parse/map prepared analysis flow, separate linear/nonlinear executors, delayed writer finalization. |
|
||||||
|
| 11 | `reference-comparison-gate` | 0-10 | shellNL nonlinear and shell linear real-input reference comparison. |
|
||||||
|
| 12 | `execution-closure-and-evidence-docs` | 0-11 | Fresh MSVC evidence, deterministic repeat/reference audit, actual-output evidence docs. |
|
||||||
|
|
||||||
|
## TDD Test Plan
|
||||||
|
|
||||||
|
| test id family | RED assertion scope | Step |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `NSNR-CLI-*` | `--output` substring first-token rejection, lexical result/log names, no-output-change proof, lease lifetime. | 0 |
|
||||||
|
| `NSNR-IO-*` | `NLGEOM=YES`, raw `*STATIC`, `NLGEOM=NO` regression, PRESELECT warning no-op, unsupported procedure diagnostics. | 1 |
|
||||||
|
| `NSNR-ROT-*` | finite rotation invariants, `J_l`, branch margin, director update. | 2 |
|
||||||
|
| `NSNR-ELEM-KIN-*` | nonlinear MITC4 creation inputs, TL shell kinematics, fixed-size four-GP recovery rows, degeneracy fail-closed, linear limit. | 3 |
|
||||||
|
| `NSNR-ELEM-TAN-*` | same-trial internal residual/tangent, directional derivative, objectivity, symmetry only for internal/no-external cases. | 4 |
|
||||||
|
| `NSNR-CTRL-*` | load factor path, absolute boundary path, global-once fixed loads and load tangent, moment admissibility, typed four convergence gates with `relative`/`zero-scale` branches and non-injectable exact thresholds/units. | 5 |
|
||||||
|
| `NSNR-SOLVER-*` | nonsymmetric tangent solve, 0x0, nonfinite/failure translation, SPD solver unchanged. | 6 |
|
||||||
|
| `NSNR-LOG-*` | serializer-owned 39-field UTF-8/LF/TAB Newton log from explicit stage/failure/channel records and fail-closed write/flush/close. | 7 |
|
||||||
|
| `NSNR-STATE-*` | factor-zero baseline creation with stable node order and full source identity, trial/committed separation, accepted frame order, full schema-v1 state inventory, finite atomic commit, rollback. | 8 |
|
||||||
|
| `NSNR-HDF5-*` | `NonlinearResultsWriter` boundary, schema v1 metadata/model/frame datasets, factor-zero metadata, atomic finalization. | 9 |
|
||||||
|
| `NSNR-PROC-*` | full procedure orchestration, single parse/map, log close before HDF5, deterministic repeat. | 10 |
|
||||||
|
| `NSNR-REF-*` | original artifact snapshot, temp input copy run, HDF5-to-original-CSV identity mapping, tolerance, classification, report data. | 11 |
|
||||||
|
| `NSNR-EVID-*` | fresh evidence docs and diff/hash/warning audits from actual command outputs. | 12 |
|
||||||
|
|
||||||
|
## CMake And CTest Plan
|
||||||
|
|
||||||
|
- Add C++ sources to `src/fesa/CMakeLists.txt` under existing `fesa_solver`.
|
||||||
|
- Add unit tests to `fesa_unit_tests`, integration tests to `fesa_integration_tests`, reference tests to `fesa_reference_tests`.
|
||||||
|
- Preserve current executable-wide labels. Use focused regex such as `ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure`.
|
||||||
|
- If scoped per-test labels are introduced, the Step that introduces the mechanism must test it and avoid changing labels for unrelated discovered tests.
|
||||||
|
- Configure/build/test commands:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow Contract
|
||||||
|
|
||||||
|
1. CLI receives `fesa.exe <model.inp>`.
|
||||||
|
2. App scans all argv tokens left-to-right. The first token containing case-sensitive substring `--output` fails with one `cli-usage` diagnostic before path resolution, parse/map, analysis, lease, log, or HDF5.
|
||||||
|
3. App derives `<stem>_results.h5` and `<stem>_log.txt` beside the lexically normalized user-addressed `.inp`.
|
||||||
|
4. App acquires move-only `OutputWriteLease` and retains it until all log and HDF5 work ends.
|
||||||
|
5. App opens/truncates the log, then `PrepareAnalysisInput(input_path)` parses/maps once into `Domain`.
|
||||||
|
6. Procedure executor receives injected `ParallelFor` plus `LinearSolver` or `TangentSolver` and computes a fully validated linear or nonlinear state without opening HDF5. Nonlinear assembly forms `r = f_int - f_ext` and `K_T = K_int - K_ext` from Step 4 internal quantities and Step 5 global-once external quantities. Nonlinear state construction preserves each node's stable `EntityIndex` and full `SourceEntityId`; source label alone is never a row identity.
|
||||||
|
7. App closes the log successfully before invoking injected `ResultsWriter` or `NonlinearResultsWriter`.
|
||||||
|
8. HDF5 is the authoritative solver output. CSV views are comparison/debug artifacts only.
|
||||||
|
|
||||||
|
## Reference Inventory
|
||||||
|
|
||||||
|
| path | role | rows | SHA-256 |
|
||||||
|
| --- | --- | ---: | --- |
|
||||||
|
| `reference/shellNL/shellNL.inp` | nonlinear input | input | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
|
||||||
|
| `reference/shellNL/shellNL displacements.csv` | required displacement CSV | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
|
||||||
|
| `reference/shellNL/shellNL reactions.csv` | required reaction CSV | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
|
||||||
|
| `reference/shellNL/shellNL stresses.csv` | nonblocking inventory artifact | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
|
||||||
|
| `reference/shell/shell.inp` | linear input | input | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
|
||||||
|
| `reference/shell/shell displacements.csv` | required displacement CSV | 49 | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
|
||||||
|
| `reference/shell/shell reactions.csv` | nonblocking inventory artifact | 49 | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
|
||||||
|
| `reference/shell/shell stresses.csv` | nonblocking inventory artifact | 288 | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
|
||||||
|
|
||||||
|
Blocking and warning families:
|
||||||
|
|
||||||
|
| family | components | rows | disposition |
|
||||||
|
| --- | --- | ---: | --- |
|
||||||
|
| `linear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | blocking |
|
||||||
|
| `linear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | warning-only |
|
||||||
|
| `nonlinear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | blocking |
|
||||||
|
| `nonlinear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | warning-only |
|
||||||
|
| `nonlinear.reaction_inplane_force` | `RF1,RF2`, constrained nodes | 48 | blocking |
|
||||||
|
| `nonlinear.reaction_transverse_force` | `RF3`, constrained nodes | 24 | blocking |
|
||||||
|
| `nonlinear.reaction_physical_moment` | `RM1,RM2`, constrained nodes | 48 | blocking |
|
||||||
|
|
||||||
|
Constrained node labels for shellNL reactions: `1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33`.
|
||||||
|
|
||||||
|
Exact shellNL `Frame`: `Increment 10: Step Time = 1.000`.
|
||||||
|
|
||||||
|
Step 11 must not run original reference input paths directly. It snapshots exact original artifact inventory, copies input bytes unchanged into a unique build-local temp case directory, runs `FesaApplication` on the copied `.inp`, consumes copied-sibling `_results.h5` and `_log.txt`, compares generated HDF5 to original read-only CSVs, and then verifies original reference directory inventory, bytes, timestamps, and hashes are unchanged. HDF5 source path identity matches the copied user-addressed input; source content identity matches the approved input hash.
|
||||||
|
|
||||||
|
## Acceptance Traceability Matrix
|
||||||
|
|
||||||
|
| requirement | Steps | test ids |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `FESA-REQ-NSNR-001` | 1,10 | `NSNR-IO-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-003` | 1,3,4,10 | `NSNR-IO-*`, `NSNR-ELEM-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-041` | 1,3,10 | `NSNR-IO-*`, `NSNR-ELEM-KIN-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-074` | 2,8,10 | `NSNR-ROT-*`, `NSNR-STATE-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-006` | 4,6,10 | `NSNR-ELEM-TAN-*`, `NSNR-SOLVER-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-007` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-069` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-070` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-008` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-014` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-046` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-048` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-018` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-063` | 5,10 | `NSNR-CTRL-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-016` | 1,5 | `NSNR-IO-*`, `NSNR-CTRL-*` |
|
||||||
|
| `FESA-REQ-NSNR-011` | 8,9,10 | `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-019` | 4,8,10 | `NSNR-ELEM-TAN-*`, `NSNR-STATE-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-020` | 1 | `NSNR-IO-*` |
|
||||||
|
| `FESA-REQ-NSNR-021` | 8,9,10 | `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-024` | 7,10 | `NSNR-LOG-*`, `NSNR-PROC-*` |
|
||||||
|
| `FESA-REQ-NSNR-083` | 0,10,12 | `NSNR-CLI-*`, `NSNR-PROC-*`, `NSNR-EVID-*` |
|
||||||
|
| `FESA-REQ-NSNR-026` | 8,10,11,12 | `NSNR-STATE-*`, `NSNR-PROC-*`, `NSNR-REF-*`, `NSNR-EVID-*` |
|
||||||
|
| `FESA-REQ-NSNR-030` | 2,3,4,5,6,7,8,9,10,11 | `NSNR-ROT-*`, `NSNR-ELEM-*`, `NSNR-CTRL-*`, `NSNR-SOLVER-*`, `NSNR-LOG-*`, `NSNR-STATE-*`, `NSNR-HDF5-*`, `NSNR-PROC-*`, `NSNR-REF-*` |
|
||||||
|
| `FESA-REQ-NSNR-034` | 11 | `NSNR-REF-*` |
|
||||||
|
|
||||||
|
## Numerical Review Coverage
|
||||||
|
|
||||||
|
| category | Steps |
|
||||||
|
| --- | --- |
|
||||||
|
| linear-limit reduction | 3,4,10,11 |
|
||||||
|
| rotation invariants and branch margin | 2,8,10 |
|
||||||
|
| tangent directional derivative schedule | 4 |
|
||||||
|
| no-moment tangent symmetry | 4 |
|
||||||
|
| finite rigid objectivity | 3,4 |
|
||||||
|
| patch/sign recovery | 3,4 |
|
||||||
|
| load/boundary path and `rho_M` | 5,10 |
|
||||||
|
| Newton factor/iteration lifecycle | 5,7,10 |
|
||||||
|
| four convergence gates | 5,7,10 |
|
||||||
|
| commit/rollback/determinism | 8,10,11,12 |
|
||||||
|
|
||||||
|
## Validation Commands
|
||||||
|
|
||||||
|
Each Step must:
|
||||||
|
|
||||||
|
1. Recheck `.harness/config.json`. If present, use the configured Harness build/test commands.
|
||||||
|
2. If absent, use:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Focused CTest commands are written explicitly in each `stepN.md`.
|
||||||
|
|
||||||
|
Harness Python validation is not in scope unless a Step changes Harness Python behavior, hook behavior, or agent configuration.
|
||||||
|
|
||||||
|
## Risks And Downstream Handoff
|
||||||
|
|
||||||
|
- Main implementation risk: current `LinearStaticAnalysis` owns parse/map and HDF5 write internally. Step 10 must refactor through prepared analysis flow so log close precedes HDF5 finalization for both linear and nonlinear runs.
|
||||||
|
- Main numerical risk: nonlinear MITC4 tangent and finite rotation derivatives must pass internal derivative/objectivity tests before reference comparison can be meaningful.
|
||||||
|
- Main backend risk: nonlinear tangent can be nonsymmetric. Preserve SPD `MklPardisoSolver` unchanged and add separate `TangentSolver`.
|
||||||
|
- Handoff to Implementation Agent through Coordinator: execute Steps 0..12 in order, one current Step at a time, with RED observed failure evidence before GREEN implementation, then focused/full CTest. Final reference gate is Step 11; evidence-document closure is Step 12.
|
||||||
|
|
||||||
|
## Open Issues
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## Plan Approval Boundary
|
||||||
|
|
||||||
|
The user-approved plan and pending phase files do not authorize Harness execution. `scripts/execute.py nonlinear-static-newton-raphson` requires a separate explicit user request.
|
||||||
@@ -0,0 +1,808 @@
|
|||||||
|
# Nonlinear Static Newton-Raphson I/O Definition
|
||||||
|
|
||||||
|
## 1. Metadata
|
||||||
|
|
||||||
|
- feature_id: `nonlinear-static-newton-raphson`
|
||||||
|
- source_requirement: `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- source_requirement_sha256: `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`
|
||||||
|
- source_research: `docs/nonlinear-static-newton-raphson/research.md`
|
||||||
|
- source_research_sha256: `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`
|
||||||
|
- source_formulation: `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- source_formulation_sha256: `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`
|
||||||
|
- source_numerical_review: `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- source_numerical_review_sha256: `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`
|
||||||
|
- source_reference_model: `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||||
|
- source_reference_model_sha256: `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`
|
||||||
|
- repository_policy: `AGENTS.md`, `docs/SOLVER_AGENT_DESIGN.md`, `docs/PRD.md`,
|
||||||
|
`docs/ARCHITECTURE.md`, `docs/ADR.md`, `docs/TOLERANCE.md`
|
||||||
|
- status: `ready-for-coordinator-review`
|
||||||
|
- owner_agent: `io-definition-agent`
|
||||||
|
- date: `2026-08-23`
|
||||||
|
- authoritative_output: input sibling `<stem>_results.h5`
|
||||||
|
- diagnostic_log: input sibling `<stem>_log.txt`
|
||||||
|
- hdf5_schema_version: `1`
|
||||||
|
|
||||||
|
이 문서는 승인된 Stage 5 I/O 계약만 정의한다. Parser, writer, comparison tool의
|
||||||
|
C++ API나 파일 소유권은 정의하지 않는다. FESA는 Abaqus와 독립적인 solver이며,
|
||||||
|
아래 `.inp` subset과 reference CSV mapping은 Abaqus full compatibility, Abaqus
|
||||||
|
`S4/S4R` 내부 알고리즘, 적분, stabilization, 상태 갱신 또는 output recovery
|
||||||
|
동등성을 주장하지 않는다.
|
||||||
|
|
||||||
|
FEM wiki 근거는 `Abaqus Input File Syntax`,
|
||||||
|
`Abaqus Output Database and Results Files`,
|
||||||
|
`Abaqus General and Linear Perturbation Steps`,
|
||||||
|
`Abaqus Initial and Boundary Conditions`,
|
||||||
|
`Abaqus Loads and Predefined Fields`,
|
||||||
|
`Abaqus Beam and Shell Section Definitions`를 사용했다. 이 근거는 keyword/data/comment
|
||||||
|
line, model/history data, output request, step/load/boundary/section 용어를 정렬하기
|
||||||
|
위한 보조 근거이며, 승인된 FESA 요구조건과 정식화가 우선한다.
|
||||||
|
|
||||||
|
## 2. Abaqus Input Scope
|
||||||
|
|
||||||
|
- input_format: Abaqus input file (`.inp`)
|
||||||
|
- supported Abaqus documentation source/version: 프로젝트 연구 bundle 및 local FEM
|
||||||
|
wiki에 보존된 Abaqus 2024 input syntax/output vocabulary. 저장된 nonlinear reference
|
||||||
|
input은 Abaqus/CAE Learning Edition 2024 생성물이다.
|
||||||
|
- supported_analysis: no-prior-history baseline에서 시작하는 정확히 하나의 source
|
||||||
|
`*STEP, NLGEOM=YES`와 하나의 nonlinear `*STATIC` procedure.
|
||||||
|
- internal_element_formulation: source `S4`와 `S4R` 모두 materially linear,
|
||||||
|
geometrically nonlinear Total Lagrangian `FESA-MITC4`에 매핑한다.
|
||||||
|
- ordinary_unit_system: 사용자가 일관되게 선택한 미지정 단위계. FESA는 단위 추론이나
|
||||||
|
변환을 수행하지 않는다.
|
||||||
|
- compatibility_disclaimer: 이 문서가 명시한 keyword 위치, parameter, data-line arity,
|
||||||
|
validation rule, output mapping만 지원 범위다.
|
||||||
|
|
||||||
|
`supported`는 syntax가 parsing되고 feature semantic model에 매핑된다는 뜻이다.
|
||||||
|
`unsupported`는 명확한 diagnostic으로 거부한다. `ignored-with-warning`은 syntax와
|
||||||
|
소속 data line을 소비하고 warning을 남기지만 Domain, AnalysisModel, nonlinear
|
||||||
|
procedure, mandatory HDF5 output 또는 reference comparison 의미를 바꾸지 않는다.
|
||||||
|
`requires-user-decision` 항목은 없다.
|
||||||
|
|
||||||
|
| keyword | policy | allowed location | required parameters and data grammar | semantic mapping | unsupported behavior |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| `*HEADING` | supported | optional top-level first keyword | parameter 없음; 다음 keyword 전까지 text row 0개 이상 | raw heading을 source metadata로 보존 | parameter, nested location, 두 번째 heading은 input error |
|
||||||
|
| `*INCLUDE` | unsupported | anywhere | 허용 data/parameter grammar 없음 | file traversal 또는 include expansion 없음 | `unsupported-keyword`; 참조 파일을 열지 않음 |
|
||||||
|
| `*PART` / `*END PART` | supported | top-level model block | `NAME=<part-name>` 필수; `*END PART` data 없음 | part-local node, element, set, shell section scope | unclosed, nested, duplicate, data-bearing close는 input error |
|
||||||
|
| `*NODE` | supported | part scope | 각 row `node_label,x,y,z`; parameter 없음 | 양의 source node label과 finite global Cartesian coordinate | arity 오류, duplicate label, nonfinite value, dangling later reference는 input/model error |
|
||||||
|
| `*NSET` | supported | part 또는 assembly scope | `NSET=<name>` 필수; optional `GENERATE`; assembly scope는 `INSTANCE=<name>` 필수; explicit labels 또는 `first,last,increment` | deterministic node-set membership | mixed-instance set, invalid generate row, duplicate set name, empty set, dangling member는 input error |
|
||||||
|
| `*ELEMENT` | supported | part scope | `TYPE=S4` 또는 `TYPE=S4R`; 각 row `element_label,n1,n2,n3,n4` | four-node source shell connectivity; source type 보존; internal type `FESA-MITC4` | 다른 element type은 `unsupported-element-formulation`; repeated node, arity 오류, dangling node, mixed element model은 error |
|
||||||
|
| `*ELSET` | supported | part 또는 assembly scope | `ELSET=<name>` 필수; optional `GENERATE`; assembly scope는 `INSTANCE=<name>` 필수; `*NSET`과 같은 row rule | deterministic element-set membership | mixed-instance set, invalid generate row, duplicate set name, empty set, dangling member는 input error |
|
||||||
|
| `*MATERIAL` | supported | top-level model data | `NAME=<material-name>` 필수; data 없음 | 정확히 하나의 supported isotropic `*ELASTIC` 소유 | duplicate material, missing/duplicate elasticity, 다른 material behavior는 input error |
|
||||||
|
| `*ELASTIC` | supported | current `*MATERIAL` scope | 정확히 한 row `E,nu`; parameter 없음 | homogeneous isotropic linear elasticity; `G=E/(2(1+nu))` 파생 | extra field/row, dependency/temperature data, nonfinite value, `E<=0`, `nu<=-1`, `nu>=0.5`는 error |
|
||||||
|
| `*SHELL SECTION` | supported | part scope | `ELSET=<name>`와 `MATERIAL=<name>` 필수; 정확히 한 row `thickness[,integration_points]` | centered homogeneous single-layer shell section | composite/layer data, offset, orientation, controls, variable thickness, missing reference, conflicting assignment, nonpositive thickness는 error |
|
||||||
|
| `*ASSEMBLY` / `*END ASSEMBLY` | supported | 정확히 하나의 top-level assembly | `NAME=<assembly-name>` 필수; `*END ASSEMBLY` data 없음 | identity-instance scope와 assembly-level set scope | nested/duplicate assembly, instance transform data, unmatched close는 input error |
|
||||||
|
| `*INSTANCE` / `*END INSTANCE` | supported | assembly scope | `NAME=<instance-name>`, `PART=<part-name>` 필수; transform data 없음 | named identity copy; 같은 part의 multiple identity instances 허용 | duplicate/dangling instance 또는 translation/rotation data는 unsupported input |
|
||||||
|
| `*BOUNDARY` | supported | top-level model data 또는 sole step의 `*STATIC` 뒤 | parameter 없음; 각 row `target,first_dof,last_dof[,value]`; omitted value는 exact zero | common load-factor path의 factor-one absolute global DOF target; DOF `1..6` | amplitude, local coordinate system, invalid range/arity, unresolved target, nonfinite value, conflicting expanded value는 error |
|
||||||
|
| `*CLOAD` | supported | sole step의 `*STATIC` 뒤 | parameter 없음; 각 row `target,dof,magnitude`; DOF `1..6` | load factor로만 scale되는 fixed-global dead nodal force/moment source | amplitude/follower/local load, invalid arity/DOF, unresolved target, nonfinite magnitude, drilling-direction aggregate moment는 error |
|
||||||
|
| `*DLOAD` | unsupported | anywhere | 허용 data/parameter grammar 없음 | distributed/body/pressure/edge/follower load object를 만들지 않음 | load-like usage는 `unsupported-distributed-load`; 그 외는 `unsupported-keyword` |
|
||||||
|
| `*STEP` / `*END STEP` | supported for nonlinear selector | 정확히 하나의 top-level history block | optional `NAME`; `NLGEOM=YES` 필수; `*END STEP` data 없음 | canonical nonlinear step identity `Step-1` | zero/multiple/mixed/unclosed/nested step 또는 non-`YES` nonlinear selector는 nonlinear increment 전 실패 |
|
||||||
|
| `*STATIC` | supported nonlinear procedure | sole step의 첫 procedure keyword | 정확히 한 row `initial_increment,time_period,minimum_increment,maximum_increment`; 네 값 모두 finite positive; `time_period`는 endpoint `1.0` identity | 첫 값은 fixed increment `h`; 세 번째/네 번째 값은 unused compatibility source; factors는 one 미만 ordinal multiple 뒤 exact factor one | missing/extra rows/fields, nonpositive/nonfinite field, endpoint가 `1.0`이 아니면 `invalid-nonlinear-static-data` |
|
||||||
|
| `*OUTPUT` | ignored-with-warning | sole step의 `*STATIC` 뒤 | 정확히 `FIELD, VARIABLE=PRESELECT` 또는 `HISTORY, VARIABLE=PRESELECT`; `FIELD`/`HISTORY`는 value 없는 flag이고 둘 중 하나만 필요; `VARIABLE`은 정확히 한 번 필요; duplicate, both flags, missing `VARIABLE`, 다른 value, extra parameter는 input error | stored reference의 `*Output, field, variable=PRESELECT`와 `*Output, history, variable=PRESELECT`를 warning no-op으로 수용; FESA mandatory output을 select/suppress할 수 없음 | output request는 FESA output을 바꾸지 않음; malformed parameter set은 `invalid-keyword-parameter` |
|
||||||
|
| `*NODE OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 variable data를 소비 | legacy nodal request `U`, `RF` 등을 수용 | HDF5 selection, history output, empty synthetic dataset을 만들지 않음 |
|
||||||
|
| `*ELEMENT OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 variable data를 소비 | legacy element request `S` 등을 수용 | extrapolated stress, averaging, comparison projection을 만들지 않음 |
|
||||||
|
| `*PREPRINT` | ignored-with-warning | top-level | parameter를 보존 후 무시; data 불필요 | generator control syntax 수용 | semantic object 없음 |
|
||||||
|
| `*RESTART` | ignored-with-warning | sole step | parameter를 보존 후 무시; restart state/data 없음 | legacy restart request syntax 수용 | restart write/read/continue 없음 |
|
||||||
|
| `*CONTACT OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 data를 소비 | legacy contact-output request syntax만 수용 | contact model/output 없음 |
|
||||||
|
|
||||||
|
`*ORIENTATION`, `*TRANSFORM`, amplitudes, follower loads, pressure, gravity, body
|
||||||
|
force, edge load, `*DLOAD`, composite shell definitions, shell section offsets,
|
||||||
|
material nonlinearity, density, temperature dependency, contact, MPC, penalty, multiple
|
||||||
|
steps, restarts, submodels, transforms, nested assemblies와 위 표에 없는 모든
|
||||||
|
model-affecting keyword는 fail-closed unsupported input이다. 저장 또는 future linear
|
||||||
|
shell input의 `NLGEOM=NO`는 `docs/linear-static-mitc4-shell/io.md`가 계속 관할한다.
|
||||||
|
이 feature bundle에서 해당 linear case는 `shell-s4-linear-limit` regression reference일
|
||||||
|
뿐 nonlinear response evidence가 아니다.
|
||||||
|
|
||||||
|
## 3. Syntax Policy
|
||||||
|
|
||||||
|
- Keyword line은 optional leading whitespace 뒤 `*`로 시작한다. Comment line은 `**`로
|
||||||
|
시작하며 semantic effect가 없다.
|
||||||
|
- Keyword name, parameter name, supported enumerated value, named-reference lookup은
|
||||||
|
ASCII case-insensitive다. Raw source spelling은 diagnostic/report display용으로
|
||||||
|
보존한다.
|
||||||
|
- Data line과 keyword parameter field는 comma-separated다. 주변 whitespace는 parsing
|
||||||
|
전에 trim한다. 필수 field가 비어 있거나, 허용되지 않은 trailing field가 있거나,
|
||||||
|
numeric token이 malformed이면 input error다.
|
||||||
|
- 승인된 empty data-field 의미는 `*BOUNDARY` 네 번째 value 생략뿐이며 exact zero로
|
||||||
|
매핑한다. `*SHELL SECTION`의 optional second field는 생략 가능하고, 존재하면 positive
|
||||||
|
base-10 integer여야 한다.
|
||||||
|
- Continuation line, physical-line continuation, multiline name, quoted case-sensitive
|
||||||
|
name, parameter substitution, include file은 unsupported다. 각 logical keyword/data row는
|
||||||
|
한 physical line에 완결되어야 한다.
|
||||||
|
- 이 feature는 public numeric Abaqus line-length compatibility limit를 정의하지 않는다.
|
||||||
|
승인 input은 single-line ASCII record이며, 읽을 수 없는 physical line은 implicit
|
||||||
|
continuation 없이 parsing 실패다.
|
||||||
|
- Keyword, parameter, set/material/part/instance name, numeric label의 input text는
|
||||||
|
ASCII로 취급한다. HDF5 string output은 UTF-8이지만 non-ASCII source label/name은
|
||||||
|
이 feature 계약 밖이다.
|
||||||
|
- Node label, element label, explicit set member는 positive base-10 integer다. Source
|
||||||
|
label은 text와 numeric identity로 보존한다. Stable internal index는 diagnostic 또는
|
||||||
|
comparison row에서 source identity를 대체할 수 없다.
|
||||||
|
- 모든 real-valued input은 finite `double`로 parse되어야 한다. `NaN`, `Inf`, overflow,
|
||||||
|
nonfinite underflow, locale-dependent numeric format은 reject한다.
|
||||||
|
- Model data와 history data는 개념적으로 분리한다. Mesh, set, material, section,
|
||||||
|
coordinate, initial shell frame은 model data다. Step, procedure, boundary, load,
|
||||||
|
output request는 history data다.
|
||||||
|
- 어떤 keyword에도 속하지 않는 standalone data 또는 active keyword block 밖의 data는
|
||||||
|
input error다. Output-request variable data는 allowlisted output keyword에 종속될 때만
|
||||||
|
no-op으로 소비한다.
|
||||||
|
- 모든 parsed keyword, parameter, data row, semantic entity는 normalized file path,
|
||||||
|
1-based line, raw keyword spelling, source identity까지 추적 가능해야 한다.
|
||||||
|
|
||||||
|
## 4. Model Data Mapping
|
||||||
|
|
||||||
|
### 4.1 Stable Source Identity and Ordering
|
||||||
|
|
||||||
|
Identity-instance expansion 뒤 source node와 source element의 stable identity는 다음과
|
||||||
|
같다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
SourceEntityId { instance_name, source_label }
|
||||||
|
```
|
||||||
|
|
||||||
|
Name lookup은 case-insensitive지만 raw spelling은 보존한다. Stable internal ID는 input
|
||||||
|
part declaration order, instance declaration order, part-local entity declaration order로
|
||||||
|
부여한다. Hash iteration, thread scheduling, set spelling, CSV row order는 source identity,
|
||||||
|
internal row order, diagnostic order 또는 result row order를 바꾸면 안 된다.
|
||||||
|
|
||||||
|
### 4.2 Nodes, Elements and Sets
|
||||||
|
|
||||||
|
- `*NODE`는 finite global Cartesian initial midsurface coordinate `[X,Y,Z]`로 매핑하며
|
||||||
|
unit dimension은 `length`다.
|
||||||
|
- `*ELEMENT, TYPE=S4/S4R`는 ordered four-node shell connectivity `[1,2,3,4]`로 매핑한다.
|
||||||
|
Natural corner 순서는 `(-1,-1)`, `(+1,-1)`, `(+1,+1)`, `(-1,+1)`이며 connectivity를
|
||||||
|
조용히 reverse하지 않는다.
|
||||||
|
- Source type `S4` 또는 `S4R`는 metadata로 보존한다. 두 type 모두 같은 internal
|
||||||
|
`FESA-MITC4` formulation, `2 x 2 x 2` integration, nonlinear state path를 선택한다.
|
||||||
|
Source `S4R`는 reduced integration, hourglass control 또는 Abaqus `S4R` internal
|
||||||
|
behavior를 활성화하지 않는다.
|
||||||
|
- `*NSET`과 `*ELSET`은 explicit row order를 보존한다. `GENERATE`는 inclusive
|
||||||
|
`first,last,increment` 순서로 expand한다. Assembly-scope set은 하나의 `INSTANCE`만
|
||||||
|
참조할 수 있고 mixed instance는 허용하지 않는다.
|
||||||
|
- Set membership은 Domain commit 전에 source identity로 resolve한다. 같은 scope의
|
||||||
|
duplicate set definition, dangling member, invalid generate range는 analysis 전 실패한다.
|
||||||
|
|
||||||
|
### 4.3 Material, Section, Coordinates and Units
|
||||||
|
|
||||||
|
- `*MATERIAL`과 `*ELASTIC`은 finite `E>0`, `-1<nu<0.5`를 갖는 homogeneous isotropic
|
||||||
|
materially linear material 하나로 매핑한다.
|
||||||
|
- `*SHELL SECTION`은 하나의 element set을 resolved material과 positive finite
|
||||||
|
`thickness>0`를 갖는 centered homogeneous shell layer로 매핑한다. Optional source
|
||||||
|
integration-point 값은 syntax compatibility로만 보존하며 quadrature, recovery, output,
|
||||||
|
reference comparison에 영향을 주지 않는다.
|
||||||
|
- Initial nodal director와 right-handed triad는 instance expansion 뒤 승인된 linear MITC4
|
||||||
|
deterministic incident-element rule로 파생한다. 이 값들은 model data이며 모든 increment의
|
||||||
|
fixed initial reference를 정의한다.
|
||||||
|
- 필수 geometry check는 finite coordinate, valid four-node topology, 모든 Gauss/tying/
|
||||||
|
center/recovery location의 positive reference Jacobian, non-opposed incident normals,
|
||||||
|
valid reciprocal bases, valid initial frames를 포함한다.
|
||||||
|
- `.inp` 단위는 user-consistent unspecified다. HDF5는 `length`, `force`, `force*length`,
|
||||||
|
`force/length`, `force/length^2`, `1` 같은 unit dimension string만 기록하고 SI를 쓰거나
|
||||||
|
추론하지 않는다.
|
||||||
|
|
||||||
|
## 5. History Data Mapping
|
||||||
|
|
||||||
|
### 5.1 Step and Procedure
|
||||||
|
|
||||||
|
Nonlinear procedure는 정확히 하나의 source step이 `*STEP, NLGEOM=YES`를 포함하고 그
|
||||||
|
안에 정확히 하나의 supported `*STATIC` data row가 있을 때만 선택한다. Semantic step
|
||||||
|
name은 canonical `Step-1`이다. Raw source step name은 provenance로만 보존한다.
|
||||||
|
|
||||||
|
Nonlinear `*STATIC` data row의 의미는 다음과 같다.
|
||||||
|
|
||||||
|
- `initial_increment`는 fixed positive load-factor increment `h`다.
|
||||||
|
- `time_period`는 endpoint `1.0`과 정확히 같은 identity여야 한다.
|
||||||
|
- `minimum_increment`와 `maximum_increment`는 positive finite source value여야 하지만
|
||||||
|
cutback, growth, retry, stopping, convergence, output cadence에는 사용하지 않는다.
|
||||||
|
- Intended factor identity는 `1.0`보다 작은 ordinal `j*h` 값들을 만든 뒤, 마지막에 exact
|
||||||
|
assigned factor `1.0` 하나를 붙여 만든다. Cumulative `lambda += h`, tolerance-based
|
||||||
|
duplicate endpoint detection, growth, cutback, retry는 금지한다.
|
||||||
|
- `reference/shellNL/shellNL.inp`의 성공 run에서 expected intended/accepted factor sequence는
|
||||||
|
`0.1,0.2,...,1.0`이다.
|
||||||
|
|
||||||
|
Factor zero는 no-prior-history step-start committed baseline이다. Accepted frame은 committed
|
||||||
|
increment와 일대일 대응해야 하므로 factor zero는 accepted HDF5 frame이 아니다. Factor zero는
|
||||||
|
다음 metadata/model dataset으로만 projection한다.
|
||||||
|
|
||||||
|
- `factor_zero_is_frame=0`
|
||||||
|
- `factor_zero_load_factor=0.0`
|
||||||
|
- `/model/prescribed_displacement_start`와 initial state의 step-start displacement 및
|
||||||
|
rotation-vector component
|
||||||
|
- `/model/shell/nodal_frame`과 `/model/shell/nodal_director`의 step-start triad/director
|
||||||
|
- zero scaled `*CLOAD` contribution과 step-start boundary value
|
||||||
|
|
||||||
|
### 5.2 Boundary Conditions
|
||||||
|
|
||||||
|
`*BOUNDARY` target resolution은 direct node label 또는 node set을 허용한다. Expanded row는
|
||||||
|
stable source-node identity와 DOF order `1..6`를 사용한다.
|
||||||
|
|
||||||
|
| DOF | component | unit dimension | nonlinear path meaning |
|
||||||
|
| ---: | --- | --- | --- |
|
||||||
|
| 1 | `UX` / CSV `U1` | length | factor-one absolute global displacement target |
|
||||||
|
| 2 | `UY` / CSV `U2` | length | factor-one absolute global displacement target |
|
||||||
|
| 3 | `UZ` / CSV `U3` | length | factor-one absolute global displacement target |
|
||||||
|
| 4 | `URX` / CSV `UR1` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target |
|
||||||
|
| 5 | `URY` / CSV `UR2` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target |
|
||||||
|
| 6 | `URZ` / CSV `UR3` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target |
|
||||||
|
|
||||||
|
Step 앞 row와 sole step 내부 row는 모두 같은 semantic step의 factor-one target으로 매핑한다.
|
||||||
|
Cross-step propagation은 없다. Load factor `lambda`에서 current constrained value는
|
||||||
|
`q_start + lambda * (q_target - q_start)`다. Current release에는 prior history가 없으므로
|
||||||
|
ordinary start value는 승인된 start-state dataset에 명시된 값을 제외하고 zero다.
|
||||||
|
Constrained Newton correction component는 exact zero다.
|
||||||
|
|
||||||
|
### 5.3 Concentrated Loads
|
||||||
|
|
||||||
|
`*CLOAD` target resolution은 boundary와 같다. 같은 node/DOF로 resolve되는 여러 row는 source
|
||||||
|
order로 factor-one global load coefficient에 누적한다. Factor `lambda`에서 magnitude는
|
||||||
|
`lambda`만 곱한다.
|
||||||
|
|
||||||
|
| DOF | source component | unit dimension | nonlinear meaning |
|
||||||
|
| ---: | --- | --- | --- |
|
||||||
|
| 1 | `F1` | force | fixed-global dead nodal force |
|
||||||
|
| 2 | `F2` | force | fixed-global dead nodal force |
|
||||||
|
| 3 | `F3` | force | fixed-global dead nodal force |
|
||||||
|
| 4 | `M1` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work |
|
||||||
|
| 5 | `M2` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work |
|
||||||
|
| 6 | `M3` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work |
|
||||||
|
|
||||||
|
Nonzero aggregated nodal moment `M_src`마다 preprocessing과 모든 entered trial state에서
|
||||||
|
`abs(dot(d,M_src))/norm(M_src) <= 1e-12`를 denominator clamping 없이 만족해야 한다.
|
||||||
|
실패하면 `unsupported-drilling-load`다. Source moment vector는 fixed global coordinate에
|
||||||
|
남으며 FESA는 rejected moment component를 회전, 축소, 변형하거나 numerical drilling channel로
|
||||||
|
보내지 않는다.
|
||||||
|
|
||||||
|
### 5.4 Output Requests
|
||||||
|
|
||||||
|
Abaqus output request keyword는 `ignored-with-warning` compatibility syntax로만 수용한다.
|
||||||
|
이 keyword들은 history output을 켜지 않고, frame cadence를 제어하지 않으며, mandatory FESA
|
||||||
|
HDF5 dataset을 select, suppress, rename할 수 없다. Trial Newton state는 HDF5 field/history
|
||||||
|
output이 아니다. Per-iteration evidence는 `<stem>_log.txt`에 diagnostic text로만 기록한다.
|
||||||
|
|
||||||
|
## 6. Internal Model Contract
|
||||||
|
|
||||||
|
이 section은 semantic field를 정의하며 C++ API를 정의하지 않는다.
|
||||||
|
|
||||||
|
- Node record: stable internal node ID, `SourceEntityId`, finite global coordinate,
|
||||||
|
initial director, initial right-handed triad, source location.
|
||||||
|
- Element record: stable internal element ID, `SourceEntityId`, preserved source type
|
||||||
|
`S4` 또는 `S4R`, internal formulation `FESA-MITC4`, ordered four-node connectivity,
|
||||||
|
resolved section/material identity, source location.
|
||||||
|
- Set record: case-insensitive set name, source scope, optional source instance,
|
||||||
|
deterministic expanded source members, stable internal member IDs.
|
||||||
|
- Material record: case-insensitive material name, finite `E`, finite `nu`, derived `G`,
|
||||||
|
source location, homogeneous isotropic materially linear identity.
|
||||||
|
- Section record: source `ELSET`, resolved material, positive thickness, optional ignored
|
||||||
|
source integration-point field, centered single-layer identity.
|
||||||
|
- Boundary record: source target, expanded node identities, DOF range, finite factor-one
|
||||||
|
absolute target values, step-start values, source location, conflict status.
|
||||||
|
- Load record: source target, expanded node identities, DOF, finite factor-one source
|
||||||
|
magnitude, deterministic aggregate value, dead fixed-global load identity.
|
||||||
|
- Step record: raw source name, canonical `Step-1`, `NLGEOM=YES` nonlinear procedure
|
||||||
|
identity, fixed increment `h`, endpoint `1.0`, unused third/fourth `*STATIC` values,
|
||||||
|
intended factor sequence, output-request no-op inventory.
|
||||||
|
- State contract: committed state와 trial state는 alias될 수 없다. 완전하게 수렴한
|
||||||
|
candidate만 displacement, rotation vector, `Q`, director, load factor, frame identity,
|
||||||
|
internal/external force, residual/reaction, physical recovery row를 commit한다. Failed
|
||||||
|
trial, nonconvergence, nonfinite data, solve failure, recovery failure 또는 output failure는
|
||||||
|
prior committed state와 prior authoritative final result를 보존한다.
|
||||||
|
- Output request record: keyword, parameter, variable row, source location은 warning
|
||||||
|
diagnostic용으로만 보존한다. Solver 또는 HDF5 selection effect는 없다.
|
||||||
|
|
||||||
|
Source identity와 internal index identity는 diagnostics, HDF5 row order, reference
|
||||||
|
comparison 전체에서 구분해야 한다. CSV의 element-label order는 solver identity가 아니며
|
||||||
|
`(instance, source_label)` key를 대체하지 않는다.
|
||||||
|
|
||||||
|
## 7. Output HDF5 Schema
|
||||||
|
|
||||||
|
### 7.1 Public Output Names, Log and Lifecycle
|
||||||
|
|
||||||
|
승인된 public CLI shape는 다음 하나뿐이다.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
fesa.exe <model.inp>
|
||||||
|
```
|
||||||
|
|
||||||
|
CLI는 input path 해석보다 먼저 argv token을 왼쪽에서 오른쪽으로 scan한다. 어떤 token이든
|
||||||
|
case-sensitive exact literal substring `--output`을 포함하면, `--output`, `--output=...`,
|
||||||
|
`--output-path`, prefix/suffix form을 모두 포함해 usage failure다. 이 failure는 input path
|
||||||
|
resolution, parsing, Analysis construction, derived-result path ownership, HDF5 candidate,
|
||||||
|
log creation/truncation, output finalization 전 exit code `2`로 끝난다. Stderr에는 ordered
|
||||||
|
diagnostic 하나만 쓴다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
severity=error code=cli-usage argument_index=<uint64> argument=<escaped argv token> message=literal --output is not supported
|
||||||
|
```
|
||||||
|
|
||||||
|
여러 token이 `--output`을 포함해도 첫 matching token만 보고 위 diagnostic 하나만 낸다.
|
||||||
|
Literal `--output`에 대한 compatibility alias나 deprecation window는 없다. `--output`을
|
||||||
|
포함하지 않는 다른 unknown option은 별도 `unrecognized-option` usage diagnostic을 유지할 수
|
||||||
|
있다.
|
||||||
|
|
||||||
|
Input/output lexical identity는 다음 순서로 정의한다.
|
||||||
|
|
||||||
|
1. 단일 input path token이 relative path이면 invocation CWD를 lexical base로 붙인다.
|
||||||
|
2. `.`와 `..` component만 lexically normalize한다. Symlink, junction, short-name,
|
||||||
|
case-preserving target path는 resolve하지 않는다.
|
||||||
|
3. Normalized user-addressed final filename의 마지막 extension이 case-insensitive `.inp`가
|
||||||
|
아니면 input usage failure다.
|
||||||
|
4. `<stem>`은 마지막 extension 하나만 제거한 basename이다. 앞선 dot과 basename case는
|
||||||
|
보존한다. 예: `Beam.Model.INP` -> `Beam.Model_results.h5`,
|
||||||
|
`Beam.Model_log.txt`.
|
||||||
|
5. Derived outputs는 normalized user-addressed input path의 sibling이다.
|
||||||
|
|
||||||
|
- result final: `<input-directory>/<stem>_results.h5`
|
||||||
|
- log final/live file: `<input-directory>/<stem>_log.txt`
|
||||||
|
|
||||||
|
File-vs-directory collision과 same-derived-pair concurrency는 output ownership 문제다.
|
||||||
|
`<stem>_log.txt`가 directory 또는 truncate 불가능한 non-regular path이면 log create/open/
|
||||||
|
truncate failure다. `<stem>_results.h5`가 directory이면 HDF5 output collision으로 fail-closed
|
||||||
|
한다. 같은 derived pair를 목표로 하는 concurrent invocation은 same-directory
|
||||||
|
implementation-private lock을 nonblocking exclusive ownership으로 먼저 획득해야 한다. Lock
|
||||||
|
획득 실패 또는 lock path의 directory collision은 exit code `6`의 output-busy failure이며
|
||||||
|
best-effort fatal stderr diagnostic 하나를 시도하고 log/HDF5를 변경하지 않는다. Lock holder
|
||||||
|
하나만 log truncate, HDF5 candidate, final replace를 시도한다. Candidate filename은
|
||||||
|
public contract가 아니지만 반드시 same-directory,
|
||||||
|
implementation-private, exclusive-create collision-safe여야 하며 실패한 candidate는
|
||||||
|
authoritative output이 아니다.
|
||||||
|
|
||||||
|
HDF5 result lifecycle과 log lifecycle은 의도적으로 비대칭이다.
|
||||||
|
|
||||||
|
- `<stem>_log.txt`는 CLI usage validation, lexical output derivation, single-writer lock
|
||||||
|
획득 뒤 replace/truncate된다. Create/open/truncate failure는 Analysis 전 exit code `6`으로
|
||||||
|
abort하며, best-effort fatal stderr diagnostic 하나를 시도한다.
|
||||||
|
- Log write/flush failure는 즉시 abort한다. Solver는 retry, fallback, continue 또는 result
|
||||||
|
commit을 하지 않는다. Prior authoritative HDF5는 보존하고, 이미 flush된 live-log prefix는
|
||||||
|
rollback하지 않는다. Failed write 뒤 남은 partial trailing line은 authoritative iteration
|
||||||
|
record가 아니며 tooling은 LF-terminated complete record만 parsing한다.
|
||||||
|
- Log close는 successful analysis/recovery 뒤, 그리고 HDF5 candidate open/write/final replace
|
||||||
|
전 수행한다. Close failure는 result commit을 block하고 exit code `6`으로 끝낸다.
|
||||||
|
- `<stem>_results.h5`는 sibling candidate가 완전히 write, flush, close, reopen, schema-check된
|
||||||
|
뒤 atomic move/replace에 성공한 경우에만 authoritative다.
|
||||||
|
- HDF5 failure는 exit code `6`을 반환하고 가능한 경우 prior valid final을 보존하며 current-run
|
||||||
|
log를 rollback하지 않는다. HDF5 failure는 log close 성공 뒤 발생하므로 current log는 닫힌
|
||||||
|
current-run audit으로 남는다.
|
||||||
|
|
||||||
|
Newton iteration log는 UTF-8 no BOM, LF-terminated text file이다. Header, trailer, BOM, CRLF는
|
||||||
|
없다. Entered Newton iteration마다 physical line 하나만 기록하고, 각 line은 fixed field order의
|
||||||
|
TAB-separated `label=value` record다. Per-iteration stderr duplication은 정확히 0개다. 각
|
||||||
|
iteration record는 다음 iteration 진입 전 또는 return 전 flush되어야 한다.
|
||||||
|
|
||||||
|
Non-Newton procedure 또는 Newton iteration에 진입하기 전 끝난 controlled failure는 iteration
|
||||||
|
record를 fabricate하지 않는다. 같은 open/truncate/failure lifecycle을 적용하되 successful
|
||||||
|
non-Newton run의 `<stem>_log.txt` content는 zero-byte empty file이다. Pre-Newton controlled
|
||||||
|
failure도 entered iteration이 없으면 iteration record가 없는 log file만 남긴다.
|
||||||
|
|
||||||
|
고정 field order는 다음과 같다.
|
||||||
|
|
||||||
|
| order | label | value contract |
|
||||||
|
| ---: | --- | --- |
|
||||||
|
| 1 | `record` | literal `newton-iteration` |
|
||||||
|
| 2 | `schema` | literal `nsnr-log-v1` |
|
||||||
|
| 3 | `increment` | entered increment identity, `uint64` |
|
||||||
|
| 4 | `target_factor` | finite round-trip numeric load factor |
|
||||||
|
| 5 | `iteration` | entered Newton iteration identity `1..100` |
|
||||||
|
| 6 | `last_completed_stage` | enum stage completed before outcome; `none` allowed |
|
||||||
|
| 7 | `failing_stage` | `none` for completed gate records, otherwise failing stage enum |
|
||||||
|
| 8 | `residual_force_channel` | literal `residual_force` or `not-evaluated(reason)` |
|
||||||
|
| 9 | `residual_force_numerator_norm` | `||r_f^u||_inf` or `not-evaluated(reason)` |
|
||||||
|
| 10 | `residual_force_denominator_scale` | `max(||f_int,f^u||_inf,||f_ext,f^u||_inf)` or `not-evaluated(reason)` |
|
||||||
|
| 11 | `residual_force_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 12 | `residual_force_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 13 | `residual_force_threshold_unit` | `1`, `force`, or `not-evaluated(reason)` |
|
||||||
|
| 14 | `residual_force_pass` | `0`, `1`, or `not-evaluated(reason)` |
|
||||||
|
| 15 | `residual_moment_channel` | literal `residual_moment` or `not-evaluated(reason)` |
|
||||||
|
| 16 | `residual_moment_numerator_norm` | `||r_f^phi||_inf` or `not-evaluated(reason)` |
|
||||||
|
| 17 | `residual_moment_denominator_scale` | `max(||f_int,f^phi||_inf,||f_ext,f^phi||_inf)` or `not-evaluated(reason)` |
|
||||||
|
| 18 | `residual_moment_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 19 | `residual_moment_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 20 | `residual_moment_threshold_unit` | `1`, `force*length`, or `not-evaluated(reason)` |
|
||||||
|
| 21 | `residual_moment_pass` | `0`, `1`, or `not-evaluated(reason)` |
|
||||||
|
| 22 | `correction_translation_channel` | literal `correction_translation` or `not-evaluated(reason)` |
|
||||||
|
| 23 | `correction_translation_numerator_norm` | `||Delta u_f||_inf` fresh correction or `not-evaluated(reason)` |
|
||||||
|
| 24 | `correction_translation_denominator_scale` | `||Delta u_inc,f||_inf` from current trial relative to step start or `not-evaluated(reason)` |
|
||||||
|
| 25 | `correction_translation_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 26 | `correction_translation_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 27 | `correction_translation_threshold_unit` | `1`, `length`, or `not-evaluated(reason)` |
|
||||||
|
| 28 | `correction_translation_pass` | `0`, `1`, or `not-evaluated(reason)` |
|
||||||
|
| 29 | `correction_rotation_channel` | literal `correction_rotation` or `not-evaluated(reason)` |
|
||||||
|
| 30 | `correction_rotation_numerator_norm` | `||Delta phi_f||_inf` fresh correction or `not-evaluated(reason)` |
|
||||||
|
| 31 | `correction_rotation_denominator_scale` | `||Delta phi_inc,f||_inf` from current trial relative to step start or `not-evaluated(reason)` |
|
||||||
|
| 32 | `correction_rotation_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 33 | `correction_rotation_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` |
|
||||||
|
| 34 | `correction_rotation_threshold_unit` | `1`, `1`, or `not-evaluated(reason)` |
|
||||||
|
| 35 | `correction_rotation_pass` | `0`, `1`, or `not-evaluated(reason)` |
|
||||||
|
| 36 | `combined_pass` | logical AND of four pass fields, or `not-evaluated(reason)` |
|
||||||
|
| 37 | `transition` | `accept`, `update`, `fail`, or `not-evaluated(reason)` |
|
||||||
|
| 38 | `outcome` | `accepted`, `continue`, `nonconverged`, or `failed` |
|
||||||
|
| 39 | `diagnostic_code` | `none` or approved diagnostic code |
|
||||||
|
|
||||||
|
Completed gate record는 `failing_stage=none`이고 네 channel의 identity, numerator/norm,
|
||||||
|
denominator/scale, branch, typed threshold, pass를 모두 finite 또는 enum value로 노출한다.
|
||||||
|
Denominator가 exact zero이면 branch는 `zero-scale`이고 typed threshold는 residual force
|
||||||
|
`1e-3 force`, residual moment `1e-3 force*length`, correction translation `1e-3 length`,
|
||||||
|
correction rotation `1e-3 dimensionless`다. Denominator가 nonzero이면 branch는 `relative`이고
|
||||||
|
threshold는 dimensionless `1e-2`다. Empty free channel은 numerator와 denominator가 exact zero인
|
||||||
|
`zero-scale` branch로 평가한다.
|
||||||
|
|
||||||
|
Early failure record는 entered iteration 하나에 대응한다. 이미 계산된 earlier fields는 실제
|
||||||
|
finite value를 기록하고, 실패 stage 뒤의 모든 later field는 `not-evaluated(reason)`을 기록한다.
|
||||||
|
Not-evaluated field에 zero, pass `0`, pass `1`, fabricated denominator 또는 fabricated
|
||||||
|
threshold를 쓰면 안 된다. `last_completed_stage`와 `failing_stage`는 stage enum을 사용하며
|
||||||
|
recommended enum은 `iteration-entered`, `trial-state`, `load-boundary`, `residual`,
|
||||||
|
`tangent`, `factorization`, `correction`, `convergence-gates`, `update`, `recovery`,
|
||||||
|
`commit`, `log-write`, `log-flush`, `none`이다.
|
||||||
|
|
||||||
|
Numeric value는 locale-independent C-locale decimal point를 사용하고 finite IEEE-754 `double`
|
||||||
|
round-trip이 가능해야 한다. `NaN`, `Inf`, localized comma, thousands separator, raw whitespace는
|
||||||
|
금지한다. String value는 raw TAB/LF/CR/control byte/backslash를 포함할 수 없으며 `\\`, `\t`,
|
||||||
|
`\n`, `\r`, `\0`, `\xHH` escape를 사용한다. Record order는 increment, target factor,
|
||||||
|
iteration 순서로 deterministic해야 한다.
|
||||||
|
|
||||||
|
Schema version `1`의 모든 mandatory HDF5 dataset은 contiguous, uncompressed dataset이다.
|
||||||
|
Chunking, compression filter, extendible dataset, trial-history group은 이 release 계약에 없다.
|
||||||
|
|
||||||
|
### 7.2 Metadata and Common Dataset Attribute Rules
|
||||||
|
|
||||||
|
`results.h5` schema가 authoritative solver output이다. 실제 final filename은 Section 7.1의
|
||||||
|
`<stem>_results.h5`다. 모든 string은 UTF-8이다. 모든 physical real dataset은 IEEE-754
|
||||||
|
float64를 사용한다. Stable ID는 별도 명시가 없으면 unsigned 64-bit integer다.
|
||||||
|
|
||||||
|
`/metadata` group의 required attributes는 다음과 같다.
|
||||||
|
|
||||||
|
| attribute | required value or meaning |
|
||||||
|
| --- | --- |
|
||||||
|
| `schema_version` | `1` |
|
||||||
|
| `feature_id` | `nonlinear-static-newton-raphson` |
|
||||||
|
| `solver_version` | executing solver version string |
|
||||||
|
| `source_input_identity` | lexical normalized user-addressed input path and content identity string; symlink/junction target resolution 없음 |
|
||||||
|
| `unit_system_label` | `user-consistent-unspecified` |
|
||||||
|
| `coordinate_convention` | `global-cartesian; shell-local=fixed-initial-reference; positive-thickness=+zeta` |
|
||||||
|
| `analysis_procedure` | `nonlinear-static-full-newton` |
|
||||||
|
| `internal_formulation` | `FESA-MITC4-total-lagrangian` |
|
||||||
|
| `integration_rule` | `2x2x2-gauss; mitc4-edge-midpoint-shear` |
|
||||||
|
| `step_name` | `Step-1` |
|
||||||
|
| `frame_indexing` | `accepted-increment-order-zero-based` |
|
||||||
|
| `factor_zero_is_frame` | `0` |
|
||||||
|
| `factor_zero_load_factor` | `0.0` |
|
||||||
|
|
||||||
|
모든 numeric model/result dataset은 다음 required attributes를 가진다.
|
||||||
|
|
||||||
|
- `schema_version=1`
|
||||||
|
- `component_names`
|
||||||
|
- `component_unit_dimensions`
|
||||||
|
- `coordinate_system`
|
||||||
|
- `location`
|
||||||
|
|
||||||
|
Accepted-frame result dataset은 추가로 다음 attributes를 가진다.
|
||||||
|
|
||||||
|
- `step_name=Step-1`
|
||||||
|
- `frame_index=<uint64>`
|
||||||
|
- `increment_index=<uint64>`
|
||||||
|
- `load_factor=<float64>`
|
||||||
|
- `is_factor_one=<0|1>`
|
||||||
|
|
||||||
|
### 7.3 Model Datasets
|
||||||
|
|
||||||
|
| dataset path | shape and dtype | row identity / fields | required attributes and ordering |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `/model/nodes` | `[node_count]` compound | `internal_node_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `coordinates:float64[3]` | internal ID ascending; `coordinate_system=global-cartesian`, `component_unit_dimensions=length,length,length`, `location=nodal-reference` |
|
||||||
|
| `/model/elements` | `[element_count]` compound | `internal_element_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `source_element_type:utf8`, `internal_formulation:utf8`, `node_internal_ids:uint64[4]`, `shell_section_internal_id:uint64`, `material_internal_id:uint64` | internal element ID ascending; `formulation=FESA-MITC4-total-lagrangian` |
|
||||||
|
| `/model/shell/materials` | `[material_count]` compound | `internal_material_id:uint64`, `name:utf8`, `E:float64`, `nu:float64` | declaration order; `component_unit_dimensions=force/length^2,1`, `location=model-material` |
|
||||||
|
| `/model/shell/sections` | `[section_count]` compound | `internal_section_id:uint64`, `source_file:utf8`, `source_line:uint64`, `source_elset:utf8`, `material_internal_id:uint64`, `thickness:float64` | declaration order; `component_unit_dimensions=length`, `location=model-shell-section`, `layering=centered-single-layer` |
|
||||||
|
| `/model/shell/nodal_director` | `[node_count,3]` float64 | `/model/nodes` row; `[D1,D2,D3]` | initial director; `coordinate_system=global-cartesian`, `location=nodal-initial-director`, units `1,1,1` |
|
||||||
|
| `/model/shell/nodal_frame` | `[node_count,3,3]` float64 | `/model/nodes` row; axis row `[A,B,D]`, global component column `[X,Y,Z]` | initial right-handed triad; `coordinate_system=global-cartesian`, `location=nodal-initial-frame`, units `1,1,1` |
|
||||||
|
| `/model/nodal_constraint_mask` | `[node_count,6]` uint8 | `/model/nodes` row; DOF `[UX,UY,UZ,URX,URY,URZ]` | `0=free`, `1=constrained`; constrained reaction comparison identity의 authority |
|
||||||
|
| `/model/prescribed_displacement_start` | `[node_count,6]` float64 | same row/DOF order | factor-zero start values; units `[length x3,1 x3]`, `load_factor=0.0` |
|
||||||
|
| `/model/prescribed_displacement_target` | `[node_count,6]` float64 | same row/DOF order | factor-one absolute target values; units `[length x3,1 x3]`, `load_factor=1.0` |
|
||||||
|
| `/model/shell/midsurface_locations` | `[4,2]` float64 | location rows `GP1..GP4`; columns `[XI,ETA]` | `coordinate_system=shell-natural`; `(-g,-g),(+g,-g),(+g,+g),(-g,+g)`, `g=1/sqrt(3)` |
|
||||||
|
| `/model/shell/section_positions` | `[3]` float64 | rows `[BOTTOM,MIDDLE,TOP]`; values `[-1,0,+1]` | `coordinate_system=shell-natural`; physical `z=t*zeta/2`; Abaqus section-point identity가 아님 |
|
||||||
|
|
||||||
|
### 7.4 Accepted Frame Table
|
||||||
|
|
||||||
|
Successful nonlinear run 뒤 `/steps/Step-1/accepted_frames`는 mandatory다.
|
||||||
|
|
||||||
|
| path | shape and dtype | fields | required meaning |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `/steps/Step-1/accepted_frames` | `[frame_count]` compound | `frame_index:uint64`, `increment_index:uint64`, `load_factor:float64`, `iteration_count:uint64`, `is_factor_one:uint8` | committed increment마다 한 row; `frame_index`는 `<frame>` group name과 같음; load factor는 strictly increasing; 마지막 row는 `load_factor=1.0`, `is_factor_one=1` |
|
||||||
|
|
||||||
|
`frame_count`는 committed increment 수이며 successful run에서는 하나 이상이다. Factor-one
|
||||||
|
row는 정확히 하나다. Factor zero는 이 dataset에 row를 갖지 않고 `/frames/0` 특별 의미도
|
||||||
|
갖지 않는다.
|
||||||
|
|
||||||
|
### 7.5 Accepted Frame Result Datasets
|
||||||
|
|
||||||
|
`/steps/Step-1/accepted_frames.frame_index = <frame>`마다 아래 dataset들이
|
||||||
|
`/steps/Step-1/frames/<frame>/` 아래 mandatory다.
|
||||||
|
|
||||||
|
| quantity | exact dataset path | shape | row identity and component order | units / coordinates / location |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| committed displacement and rotation vector | `/steps/Step-1/frames/<frame>/nodal/displacement` | `[node_count,6]` float64 | `/model/nodes` row; `[UX,UY,UZ,URX,URY,URZ]` | `[length,length,length,1,1,1]`; global Cartesian translations and fixed-initial global rotation-vector components; nodal |
|
||||||
|
| committed triad | `/steps/Step-1/frames/<frame>/nodal/triad` | `[node_count,3,3]` float64 | node row; axis row `[A,B,D]`, global component column `[X,Y,Z]` | dimensionless; global Cartesian; committed `Q`; director는 row `D` |
|
||||||
|
| committed director | `/steps/Step-1/frames/<frame>/nodal/director` | `[node_count,3]` float64 | node row; `[D1,D2,D3]` | dimensionless; global Cartesian; triad axis `D`와 같아야 함 |
|
||||||
|
| generalized internal force | `/steps/Step-1/frames/<frame>/nodal/generalized_internal_force` | `[node_count,6]` float64 | node row; `[FI1,FI2,FI3,MI_PHI1,MI_PHI2,MI_PHI3]` | `[force x3,force*length x3]`; work-conjugate to `[u,phi]`; nodal |
|
||||||
|
| generalized external force | `/steps/Step-1/frames/<frame>/nodal/generalized_external_force` | `[node_count,6]` float64 | node row; `[FE1,FE2,FE3,ME_PHI1,ME_PHI2,ME_PHI3]` | `[force x3,force*length x3]`; work-conjugate to `[u,phi]`; approved physical moment projection 후 fixed-global dead loads; nodal |
|
||||||
|
| generalized residual | `/steps/Step-1/frames/<frame>/nodal/generalized_residual` | `[node_count,6]` float64 | node row; `[RU1,RU2,RU3,RPHI1,RPHI2,RPHI3]` | `[force x3,force*length x3]`; nonlinear solution coordinate의 full assembled `f_int-f_ext`; nodal |
|
||||||
|
| reaction / physical residual projection | `/steps/Step-1/frames/<frame>/nodal/reaction` | `[node_count,6]` float64 | node row; `[RF1,RF2,RF3,RM1,RM2,RM3]` | `[force x3,force*length x3]`; global; constrained entry는 physical reaction, free entry는 same-state equilibrium evidence; rotational columns는 `J_l(phi)^(-T)` spatial moment conversion |
|
||||||
|
| shell local frame | `/steps/Step-1/frames/<frame>/element/shell/local_frame` | `[element_count,4,3,3]` float64 | element row, midsurface location row `GP1..GP4`, axis row `[E1,E2,E3]`, global component column `[X,Y,Z]` | dimensionless; physical recovery용 fixed-initial shell local frame; rotating Abaqus output frame이 아님 |
|
||||||
|
| generalized strain | `/steps/Step-1/frames/<frame>/element/shell/generalized_strain` | `[element_count,4,8]` float64 | element row, `GP1..GP4`; `[E11,E22,G12,K11,K22,K12,G13,G23]` | `[1,1,1,1/length,1/length,1/length,1,1]`; fixed-reference shell local; midsurface |
|
||||||
|
| section resultant | `/steps/Step-1/frames/<frame>/element/shell/section_resultant` | `[element_count,4,8]` float64 | element row, `GP1..GP4`; `[N11,N22,N12,M11,M22,M12,Q13,Q23]` | `[force/length x3,force x3,force/length x2]`; fixed-reference shell local; midsurface |
|
||||||
|
| in-plane stress | `/steps/Step-1/frames/<frame>/element/shell/stress` | `[element_count,4,3,3]` float64 | element row, `GP1..GP4`, section position `[BOTTOM,MIDDLE,TOP]`, component `[S11,S22,S12]` | `force/length^2`; fixed-reference shell local; direct bottom/middle/top evaluation |
|
||||||
|
| physical strain energy | `/steps/Step-1/frames/<frame>/global/energy` | `[1]` float64 | `[PHYSICAL_STRAIN_ENERGY]` | `force*length`; deterministic element reduction; numerical drilling stabilization 제외 |
|
||||||
|
| global equilibrium | `/steps/Step-1/frames/<frame>/global/equilibrium` | `[6]` float64 | `[FORCE_1,FORCE_2,FORCE_3,MOMENT_1,MOMENT_2,MOMENT_3]` | `[force x3,force*length x3]`; global Cartesian; moment about global origin `[0,0,0]`, current force arms와 spatial physical nodal moments 사용 |
|
||||||
|
|
||||||
|
Trial Newton state, iteration history, line search, cutback attempt, damping, automatic
|
||||||
|
stabilization, numerical drilling stress, drilling energy ratio, `S33`, `S13`, `S23`,
|
||||||
|
nodal stress extrapolation, element-corner stress, averaged stress, Abaqus integration-point
|
||||||
|
number에 대한 HDF5 dataset은 만들지 않는다.
|
||||||
|
|
||||||
|
### 7.6 Diagnostics Dataset
|
||||||
|
|
||||||
|
`/diagnostics`는 mandatory이며 row가 0개일 수 있다.
|
||||||
|
|
||||||
|
| path | shape and dtype | fields | required meaning |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `/diagnostics` | `[diagnostic_count]` compound | `severity:utf8`, `code:utf8`, `file:utf8`, `line:uint64`, `keyword:utf8`, `entity_identity:utf8`, `message:utf8` | CLI/input/model/solver/output deterministic diagnostics; ignored keyword warning도 success file에 보존 |
|
||||||
|
|
||||||
|
Diagnostic order는 source file declaration order, 1-based line, stable entity identity,
|
||||||
|
diagnostic code, discovery order를 순서대로 사용한다. Source가 없는 CLI/solver/output
|
||||||
|
diagnostic은 explicit empty source field를 사용한다.
|
||||||
|
|
||||||
|
### 7.7 Output Failure and Atomic Finalization
|
||||||
|
|
||||||
|
Writer는 log close 성공 뒤에만 final file과 같은 directory에 implementation-private temporary
|
||||||
|
HDF5 candidate를 만든다. Candidate는 metadata, model datasets, accepted-frame table, 모든
|
||||||
|
accepted-frame dataset, diagnostics를 모두 쓰고, shape, attribute, finite value, source
|
||||||
|
identity, row order를 검증한다. Checked HDF5 close와 read-only reopen/self-check가 성공한
|
||||||
|
뒤에만 final `<stem>_results.h5`를 replace/create한다. 실패한 candidate는 제거하거나
|
||||||
|
non-authoritative implementation-private artifact로만 남긴다. Controlled failure는 incomplete
|
||||||
|
final result를 노출하면 안 된다. HDF5 failure는 이미 닫힌 current-run log를 rollback하지 않는다.
|
||||||
|
|
||||||
|
## 8. FESA HDF5 to Reference CSV Comparison Mapping
|
||||||
|
|
||||||
|
Comparison tooling은 FESA `results.h5` schema와 exact read-only Abaqus CSV artifact만 읽는다.
|
||||||
|
CSV는 FESA output이 아니다. HDF5에서 추출한 deterministic CSV view는 debugging/reporting
|
||||||
|
보조물로만 둘 수 있다.
|
||||||
|
|
||||||
|
### 8.1 Declared Cases and Artifacts
|
||||||
|
|
||||||
|
| case id | role | exact path | comparison disposition |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `shellnl-s4-final` | nonlinear input | `reference/shellNL/shellNL.inp` | required source input |
|
||||||
|
| `shellnl-s4-final` | displacement CSV | `reference/shellNL/shellNL displacements.csv` | required comparison |
|
||||||
|
| `shellnl-s4-final` | reaction CSV | `reference/shellNL/shellNL reactions.csv` | constrained nodes/components only required comparison |
|
||||||
|
| `shellnl-s4-final` | stress CSV | `reference/shellNL/shellNL stresses.csv` | optional read-only inspection/order evidence only |
|
||||||
|
| `shell-s4-linear-limit` | linear control input | `reference/shell/shell.inp` | existing linear MITC4 contract의 required regression input |
|
||||||
|
| `shell-s4-linear-limit` | displacement CSV | `reference/shell/shell displacements.csv` | required regression comparison |
|
||||||
|
| `shell-s4-linear-limit` | reaction CSV | `reference/shell/shell reactions.csv` | optional read-only inspection only |
|
||||||
|
| `shell-s4-linear-limit` | stress CSV | `reference/shell/shell stresses.csv` | optional read-only inspection/order evidence only |
|
||||||
|
|
||||||
|
Reference artifact file은 workflow에서 rename, rewrite, normalize, zero-clamp, repair,
|
||||||
|
regenerate하지 않는다.
|
||||||
|
|
||||||
|
### 8.2 Accepted-State and Frame Mapping
|
||||||
|
|
||||||
|
- `shellnl-s4-final`은 accepted factor-one HDF5 frame만 비교한다. 해당 frame은
|
||||||
|
`/steps/Step-1/accepted_frames`에서 `is_factor_one=1`이고 `load_factor=1.0`인 unique row다.
|
||||||
|
그 `frame_index`가 `/steps/Step-1/frames/<frame>`를 선택한다.
|
||||||
|
- Required `shellNL` CSV row는 exact `Frame` value
|
||||||
|
`Increment 10: Step Time = 1.000`만 가져야 하며, 이는 accepted factor-one state로
|
||||||
|
논리 매핑한다. Required row에 다른 `Frame` 값이 있으면 schema mismatch다.
|
||||||
|
- `shell-s4-linear-limit` CSV에는 `Frame` column이 없으며
|
||||||
|
`docs/linear-static-mitc4-shell/io.md`의 existing linear MITC4 final frame
|
||||||
|
`/steps/Step-1/frames/0`에 매핑한다.
|
||||||
|
- Trial Newton state, iteration log line, optional stress inventory row는 reference row가
|
||||||
|
아니다.
|
||||||
|
|
||||||
|
### 8.3 Nodal Displacement Projection
|
||||||
|
|
||||||
|
Required logical key는 다음과 같다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
(case_id, accepted_state, canonical_instance_name, source_node_label, component)
|
||||||
|
```
|
||||||
|
|
||||||
|
두 case 모두 instance `PART-1-1`에서 node label `1..49`가 정확히 한 번씩 필요하다.
|
||||||
|
Instance matching은 case-insensitive로 수행하되 report에는 raw spelling을 보존한다.
|
||||||
|
|
||||||
|
| CSV column | comparison component | nonlinear HDF5 source | linear regression HDF5 source |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `U-U1` | `U1` | `nodal/displacement` column `UX` | `nodal/displacement` column `UX` |
|
||||||
|
| `U-U2` | `U2` | `nodal/displacement` column `UY` | `nodal/displacement` column `UY` |
|
||||||
|
| `U-U3` | `U3` | `nodal/displacement` column `UZ` | `nodal/displacement` column `UZ` |
|
||||||
|
| `UR-UR1` | `UR1` | `nodal/displacement` column `URX` | `nodal/displacement` column `URX` |
|
||||||
|
| `UR-UR2` | `UR2` | `nodal/displacement` column `URY` | `nodal/displacement` column `URY` |
|
||||||
|
| `UR-UR3` | `UR3` | `nodal/displacement` column `URZ` | `nodal/displacement` column `URZ` |
|
||||||
|
|
||||||
|
`U1/U2/U3`는 blocking이다. `UR1/UR2/UR3`는 두 case 모두 warning-only다. UR warning
|
||||||
|
exceedance는 blocking verdict를 바꾸지 않는다.
|
||||||
|
|
||||||
|
### 8.4 Nonlinear Constrained Reaction Projection
|
||||||
|
|
||||||
|
Reaction comparison은 `shellnl-s4-final`에만 적용하며 input boundary mask의 constrained node
|
||||||
|
중 아래 24개 node에만 적용한다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33
|
||||||
|
```
|
||||||
|
|
||||||
|
승인 input에서 이 24개 node는 여섯 global DOF가 모두 constrained다. Comparator는 required
|
||||||
|
HDF5 reaction row eligibility를 CSV zero value가 아니라 `/model/nodal_constraint_mask`와
|
||||||
|
source node identity에서 도출한다.
|
||||||
|
|
||||||
|
| CSV columns | logical family | HDF5 source | disposition |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `RF-RF1`, `RF-RF2` | `nonlinear.reaction_inplane_force` | factor-one `/nodal/reaction` columns `RF1,RF2` | blocking |
|
||||||
|
| `RF-RF3` | `nonlinear.reaction_transverse_force` | factor-one `/nodal/reaction` column `RF3` | blocking |
|
||||||
|
| `RM-RM1`, `RM-RM2` | `nonlinear.reaction_physical_moment` | factor-one `/nodal/reaction` columns `RM1,RM2`; `J_l(phi)^(-T)` 변환 뒤 spatial physical moment | blocking |
|
||||||
|
| `RM-RM3` | excluded | comparison projection 없음 | blocking 및 warning-only family에서 제외 |
|
||||||
|
|
||||||
|
Raw generalized rotation-coordinate residual column은 Abaqus `RM` CSV column과 직접 비교하지
|
||||||
|
않는다.
|
||||||
|
|
||||||
|
### 8.5 Comparison Families
|
||||||
|
|
||||||
|
External tolerance source는 정확히 `docs/TOLERANCE.md`다. 별도 absolute floor, `max(1,S)`
|
||||||
|
clamp, row averaging, source-order matching, component calibration, zero clamp는 허용하지
|
||||||
|
않는다.
|
||||||
|
|
||||||
|
| family id | case | components | required row count | units / coordinates | disposition |
|
||||||
|
| --- | --- | --- | ---: | --- | --- |
|
||||||
|
| `linear.translation` | `shell-s4-linear-limit` | `U1,U2,U3` on nodes `1..49` | 147 | length / global | blocking regression |
|
||||||
|
| `linear.rotation` | `shell-s4-linear-limit` | `UR1,UR2,UR3` on nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only |
|
||||||
|
| `nonlinear.translation` | `shellnl-s4-final` | `U1,U2,U3` on nodes `1..49` | 147 | length / global | blocking |
|
||||||
|
| `nonlinear.rotation` | `shellnl-s4-final` | `UR1,UR2,UR3` on nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only |
|
||||||
|
| `nonlinear.reaction_inplane_force` | `shellnl-s4-final` | `RF1,RF2` on constrained nodes | 48 | force / fixed-initial global plane | blocking |
|
||||||
|
| `nonlinear.reaction_transverse_force` | `shellnl-s4-final` | `RF3` on constrained nodes | 24 | force / fixed-initial global transverse | blocking |
|
||||||
|
| `nonlinear.reaction_physical_moment` | `shellnl-s4-final` | `RM1,RM2` on constrained nodes | 48 | force*length / global spatial | blocking |
|
||||||
|
|
||||||
|
Reference-model read-only scale audit value는 다음과 같다.
|
||||||
|
|
||||||
|
| family id | `S=max(abs(reference))` | `0.01*S` |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| `linear.translation` | `2.37408203e-5` | `2.37408203e-7` |
|
||||||
|
| `linear.rotation` | `7.60725743e-6` | `7.60725743e-8` |
|
||||||
|
| `nonlinear.translation` | `2.37408203e-5` | `2.37408203e-7` |
|
||||||
|
| `nonlinear.rotation` | `7.60725743e-6` | `7.60725743e-8` |
|
||||||
|
| `nonlinear.reaction_inplane_force` | `1.91663182` | `1.91663182e-2` |
|
||||||
|
| `nonlinear.reaction_transverse_force` | `1.17769805e4` | `1.17769805e2` |
|
||||||
|
| `nonlinear.reaction_physical_moment` | `1.95418418e4` | `1.95418418e2` |
|
||||||
|
|
||||||
|
### 8.6 Row Prechecks
|
||||||
|
|
||||||
|
아래 조건 중 하나라도 거짓이면 comparator는 tolerance 계산 전에 실패한다.
|
||||||
|
|
||||||
|
1. Exact declared input path와 required CSV path가 존재하고 readable이다.
|
||||||
|
2. Reference CSV header는 surrounding whitespace trim 뒤 필요한 column을 가진다.
|
||||||
|
3. `shellnl-s4-final` required row는 exact approved `Frame` value만 포함한다.
|
||||||
|
4. HDF5 metadata, model rows, accepted-frame table, factor-one frame, required result dataset이
|
||||||
|
문서화된 shape, component name, finite value를 가진다.
|
||||||
|
5. Wide CSV row는 이 문서의 component mapping으로 component row로 expand한다.
|
||||||
|
6. Required source wide key와 expanded component key는 unique하다. Duplicate reference 또는
|
||||||
|
HDF5 key는 실패다.
|
||||||
|
7. 각 declared family에서 FESA와 reference projected key set은 정확히 같아야 한다. Missing row와
|
||||||
|
extra row는 모두 실패다.
|
||||||
|
8. 모든 required numeric value는 finite다. Nonfinite HDF5 또는 CSV value는 tolerance 전 실패다.
|
||||||
|
9. `shellNL` reaction row는 constrained mask와 exact 24-node list에서 선택한다. Free-node CSV
|
||||||
|
row는 inventory only이며 zero reaction target으로 해석하지 않는다.
|
||||||
|
10. Required row를 omit, synthesize, average, substitute identity로 sort, normalize, zero-clamp,
|
||||||
|
repair하지 않는다.
|
||||||
|
|
||||||
|
### 8.7 Stress CSV Disposition
|
||||||
|
|
||||||
|
Optional stress CSV identity는 다음과 같다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
(case_id, accepted_state, instance, element_label,
|
||||||
|
element_corner_node_label, section_surface, component)
|
||||||
|
```
|
||||||
|
|
||||||
|
현재 stress CSV는 element-corner node row와 `SPOS/SNEG` section surface에서 `S-S11`,
|
||||||
|
`S-S22`, `S-S33`, `S-S12`를 포함하며, 저장된 ascending element-label block `1..36` 순서를
|
||||||
|
갖는다. FESA HDF5는 `GP1..GP4`와 `BOTTOM/MIDDLE/TOP`에서 direct `[S11,S22,S12]`만 emit한다.
|
||||||
|
|
||||||
|
따라서 두 case의 stress CSV는 optional read-only inspection 및 order evidence only다. HDF5
|
||||||
|
comparison projection, `S33` synthesis, nodal extrapolation, corner averaging, Gauss-to-corner
|
||||||
|
matching, element-label-order identity는 없다.
|
||||||
|
|
||||||
|
## 9. Validation Rules
|
||||||
|
|
||||||
|
| validation area | required pass condition | failure class |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| CLI usage | input path 정확히 하나; 어떤 argv token에도 exact literal substring `--output` 없음; matching 시 path resolution/parsing/Analysis/log/HDF5 전 `cli-usage` stderr diagnostic 정확히 1개 | usage, exit `2` |
|
||||||
|
| keyword inventory | keyword가 supported, explicit diagnostic의 unsupported, 또는 exact ignored-with-warning allowlist 중 하나 | input, exit `3` |
|
||||||
|
| syntax | ASCII keyword/data grammar, comma fields, finite numeric tokens, continuation/include 없음 | input, exit `3` |
|
||||||
|
| nesting/cardinality | part/assembly/instance/step이 닫힘; nonlinear procedure는 정확히 하나의 `NLGEOM=YES` step | input, exit `3` |
|
||||||
|
| source identity | scope 내 duplicate name/label 없음; 모든 reference resolved; instance identity unique | input, exit `3` |
|
||||||
|
| set expansion | explicit/generated set이 deterministic expand되고 하나의 supported scope/instance에 머묾 | input, exit `3` |
|
||||||
|
| shell element | only `S4/S4R`; 네 개의 distinct resolved nodes; mixed element model 없음; source type metadata 보존 | input/model, exit `3` 또는 `4` |
|
||||||
|
| material and section | single isotropic elastic material, centered homogeneous positive-thickness shell section, element마다 정확히 하나의 assignment | input/model, exit `3` 또는 `4` |
|
||||||
|
| geometry and coordinates | finite global coordinates, positive reference/current validity checks, required location마다 valid directors/triads/branches | model 또는 solver trial failure, exit `4` 또는 `5` |
|
||||||
|
| boundary | DOF `1..6`, resolved finite targets, factor-one absolute meaning, conflicting expanded value 없음 | input, exit `3` |
|
||||||
|
| load | resolved finite `CLOAD`, stable aggregation, fixed-global dead path, unsupported `DLOAD`/follower/distributed load 없음 | input/model, exit `3` 또는 `4` |
|
||||||
|
| aggregate moment | exact-zero case 또는 preprocessing 및 모든 entered trial에서 `rho_M<=1e-12` | model/solver, exit `4` 또는 `5` |
|
||||||
|
| nonlinear static data | 네 positive finite values, endpoint `1.0`, fixed increment sequence with final exact factor one | input, exit `3` |
|
||||||
|
| Newton iteration | iteration identity `1..100`; iteration `100` acceptance 가능; iteration `101` 없음; line search/cutback/retry/fallback 없음 | solver, exit `5` |
|
||||||
|
| convergence channels | residual force, residual moment, correction translation, correction rotation이 모두 inclusive `<=` rule 또는 typed zero-scale threshold 통과 | solver, exit `5` |
|
||||||
|
| nonfinite data | required residual, tangent, correction, state, load, recovery, output value가 acceptance 전 finite | solver/output, exit `5` 또는 `6` |
|
||||||
|
| commit/rollback | complete converged candidate만 commit; failure는 prior committed state와 prior authoritative final HDF5 보존 | solver/output, exit `5` 또는 `6` |
|
||||||
|
| HDF5 schema | exact paths, shapes, attributes, schema version, row identities, finite values, accepted-frame table, diagnostics; final replace는 log close success 뒤에만 허용 | output, exit `6` |
|
||||||
|
| log | UTF-8 no BOM, LF, TAB-separated fixed `label=value` schema; entered Newton iteration마다 record 하나; no per-iteration stderr duplication; no-Newton procedure는 zero-byte empty log; open/write/flush/close fail-closed | output, exit `6` |
|
||||||
|
| reference rows | exact required artifacts, headers, row keys, component keys, finite values, factor-one frame mapping | reference precheck |
|
||||||
|
| tolerance | exact `docs/TOLERANCE.md` family-scale row/RMS policy; blocking/warning disposition 보존 | reference verification |
|
||||||
|
|
||||||
|
Downstream test가 다뤄야 하는 approved diagnostic code는 다음을 포함한다.
|
||||||
|
|
||||||
|
| code | class | meaning |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `cli-usage` | usage/2 | argv token이 exact literal substring `--output`을 포함하며 pre-input/pre-log/pre-output failure 하나를 stderr에 기록 |
|
||||||
|
| `unrecognized-option` | usage/2 | `--output` substring을 포함하지 않는 다른 unsupported option |
|
||||||
|
| `malformed-keyword` | input/3 | keyword 또는 parameter grammar invalid |
|
||||||
|
| `invalid-keyword-location` | input/3 | keyword가 approved scope 밖에 위치 |
|
||||||
|
| `invalid-keyword-parameter` | input/3 | parameter missing, duplicate, empty 또는 subset 밖 |
|
||||||
|
| `unsupported-keyword` | input/3 | `*INCLUDE` 포함 approved subset 밖 keyword |
|
||||||
|
| `unsupported-distributed-load` | input/3 | `*DLOAD`, pressure, gravity, body, edge, follower load 요청 |
|
||||||
|
| `duplicate-entity` | input/3 | source identity가 scope 안에서 duplicate |
|
||||||
|
| `unresolved-reference` | input/3 | connectivity, set, instance, section, material, load, boundary target dangling |
|
||||||
|
| `unsupported-element-formulation` | input/3 | shell feature에서 source element type이 `S4` 또는 `S4R`가 아님 |
|
||||||
|
| `unsupported-mixed-element-model` | input/3 | shell과 non-shell product semantics 혼합 |
|
||||||
|
| `invalid-shell-connectivity` | input/3 | shell connectivity arity, duplicate node 또는 resolved node identity invalid |
|
||||||
|
| `unsupported-shell-section-option` | input/3 | composite/layer/offset/orientation/variable-thickness section 의미 등장 |
|
||||||
|
| `invalid-shell-material` | model/4 | material value가 finite `E,nu` bound 위반 |
|
||||||
|
| `invalid-shell-thickness` | model/4 | shell thickness nonfinite 또는 nonpositive |
|
||||||
|
| `invalid-shell-geometry` | model/4 | shell geometry, reference Jacobian 또는 topology invalid |
|
||||||
|
| `opposed-incident-normal` | model/4 | averaging 전 incident normal pair가 nonpositive |
|
||||||
|
| `invalid-shell-director` | model/4 | nodal/interpolated director, triad 또는 branch validity 실패 |
|
||||||
|
| `invalid-shell-jacobian` | model/4 | required Gauss/tying/center/recovery point의 basis/Jacobian invalid |
|
||||||
|
| `unsupported-drilling-load` | model/4 또는 solver/5 | aggregate nodal moment가 current-director admissibility 위반 |
|
||||||
|
| `invalid-nonlinear-static-data` | input/3 | `*STATIC` row arity, finite/positive check 또는 endpoint-one identity 실패 |
|
||||||
|
| `unsupported-analysis-procedure` | input/3 | supported nonlinear static source step으로 매핑되지 않음 |
|
||||||
|
| `nonfinite-newton-data` | solver/5 | required residual, tangent, correction 또는 trial state nonfinite |
|
||||||
|
| `tangent-factorization-failed` | solver/5 | entered iteration의 fresh tangent factorization 실패 |
|
||||||
|
| `correction-solve-failed` | solver/5 | fresh Newton correction solve 실패 |
|
||||||
|
| `nonlinear-nonconvergence` | solver/5 | iteration `100` 완료 후 네 convergence channel이 모두 통과하지 않음 |
|
||||||
|
| `invalid-accepted-state` | solver/5 | converged candidate recovery/state identity가 commit 전 실패 |
|
||||||
|
| `log-output-failure` | output/6 | required live log create/open/truncate, write, flush 또는 close 실패 |
|
||||||
|
| `output-busy` | output/6 | same derived pair single-writer lock을 획득하지 못했거나 lock path collision 발생 |
|
||||||
|
| `hdf5-output-failure` | output/6 | candidate HDF5 write, schema validation 또는 atomic finalization 실패 |
|
||||||
|
|
||||||
|
## 10. Open Issues and Downstream Handoff
|
||||||
|
|
||||||
|
Open issues blocking Implementation Planning: 없음.
|
||||||
|
|
||||||
|
Downstream handoff to Implementation Planning Agent through Coordinator:
|
||||||
|
|
||||||
|
- Public CLI/output naming migration을 보존한다: `fesa.exe <model.inp>`,
|
||||||
|
lexical sibling `<stem>_results.h5`, `<stem>_log.txt`, 그리고 exact literal substring
|
||||||
|
`--output`을 포함하는 모든 argv token의 pre-input/pre-log/pre-output exit `2`와 정확히
|
||||||
|
하나의 `cli-usage` stderr diagnostic.
|
||||||
|
- Supported/unsupported/ignored keyword row와 nonlinear `*STATIC` rule을 parser
|
||||||
|
acceptance/rejection test로 변환한다.
|
||||||
|
- Stored reference grammar인 `*Output, field, variable=PRESELECT`와
|
||||||
|
`*Output, history, variable=PRESELECT`를 duplicate/extra parameter 없이
|
||||||
|
`ignored-with-warning`으로 수용하고, output request가 FESA output을 바꾸지 못함을 test한다.
|
||||||
|
- `NLGEOM=YES`가 nonlinear procedure를 선택하고 `shell` `NLGEOM=NO` case가 기존 linear
|
||||||
|
MITC4 contract의 regression으로 남는지 test한다.
|
||||||
|
- HDF5 schema version `1`을 위 accepted-frame schema 그대로 구현한다. Factor-zero non-frame
|
||||||
|
handling, unique factor-one frame selection, triad/director projection, no
|
||||||
|
compression/chunking, no trial-state HDF5 history를 포함한다.
|
||||||
|
- 비대칭 lifecycle을 보존한다. Log는 usage validation, lexical path derivation, single-writer
|
||||||
|
lock 뒤 live current-run audit이고, log create/open/truncate는 Analysis 전 abort, write/flush는
|
||||||
|
즉시 abort, close failure는 HDF5 commit을 block한다. HDF5 final은 log close와 candidate
|
||||||
|
self-check 성공 뒤에만 replace하며 failure는 prior valid final과 current log를 손상하지 않는다.
|
||||||
|
- Newton log parser/schema test는 UTF-8 no BOM, LF, physical TAB-separated fixed
|
||||||
|
`label=value` field order, finite round-trip numerics, escaping, completed-gate four-channel
|
||||||
|
metrics, early-failure `not-evaluated(reason)`, no-Newton zero-byte log, zero per-iteration
|
||||||
|
stderr duplication, flush-before-next/return을 포함한다.
|
||||||
|
- Exact CSV paths, trimmed headers, exact `shellNL` `Frame` value, source node/component
|
||||||
|
identity, constrained reaction mask, missing/extra/duplicate rows, nonfinite values를
|
||||||
|
tolerance 전에 precheck한다.
|
||||||
|
- Declared family에는 `docs/TOLERANCE.md`만 적용한다. `U`는 blocking, `UR`은 warning-only,
|
||||||
|
`RF1/RF2`, `RF3`, physical spatial `RM1/RM2`는 blocking으로 유지하고 `RM3`와 모든 stress
|
||||||
|
CSV value는 제외한다.
|
||||||
|
- Optional stress CSV는 read-only inventory/order evidence only로 유지한다. Nodal stress
|
||||||
|
extrapolation, corner averaging, `S33` synthesis, element-label-order matching을 추가하지
|
||||||
|
않는다.
|
||||||
|
- Final HDF5 projection, parser diagnostics, schema tests, reference comparison tests,
|
||||||
|
log lifecycle tests는 Coordinator를 통해 전달한다. 이 문서만으로 parser, C++ API,
|
||||||
|
reference artifact, comparison-result, physics, release 변경을 승인하지 않는다.
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
# Nonlinear Static Newton-Raphson 수치 검토
|
||||||
|
|
||||||
|
## 1. Metadata and source formulation
|
||||||
|
|
||||||
|
- feature_id: `nonlinear-static-newton-raphson`
|
||||||
|
- source_formulation: `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- source_formulation_status: `ready-for-numerical-review`
|
||||||
|
- source_formulation_sha256: `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`
|
||||||
|
- source_requirements: `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- source_requirements_sha256: `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`
|
||||||
|
- source_research: `docs/nonlinear-static-newton-raphson/research.md`
|
||||||
|
- source_research_sha256: `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`
|
||||||
|
- repository_policy: `AGENTS.md`, `docs/SOLVER_AGENT_DESIGN.md`, `docs/TOLERANCE.md`
|
||||||
|
- related_linear_contracts: `docs/linear-static-mitc4-shell/numerical-review.md`,
|
||||||
|
`docs/linear-static-mitc4-shell/reference-model.md`
|
||||||
|
- status: `pass-for-io-definition`
|
||||||
|
- owner_agent: `numerical-review-agent`
|
||||||
|
- date: `2026-08-23`
|
||||||
|
|
||||||
|
이 검토는 정식화를 수학 및 수치 알고리즘 계약으로만 검토했다. C++ API, HDF5 schema,
|
||||||
|
implementation plan, reference solver 실행, reference artifact 생성/수정은 수행하지 않았다.
|
||||||
|
|
||||||
|
## 2. Review Verdict
|
||||||
|
|
||||||
|
- verdict: `pass-for-io-definition`
|
||||||
|
- reason: 승인 정식화는 fixed-initial-reference Total Lagrangian MITC4, finite rotation
|
||||||
|
state, nonlinear `24 -> 20` map, objective drilling, fixed-global load work,
|
||||||
|
same-trial residual/tangent, Full Newton convergence, recovery와 state commit/rollback
|
||||||
|
의미를 구현 가능한 수치 계약으로 닫고 있다. 차원, 부호, DOF 순서, 적분, reaction
|
||||||
|
의미 또는 reference identity와 충돌하는 blocking defect는 확인되지 않았다.
|
||||||
|
- reference readiness: `reference/shellNL` 및 `reference/shell`의 선언 파일과 CSV는
|
||||||
|
읽을 수 있고 row identity/precheck/tolerance 계약을 정의할 수 있다.
|
||||||
|
- boundary: 이 verdict는 I/O Definition 진입 허가이며 implementation, reference comparison
|
||||||
|
pass, physics evaluation 또는 release readiness 승인이 아니다.
|
||||||
|
|
||||||
|
`reference/shellNL`은 `nlgeom=YES`와 factor-one final frame을 갖는 저장 reference로 사용할 수
|
||||||
|
있지만, 주요 `U3`와 stress 값은 선형 `reference/shell`과 거의 같다. 관찰된 nonlinear 신호는
|
||||||
|
주로 약한 in-plane coupling이다(`RF1/RF2` 최대 약 `1.9166`, `U1/U2` 최대 약
|
||||||
|
`1.29e-11`). 따라서 이 CSV 세트만으로 finite-rotation objectivity, exact tangent,
|
||||||
|
rollback 또는 큰 변위 benchmark를 통과했다고 판단하지 않는다. 해당 항목은 아래의
|
||||||
|
blocking internal tests로 분리한다.
|
||||||
|
|
||||||
|
## 3. Critical Findings
|
||||||
|
|
||||||
|
### Confirmed defects
|
||||||
|
|
||||||
|
없음. Formulation Agent 또는 Research Agent로 즉시 되돌릴 confirmed numerical defect는 없다.
|
||||||
|
|
||||||
|
### Numerical risks requiring downstream evidence
|
||||||
|
|
||||||
|
- `shellNL`의 stored reference는 geometric nonlinearity가 켜진 최종 상태 비교에는 충분하지만
|
||||||
|
response amplitude가 작아 finite-rotation/tangent/objectivity 검증을 대신하지 못한다.
|
||||||
|
- Abaqus stress CSV는 `(instance, element label, element-corner node label,
|
||||||
|
section point, component)` identity로 완전하지만 FESA의 approved Gauss-location direct
|
||||||
|
bottom/middle/top recovery와 location이 다르다. Current stored order는 element label
|
||||||
|
`1..36` ascending block이며 이를 바꾸지 않는다. Nodal extrapolation/averaging을 만들지
|
||||||
|
않고 stress CSV는 comparison family에서 제외한다.
|
||||||
|
- External `UR` comparison은 기존 MITC4 정책에 따라 `warning-only`다. Rotation/director
|
||||||
|
correctness는 `Q`, `d`, branch, objectivity invariant tests에서 blocking으로 확인해야 한다.
|
||||||
|
|
||||||
|
### Open questions
|
||||||
|
|
||||||
|
현재 I/O Definition 진입을 막는 open question은 없다. Large-response public benchmark,
|
||||||
|
MMS, broader locking/distortion characterization은 유용하지만 승인된 Stage 4 pass 조건은 아니다.
|
||||||
|
|
||||||
|
## 4. Numerical Risk Assessment
|
||||||
|
|
||||||
|
| risk label | assessment | required control / downstream evidence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `rigid_body_modes` | 물리/internal/drill energy가 finite rigid motion에서 objective해야 하며 pure drill만 regularized 되어야 한다. | finite rigid translation/rotation superposition에서 strain, stress, physical energy, drill gamma, residual을 blocking invariant로 확인한다. |
|
||||||
|
| `patch_test` | Green-Lagrange direct strain과 MITC tied shear가 같은 trial geometry와 같은 first/second variation을 써야 한다. | membrane, bending, twist, transverse-shear patch를 linear limit와 finite valid trial perturbation에서 각각 확인한다. |
|
||||||
|
| `symmetry` | applied nodal moment가 없으면 physical/drill tangent는 exact arithmetic에서 symmetric이다. Fixed-spatial moment work tangent는 일반적으로 nonsymmetric이다. | no-moment case만 scaled symmetry check 대상으로 두고, moment case를 임의 symmetrization하지 않는다. |
|
||||||
|
| `positive_definiteness` | nonlinear tangent는 load state, compression, near-buckling에서 indefinite일 수 있다. Positive definiteness는 일반 gate가 아니다. | stress-free constrained linear limit의 nonsingular solve와 singular negative case를 분리하고, factorization failure를 숨기지 않는다. |
|
||||||
|
| `hourglass` | S4/S4R 모두 `2 x 2 x 2` full integration이므로 one-point reduced hourglass path는 승인 범위 밖이다. | source type으로 reduced/selective integration 또는 hourglass stabilization을 선택하지 않는 unit/integration test가 필요하다. |
|
||||||
|
| `shear_locking` | MITC shear tying은 transverse-shear locking을 완화하지만 모든 thin-shell mesh에서 locking-free를 보장하지 않는다. | patch/reference evidence를 blocking으로 두고 broader thin/thick convergence는 nonblocking characterization으로 둔다. |
|
||||||
|
| `volumetric_locking` | approved plane-stress shell, St. Venant-Kirchhoff-type material restriction에서는 `N/A`다. | 3-D incompressible material 또는 `nu >= 0.5` 의미로 확장하지 않는다. |
|
||||||
|
| `membrane_locking` | original-style MITC4는 curved/distorted nonlinear meshes에서 membrane locking 위험이 남는다. | known limitation으로 기록한다. MITC4+ 성능 또는 Abaqus S4/S4R internal equivalence를 주장하지 않는다. |
|
||||||
|
| `distortion` | positive Jacobian이라도 severe distortion/warpage는 conditioning과 stress accuracy를 악화할 수 있다. | 모든 Gauss/tying/center/recovery location의 finite, positive predicate를 fail-closed로 적용한다. 추가 quality cutoff는 요구하지 않는다. |
|
||||||
|
| `singular_jacobian` | `J0 <= 0`, `j <= 0`, invalid reciprocal basis, invalid polar stretch는 residual/tangent를 무효화한다. | failed location을 omit/average/clamp/repair하지 않고 model/trial failure로 처리한다. |
|
||||||
|
| `conditioning` | thin shells, small fixed drill scale, near-mechanism constraints는 Kff conditioning을 악화시킬 수 있다. | scaled matrix diagnostics만 사용하고 solver regularization/fallback으로 singularity를 숨기지 않는다. |
|
||||||
|
| `convergence` | Full Newton은 same-trial consistent tangent에 의존한다. No line search/cutback이므로 difficult step은 deterministic nonconvergence가 될 수 있다. | NSNR-069/070 four-channel gates, iteration `1..100`, nonfinite rejection, no hidden retry를 integration tests로 고정한다. |
|
||||||
|
|
||||||
|
## 5. Consistency Checks
|
||||||
|
|
||||||
|
| check | result | evidence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| units and dimensions | `pass` | Translation/force, rotation/moment, stress/resultant dimensions are separated. Convergence channels keep force, force-length, length and dimensionless rotation separate. |
|
||||||
|
| signs and residual convention | `pass` | Global residual is `f_int - f_ext`; constrained full residual is reaction and free residual is equilibrium evidence. Fixed-global dead force has no configuration derivative. |
|
||||||
|
| DOF ordering and free/constrained assumptions | `pass` | Per-node global order is `[UX, UY, UZ, URX, URY, URZ]`; Newton solve uses stable free coordinates with `Delta q_c = 0`. Valid `0 x 0` free system is trivial success. |
|
||||||
|
| coordinate transforms | `pass` | `Q=Exp(phi^)Q0`, left-spatial update, `J_l` variation, physical swing map and spatial reaction moment conversion are explicitly defined. |
|
||||||
|
| kinematic operator / B matrix | `pass` | Green-Lagrange strain, MITC shear projection and both first/second variations use the same trial identity. |
|
||||||
|
| constitutive contract | `pass` | Constant symmetric `C5` maps engineering Green-Lagrange strain to second Piola-Kirchhoff stress; no material history is introduced. |
|
||||||
|
| Jacobian rules | `pass` | Fixed reference `J0` is integration measure; current `j` and `det F_c` are validity checks. Failed locations are not skipped. |
|
||||||
|
| integration policy | `pass` | S4 and S4R share four midsurface Gauss points times two thickness points; reduced/selective integration is prohibited. |
|
||||||
|
| residual/tangent consistency | `pass` | Complete tangent includes material, geometric, map-Hessian, objective drill Hessian and fixed-spatial moment work derivative terms. |
|
||||||
|
| tangent symmetry expectation | `pass` | Symmetric only for conservative no-applied-moment case; generally nonsymmetric moment tangent must remain unsymmetrized. |
|
||||||
|
| output locations | `pass-with-handoff` | Nodal U/UR/RF/RM and shell stress/resultant logical quantities are defined; exact HDF5 projection remains I/O-owned. Current nodal SPOS/SNEG stress CSV는 Gauss direct recovery와 일대일 대응하지 않으므로 external numerical comparison은 N/A다. |
|
||||||
|
|
||||||
|
## 6. Verification Readiness
|
||||||
|
|
||||||
|
### Blocking internal numerical tests
|
||||||
|
|
||||||
|
Implementation Planning shall carry these as feature-required tests before any reference-comparison success claim:
|
||||||
|
|
||||||
|
Mixed translation/rotation 검사는 fixed-reference characteristic length
|
||||||
|
`L=max(||X_I-X_J||)`와 node block `Dq=diag(L I3,I3)`를 사용한다. Tangent test direction은
|
||||||
|
`||p_hat||inf=1`, perturbation은 `q +/- h Dq p_hat`으로 두고
|
||||||
|
`h={1e-3,3e-4,1e-4,3e-5,1e-5,3e-6,1e-6,3e-7}` 전부를 검사한다. Roundoff plateau 전
|
||||||
|
최소 두 interval에서 centered-difference observed order `>=1.5`이고 한 interior point가
|
||||||
|
scaled error `<=1e-6`여야 한다. Single-`h` 우연 통과는 허용하지 않는다.
|
||||||
|
|
||||||
|
1. Linear limit: at stress-free `q=0`, nonlinear element residual/tangent/recovery reduce to approved linear MITC4 signs, `2 x 2 x 2` integration and physical/drill split.
|
||||||
|
2. Rotation state invariants: every committed/trial `Q` satisfies `||Q^T Q-I||_F <= 1e-12`,
|
||||||
|
`|det(Q)-1| <= 1e-12`, and `d=Q e3`. Global/swing/twist `pi` branch angular margin은
|
||||||
|
`sqrt(epsilon_double)`, 약 `1.4901161193847656e-8` rad보다 커야 한다.
|
||||||
|
3. Tangent directional derivative: compare `Dq^T K_T Dq p_hat` with the central
|
||||||
|
residual derivative under the schedule above in separated force and moment channels.
|
||||||
|
Zero analytical directions require exact-zero construction and scaled absolute error
|
||||||
|
`<=1e-10`; nonfinite metric은 허용하지 않는다.
|
||||||
|
4. No-moment tangent symmetry: after work-conjugate congruence `Dq^T K_T Dq`, no-applied-moment
|
||||||
|
tangent scaled Frobenius symmetry error `<=1e-12`; applied fixed-spatial moment cases are checked for
|
||||||
|
exact derivative consistency, not symmetry.
|
||||||
|
5. Finite rigid objectivity: superposed finite rigid motion leaves physical strain/stress,
|
||||||
|
physical energy, drill gamma/energy and internal residual at scaled `<=1e-10` levels.
|
||||||
|
6. Patch/sign recovery: membrane, bending, twist and transverse shear patch states preserve
|
||||||
|
component order and bottom/top stress signs.
|
||||||
|
Analytical strain/resultant/stress error is relative `<=1e-9`.
|
||||||
|
7. Load and boundary path: fixed-global force/moment source identity, `rho_M <= 1e-12`
|
||||||
|
rejection/projection, absolute factor-one boundary path and zero constrained Newton
|
||||||
|
correction are tested independently.
|
||||||
|
8. Newton lifecycle: factor identities use ordinal `j*h` values strictly below one,
|
||||||
|
followed by one exact assigned `1.0`; cumulative `lambda += h`와 tolerance-based duplicate
|
||||||
|
endpoint는 금지한다. For `shellNL` the expected intended factors are `0.1, 0.2, ...,
|
||||||
|
1.0`. Iterations are `1..100`, pass at `100` is allowed, iteration `101` is forbidden.
|
||||||
|
9. Convergence gates: NSNR-069/070 four-channel inclusive `<=` rules, typed zero-scale
|
||||||
|
`1e-3` thresholds and nonfinite rejection are tested without adding energy or line-search gates.
|
||||||
|
10. Commit/rollback and determinism: failed trial, recovery, solve or output does not mutate
|
||||||
|
the prior committed state or prior authoritative final result; row/diagnostic order is stable.
|
||||||
|
|
||||||
|
### Downstream reference comparisons
|
||||||
|
|
||||||
|
The required stored-reference cases and logical quantities are defined in
|
||||||
|
`docs/nonlinear-static-newton-raphson/reference-model.md`.
|
||||||
|
|
||||||
|
- `shellnl-s4-final` is the primary nonlinear external reference at accepted factor one.
|
||||||
|
- `shell-s4-linear-limit` is the read-only linear-limit/reference-identity regression for the
|
||||||
|
same S4 mesh. Current stress element-label ordering is inventoried without becoming a
|
||||||
|
comparison quantity.
|
||||||
|
|
||||||
|
External comparison uses only accepted-state quantities and `docs/TOLERANCE.md`. Missing,
|
||||||
|
extra, duplicate or nonfinite required rows fail before tolerance. The comparison result itself
|
||||||
|
is Implementation Agent ownership.
|
||||||
|
|
||||||
|
## 7. Required Revisions
|
||||||
|
|
||||||
|
### Formulation Agent
|
||||||
|
|
||||||
|
None before I/O Definition. The current formulation is numerically sufficient for the I/O
|
||||||
|
contract. Current source element/node SPOS/SNEG stress CSV에 맞추기 위한 extrapolation,
|
||||||
|
averaging 또는 새 recovery 의미는 추가하지 않는다.
|
||||||
|
|
||||||
|
### Research Agent
|
||||||
|
|
||||||
|
None before I/O Definition. Public large-response benchmarks and shell MMS remain useful future
|
||||||
|
evidence, but the current Stage 4 gate does not require another research pass.
|
||||||
|
|
||||||
|
### I/O Definition Agent
|
||||||
|
|
||||||
|
Define parser/semantic/HDF5/log projection for the logical quantities and row identities in
|
||||||
|
`reference-model.md`. Preserve the split between blocking internal nonlinear tests and external
|
||||||
|
stored reference comparison; do not claim Abaqus internal equivalence.
|
||||||
|
|
||||||
|
## 8. Downstream Handoff
|
||||||
|
|
||||||
|
For I/O Definition Agent through Coordinator:
|
||||||
|
|
||||||
|
- Use accepted factor-one frames only for external reference comparison; trial Newton states are
|
||||||
|
not reference quantities.
|
||||||
|
- Preserve required source identity: case, accepted state, instance, node label and component.
|
||||||
|
Stress artifact의 element/node/section identity와 stored element-label order는 read-only
|
||||||
|
inventory로 보존하되 FESA comparison row로 합성하지 않는다.
|
||||||
|
- Keep `U1/U2/U3` blocking and `UR1/UR2/UR3` warning-only. For `shellNL`, compare
|
||||||
|
constrained `RF1/RF2`, `RF3`, and spatial physical `RM1/RM2` in the separate blocking
|
||||||
|
families from `reference-model.md`. `RM3`와 stress는 comparison에서 제외한다.
|
||||||
|
- Apply `docs/TOLERANCE.md` exactly; do not add an independent absolute floor, row averaging,
|
||||||
|
source-order matching, or calibration gate.
|
||||||
|
- Treat `shellNL` as weak but valid nonlinear final-state reference evidence; require the
|
||||||
|
blocking internal tests above for tangent/objectivity/rollback/finite-rotation correctness.
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
# Nonlinear Static Newton-Raphson Reference Model
|
||||||
|
|
||||||
|
## 1. Metadata
|
||||||
|
|
||||||
|
- feature_id: `nonlinear-static-newton-raphson`
|
||||||
|
- source_requirements: `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- source_research: `docs/nonlinear-static-newton-raphson/research.md`
|
||||||
|
- source_formulation: `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- source_numerical_review: `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- status: `pass-for-io-definition`
|
||||||
|
- owner_agent: `numerical-review-agent`
|
||||||
|
- date: `2026-08-23`
|
||||||
|
- artifact_policy: `read-only-existing-files`
|
||||||
|
- tolerance_policy: `docs/TOLERANCE.md`
|
||||||
|
|
||||||
|
이 문서는 logical reference quantity, source identity, component matching, row precheck와
|
||||||
|
blocking/warning 분류만 정의한다. 최종 HDF5 dataset projection은 I/O Definition Agent 소유다.
|
||||||
|
|
||||||
|
## 2. Reference Acceptance Scope
|
||||||
|
|
||||||
|
Required scope는 두 stored case다.
|
||||||
|
|
||||||
|
- `shellnl-s4-final`: `nlgeom=YES` nonlinear static S4 final accepted state를 비교하는
|
||||||
|
primary external reference case.
|
||||||
|
- `shell-s4-linear-limit`: 같은 S4 mesh의 `nlgeom=NO` read-only linear-limit/reference-identity
|
||||||
|
regression case. 이 case는 nonlinear response evidence가 아니며, 현재 stress CSV의 element-label
|
||||||
|
ordering을 row-order matching으로 사용하지 않는다.
|
||||||
|
|
||||||
|
`shellNL`은 final-state reference comparison에는 충분하지만 weak nonlinear response다. Dominant
|
||||||
|
`U3`/stress 값이 linear case와 거의 같으므로 finite-rotation objectivity, consistent tangent,
|
||||||
|
commit/rollback과 convergence lifecycle은 `numerical-review.md`의 blocking internal tests로 검증한다.
|
||||||
|
|
||||||
|
## 3. Reference Case Inventory with exact input and required CSV paths
|
||||||
|
|
||||||
|
| case id | artifact role | required comparison artifact | exact path | observed status |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `shellnl-s4-final` | nonlinear input | yes | `reference/shellNL/shellNL.inp` | readable; S4, 49 nodes, 36 elements, `NLGEOM=YES` |
|
||||||
|
| `shellnl-s4-final` | displacement reference | yes | `reference/shellNL/shellNL displacements.csv` | 49 finite unique node rows; one factor-one Frame |
|
||||||
|
| `shellnl-s4-final` | reaction reference | yes | `reference/shellNL/shellNL reactions.csv` | 49 finite unique node rows; one factor-one Frame |
|
||||||
|
| `shellnl-s4-final` | stress review evidence | no | `reference/shellNL/shellNL stresses.csv` | 288 finite unique rows; element labels `1..36` in stored ascending blocks |
|
||||||
|
| `shell-s4-linear-limit` | linear control input | yes | `reference/shell/shell.inp` | readable; S4, 49 nodes, 36 elements, `NLGEOM=NO` |
|
||||||
|
| `shell-s4-linear-limit` | displacement reference | yes | `reference/shell/shell displacements.csv` | 49 finite unique node rows; no `Frame` column |
|
||||||
|
| `shell-s4-linear-limit` | reaction review evidence | no | `reference/shell/shell reactions.csv` | 49 finite unique node rows |
|
||||||
|
| `shell-s4-linear-limit` | stress review evidence | no | `reference/shell/shell stresses.csv` | 288 finite unique rows; element labels `1..36` in stored ascending blocks |
|
||||||
|
|
||||||
|
`required comparison artifact=no`인 파일도 이번 review에서 읽기 가능성, row identity,
|
||||||
|
finite values와 current ordering을 확인했다. 그러나 해당 파일은 missing-required-artifact
|
||||||
|
판정이나 tolerance family를 만들지 않는다.
|
||||||
|
|
||||||
|
두 `.inp`는 같은 node/element/connectivity, material/section, instance, boundary와 center-node
|
||||||
|
`CLOAD`를 사용한다. Text 차이는 heading identity, `NLGEOM=NO -> YES`, 그리고 `*STATIC`
|
||||||
|
data `1.,1.,1e-05,1. -> 0.1,1.,0.001,0.1`이다. 따라서 `shellNL`은 실제 nonlinear
|
||||||
|
selector와 승인된 fixed increment `0.1`을 갖지만, 두 deck 차이를 오직 `NLGEOM` 하나의
|
||||||
|
isolated effect라고 표현하지 않는다.
|
||||||
|
|
||||||
|
Read-only SHA-256 observations:
|
||||||
|
|
||||||
|
| path | SHA-256 |
|
||||||
|
| --- | --- |
|
||||||
|
| `reference/shellNL/shellNL.inp` | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
|
||||||
|
| `reference/shellNL/shellNL displacements.csv` | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
|
||||||
|
| `reference/shellNL/shellNL reactions.csv` | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
|
||||||
|
| `reference/shellNL/shellNL stresses.csv` | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
|
||||||
|
| `reference/shell/shell.inp` | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
|
||||||
|
| `reference/shell/shell displacements.csv` | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
|
||||||
|
| `reference/shell/shell reactions.csv` | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
|
||||||
|
| `reference/shell/shell stresses.csv` | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
|
||||||
|
|
||||||
|
## 4. Source Identity and Component Contract
|
||||||
|
|
||||||
|
### 4.1 Accepted-state identity
|
||||||
|
|
||||||
|
- Abaqus identifiers are case-insensitive semantic identities. Input spelling
|
||||||
|
`Part-1-1` and CSV spelling `PART-1-1` match as one instance while original text is
|
||||||
|
retained in artifacts and reports; no file or row is rewritten.
|
||||||
|
- `shellnl-s4-final` rows require exact CSV `Frame` value
|
||||||
|
`Increment 10: Step Time = 1.000`, mapped logically to the accepted factor-one state.
|
||||||
|
- `shell-s4-linear-limit` rows have no `Frame` column and map to the single final static state.
|
||||||
|
- Row order is never a matching identity. It may only be used for deterministic reporting after
|
||||||
|
source keys are matched.
|
||||||
|
|
||||||
|
### 4.2 Nodal displacement contract
|
||||||
|
|
||||||
|
Required mapping is `U-U1/U-U2/U-U3 -> U1/U2/U3` and
|
||||||
|
`UR-UR1/UR-UR2/UR-UR3 -> UR1/UR2/UR3`. U is global length; UR is the
|
||||||
|
dimensionless fixed-initial global rotation-vector output. Logical key is
|
||||||
|
|
||||||
|
```text
|
||||||
|
(case_id, accepted_state, canonical_instance_name, source_node_label, component)
|
||||||
|
```
|
||||||
|
|
||||||
|
Both cases require source node labels `1..49` exactly once. U components form one
|
||||||
|
blocking translation family and UR components form one warning-only rotation family,
|
||||||
|
preserving the project MITC4 classification.
|
||||||
|
|
||||||
|
### 4.3 Nonlinear reaction contract
|
||||||
|
|
||||||
|
Reaction comparison applies only to `shellnl-s4-final` and only to the input boundary
|
||||||
|
`Set-2` nodes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33
|
||||||
|
```
|
||||||
|
|
||||||
|
All six global components are constrained at these 24 nodes. Other CSV node rows remain
|
||||||
|
part of file/schema/finite inventory but are not numerical reaction rows: FESA free entries
|
||||||
|
are equilibrium residual evidence, not Abaqus free-node zero reactions.
|
||||||
|
|
||||||
|
| CSV components | logical quantity | FESA meaning | disposition |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `RF-RF1`, `RF-RF2` | fixed-initial shell-plane reaction force | constrained translational full residual, global force | blocking family |
|
||||||
|
| `RF-RF3` | fixed-initial transverse reaction force | constrained translational full residual, global force | blocking family |
|
||||||
|
| `RM-RM1`, `RM-RM2` | tangent-plane spatial reaction moment | `J_l(phi)^(-T)` conversion of the constrained generalized reaction, global force-length | blocking family |
|
||||||
|
| `RM-RM3` | director/drilling-axis reaction review value | stabilization-dependent; no physical external equivalence target | excluded |
|
||||||
|
|
||||||
|
In-plane and transverse force are distinct model-fixed logical projections and therefore
|
||||||
|
use distinct families. Raw generalized rotation-coordinate residual is not matched directly
|
||||||
|
to the CSV `RM` value.
|
||||||
|
|
||||||
|
### 4.4 Stress review identity and comparison exclusion
|
||||||
|
|
||||||
|
Stress rows have read-only identity
|
||||||
|
|
||||||
|
```text
|
||||||
|
(case_id, accepted_state, instance, element label,
|
||||||
|
element-corner node label, SPOS/SNEG section surface, component)
|
||||||
|
```
|
||||||
|
|
||||||
|
Every current element has its four connectivity nodes and one `SPOS` plus one `SNEG`
|
||||||
|
row per node. The files are ordered in contiguous ascending element-label blocks `1..36`;
|
||||||
|
this exact artifact order is retained and no node/surface secondary reorder is applied.
|
||||||
|
|
||||||
|
The identity is nevertheless not the approved FESA recovery location: FESA emits direct
|
||||||
|
`[S11,S22,S12]` at four midsurface Gauss locations and bottom/middle/top positions, without
|
||||||
|
nodal extrapolation or averaging, and does not emit `S33`. Consequently no stress column
|
||||||
|
forms a blocking or warning-only comparison family. Stress files remain optional read-only
|
||||||
|
review evidence only.
|
||||||
|
|
||||||
|
### 4.5 Comparison families
|
||||||
|
|
||||||
|
| family id | components and source set | row count | units / coordinates | disposition |
|
||||||
|
| --- | --- | ---: | --- | --- |
|
||||||
|
| `linear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | length / global | blocking regression |
|
||||||
|
| `linear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only |
|
||||||
|
| `nonlinear.translation` | `U1,U2,U3`, nodes `1..49` | 147 | length / global | blocking |
|
||||||
|
| `nonlinear.rotation` | `UR1,UR2,UR3`, nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only |
|
||||||
|
| `nonlinear.reaction_inplane_force` | `RF1,RF2`, 24 constrained nodes | 48 | force / fixed-initial global plane | blocking |
|
||||||
|
| `nonlinear.reaction_transverse_force` | `RF3`, 24 constrained nodes | 24 | force / fixed-initial global transverse | blocking |
|
||||||
|
| `nonlinear.reaction_physical_moment` | `RM1,RM2`, 24 constrained nodes | 48 | force-length / global spatial | blocking |
|
||||||
|
|
||||||
|
## 5. Row Prechecks
|
||||||
|
|
||||||
|
Before tolerance, the comparator shall fail the affected comparison if any required condition
|
||||||
|
below is false.
|
||||||
|
|
||||||
|
1. Exact declared input path and every `required comparison artifact=yes` CSV path for the
|
||||||
|
case exist and are readable.
|
||||||
|
2. Required headers are present after trimming surrounding whitespace from header names.
|
||||||
|
3. `shellnl-s4-final` contains only the exact required `Frame` value for required rows.
|
||||||
|
4. Wide CSV rows expand to component rows using the component contract in Section 4.
|
||||||
|
5. Required source row keys are unique. Duplicate wide keys or duplicate expanded component keys fail.
|
||||||
|
6. Displacement projection requires all 49 source nodes and declared components. Nonlinear
|
||||||
|
reaction projection derives the exact 24-node/component set from the input constraint mask;
|
||||||
|
it does not infer reaction identity from CSV zero values.
|
||||||
|
7. FESA and reference required projected row-key sets are exactly equal: missing and extra rows
|
||||||
|
both fail.
|
||||||
|
8. Every required numeric value is finite. Nonfinite required FESA or CSV value fails before tolerance.
|
||||||
|
9. Optional stress inventory uses `(instance, element label, node label, section point)` and verifies
|
||||||
|
the current ascending element-label blocks, connectivity nodes and SPOS/SNEG pair. This inspection
|
||||||
|
does not create a stress equality gate.
|
||||||
|
10. Required rows are not omitted, synthesized, normalized, averaged, sorted into a different identity,
|
||||||
|
zero-clamped, or repaired.
|
||||||
|
|
||||||
|
Observed read-only inventory used for this contract:
|
||||||
|
|
||||||
|
| CSV | observed wide key columns | duplicate wide keys | nonfinite observed values | observed element labels |
|
||||||
|
| --- | --- | ---: | ---: | --- |
|
||||||
|
| `reference/shellNL/shellNL displacements.csv` | `Frame`, `Part Instance Name`, `Node Label` | 0 | 0 | N/A |
|
||||||
|
| `reference/shellNL/shellNL reactions.csv` | `Frame`, `Part Instance Name`, `Node Label` | 0 | 0 | N/A |
|
||||||
|
| `reference/shellNL/shellNL stresses.csv` | `Frame`, `Part Instance Name`, `Element Label`, `Node Label`, `Section Point` | 0 | 0 | `1..36` |
|
||||||
|
| `reference/shell/shell displacements.csv` | `Part Instance Name`, `Node Label` | 0 | 0 | N/A |
|
||||||
|
| `reference/shell/shell reactions.csv` | `Part Instance Name`, `Node Label` | 0 | 0 | N/A |
|
||||||
|
| `reference/shell/shell stresses.csv` | `Part Instance Name`, `Element Label`, `Node Label`, `Section Point` | 0 | 0 | `1..36` |
|
||||||
|
|
||||||
|
## 6. Tolerance and Blocking/Warning Policy
|
||||||
|
|
||||||
|
Use exactly `docs/TOLERANCE.md` for every external reference family. This report does not invent
|
||||||
|
or calibrate tolerance values.
|
||||||
|
|
||||||
|
For each comparison family:
|
||||||
|
|
||||||
|
- `S = max(abs(reference_value_i))`, using reference values only.
|
||||||
|
- near-zero band is `0.01*S`.
|
||||||
|
- if `abs(reference_value_i) <= 0.01*S`, row passes iff `abs(fesa-reference) <= 0.01*S`.
|
||||||
|
- otherwise row passes iff relative error `<= 0.05`.
|
||||||
|
- family relative RMS is `RMS(error)/S <= 0.01`.
|
||||||
|
- no independent absolute-error floor, `max(1, S)` clamp, row omission, averaging, or zero clamp is allowed.
|
||||||
|
- if `S = 0`, the family passes only when all FESA values are exactly zero; otherwise report
|
||||||
|
`zero-reference-scale-nonzero-error`.
|
||||||
|
|
||||||
|
Families are separated by the exact case/logical quantities in Section 4.5. Current
|
||||||
|
reference-only scales provide a reproducible reader/comparator audit:
|
||||||
|
|
||||||
|
| family | `S` | `B=0.01*S` |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| `linear.translation` | `2.37408203e-5` | `2.37408203e-7` |
|
||||||
|
| `linear.rotation` | `7.60725743e-6` | `7.60725743e-8` |
|
||||||
|
| `nonlinear.translation` | `2.37408203e-5` | `2.37408203e-7` |
|
||||||
|
| `nonlinear.rotation` | `7.60725743e-6` | `7.60725743e-8` |
|
||||||
|
| `nonlinear.reaction_inplane_force` | `1.91663182` | `1.91663182e-2` |
|
||||||
|
| `nonlinear.reaction_transverse_force` | `1.17769805e4` | `1.17769805e2` |
|
||||||
|
| `nonlinear.reaction_physical_moment` | `1.95418418e4` | `1.95418418e2` |
|
||||||
|
|
||||||
|
Any `blocking` family row or RMS failure fails the reference comparison for the feature.
|
||||||
|
`warning-only` failures produce deterministic warning evidence but do not change the blocking
|
||||||
|
verdict. `RM3` and stress artifacts create neither a blocking nor warning-only tolerance family.
|
||||||
|
|
||||||
|
## 7. Open Issues and I/O Handoff
|
||||||
|
|
||||||
|
Open issues blocking I/O Definition: 없음.
|
||||||
|
|
||||||
|
I/O Definition Agent handoff:
|
||||||
|
|
||||||
|
- Project only the comparison quantities in Sections 4.2, 4.3 and 4.5 to authoritative FESA
|
||||||
|
result datasets without changing source identity or final comparison disposition.
|
||||||
|
- Preserve `Frame` handling for `shellnl-s4-final` as accepted factor-one state identity; do not expose
|
||||||
|
trial Newton history as reference rows.
|
||||||
|
- Derive constrained reaction identity from the input mask. Compare `RM1/RM2` with the global
|
||||||
|
spatial physical reaction moment, not the raw generalized rotation-coordinate covector.
|
||||||
|
- Preserve approved Gauss direct stress recovery. Do not create element-corner stress,
|
||||||
|
extrapolation, averaging or a stress CSV projection for the current optional SPOS/SNEG artifacts.
|
||||||
|
- Keep `RM3`, `S-S33`, `S-S11`, `S-S22` and `S-S12` out of current comparison families.
|
||||||
|
- Use the common tolerance policy exactly as written above and in `docs/TOLERANCE.md`.
|
||||||
|
|
||||||
|
Reference artifact status: complete for I/O Definition. No declared required input or required
|
||||||
|
comparison CSV is missing or unreadable. Optional stress CSVs are present and readable as inventory
|
||||||
|
evidence only. No reference artifact was generated, renamed, repaired, normalized, or modified.
|
||||||
@@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
namespace fesa {
|
namespace fesa {
|
||||||
|
|
||||||
/// @brief Carries input and authoritative output paths for one analysis run.
|
/// @brief Carries input, authoritative output, and diagnostic-log paths.
|
||||||
struct AnalysisRequest {
|
struct AnalysisRequest {
|
||||||
std::filesystem::path input_path;
|
std::filesystem::path input_path;
|
||||||
std::filesystem::path output_path;
|
std::filesystem::path output_path;
|
||||||
|
std::filesystem::path log_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Defines the minimal execution contract shared by analysis procedures.
|
/// @brief Defines the minimal execution contract shared by analysis procedures.
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ namespace fesa {
|
|||||||
/// @brief Owns the argv-independent CLI contract and stable process exit codes.
|
/// @brief Owns the argv-independent CLI contract and stable process exit codes.
|
||||||
class FesaApplication {
|
class FesaApplication {
|
||||||
public:
|
public:
|
||||||
/// @brief Runs one solver invocation from operands and options after argv[0].
|
/// @brief Runs one solver invocation from arguments after argv[0].
|
||||||
/// @param arguments Input path and optional `--output` pair.
|
/// @param arguments One input path with no unsupported option token.
|
||||||
/// @return The stable CLI exit code for usage, input, model, solver, or
|
/// @return The stable CLI exit code for usage, input, model, solver, or
|
||||||
/// output status.
|
/// output status.
|
||||||
int Run(const std::vector<std::string>& arguments);
|
int Run(const std::vector<std::string>& arguments);
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef FESA_APP_OUTPUT_PATHS_H_
|
||||||
|
#define FESA_APP_OUTPUT_PATHS_H_
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fesa/core/status.h"
|
||||||
|
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
/// @brief Names the input and user-addressed output files for one invocation.
|
||||||
|
struct DerivedOutputPaths {
|
||||||
|
std::filesystem::path input_path;
|
||||||
|
std::filesystem::path results_path;
|
||||||
|
std::filesystem::path log_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Retains exclusive ownership of one derived output pair.
|
||||||
|
/// @note The lease owns a platform-private lock and must outlive output I/O.
|
||||||
|
class OutputWriteLease {
|
||||||
|
public:
|
||||||
|
OutputWriteLease(const OutputWriteLease&) = delete;
|
||||||
|
OutputWriteLease& operator=(const OutputWriteLease&) = delete;
|
||||||
|
OutputWriteLease(OutputWriteLease&&) noexcept;
|
||||||
|
OutputWriteLease& operator=(OutputWriteLease&&) noexcept;
|
||||||
|
~OutputWriteLease();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
|
||||||
|
friend Result<OutputWriteLease> AcquireOutputWriteLease(
|
||||||
|
const DerivedOutputPaths& paths);
|
||||||
|
|
||||||
|
explicit OutputWriteLease(std::unique_ptr<Impl> impl) noexcept;
|
||||||
|
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Validates CLI operands and derives lexical sibling output paths.
|
||||||
|
/// @param arguments Arguments after argv[0].
|
||||||
|
/// @param invocation_cwd Lexical base for a relative input path.
|
||||||
|
/// @return The input/result/log path triplet or a usage failure.
|
||||||
|
/// @note This function does not resolve symlinks, junctions, or short names.
|
||||||
|
Result<DerivedOutputPaths> DeriveSingleInputOutputPaths(
|
||||||
|
const std::vector<std::string>& arguments,
|
||||||
|
const std::filesystem::path& invocation_cwd);
|
||||||
|
|
||||||
|
/// @brief Acquires exclusive ownership for writes to one output pair.
|
||||||
|
/// @return A move-only lease or an output-busy failure.
|
||||||
|
/// @note The lease does not create, truncate, or replace public output files.
|
||||||
|
Result<OutputWriteLease> AcquireOutputWriteLease(
|
||||||
|
const DerivedOutputPaths& paths);
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
|
||||||
|
#endif // FESA_APP_OUTPUT_PATHS_H_
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
"dir": "cpp-object-oriented-modular-refactoring",
|
"dir": "cpp-object-oriented-modular-refactoring",
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"completed_at": "2026-08-16T13:54:51+0900"
|
"completed_at": "2026-08-16T13:54:51+0900"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"dir": "nonlinear-static-newton-raphson",
|
||||||
|
"status": "pending"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
# Step 0: cli-output-lease-and-derived-names
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/SOLVER_AGENT_DESIGN.md`
|
||||||
|
- `docs/HARNESS.md`
|
||||||
|
- `docs/HARNESS_WORKFLOW.md`
|
||||||
|
- `.codex/hooks.json`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `src/fesa/app/fesa_application.cpp`
|
||||||
|
- `include/fesa/app/fesa_application.h`
|
||||||
|
- `include/fesa/analysis/analysis.h`
|
||||||
|
- `tests/integration/app/fesa_application_test.cpp`
|
||||||
|
- `src/fesa/CMakeLists.txt`
|
||||||
|
- `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
없음. 이 Step은 app/CLI output lifecycle의 첫 변경이다.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/app/output_paths.h`
|
||||||
|
- Create: `src/fesa/app/output_paths.cpp`
|
||||||
|
- Create: `tests/unit/app/output_paths_test.cpp`
|
||||||
|
- Modify: `include/fesa/analysis/analysis.h`
|
||||||
|
- Modify: `include/fesa/app/fesa_application.h`
|
||||||
|
- Modify: `src/fesa/app/fesa_application.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
- Test: `tests/integration/app/fesa_application_test.cpp`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct DerivedOutputPaths {
|
||||||
|
std::filesystem::path input_path;
|
||||||
|
std::filesystem::path results_path;
|
||||||
|
std::filesystem::path log_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OutputWriteLease {
|
||||||
|
public:
|
||||||
|
OutputWriteLease(const OutputWriteLease&) = delete;
|
||||||
|
OutputWriteLease& operator=(const OutputWriteLease&) = delete;
|
||||||
|
OutputWriteLease(OutputWriteLease&&) noexcept;
|
||||||
|
OutputWriteLease& operator=(OutputWriteLease&&) noexcept;
|
||||||
|
~OutputWriteLease();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
friend Result<OutputWriteLease> AcquireOutputWriteLease(
|
||||||
|
const DerivedOutputPaths& paths);
|
||||||
|
explicit OutputWriteLease(std::unique_ptr<Impl> impl) noexcept;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<DerivedOutputPaths> DeriveSingleInputOutputPaths(
|
||||||
|
const std::vector<std::string>& arguments,
|
||||||
|
const std::filesystem::path& invocation_cwd);
|
||||||
|
|
||||||
|
Result<OutputWriteLease> AcquireOutputWriteLease(
|
||||||
|
const DerivedOutputPaths& paths);
|
||||||
|
|
||||||
|
struct AnalysisRequest {
|
||||||
|
std::filesystem::path input_path;
|
||||||
|
std::filesystem::path output_path;
|
||||||
|
std::filesystem::path log_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
`OutputWriteLease`는 acquisition-only private constructor와 private pimpl storage로 lock lifetime을 보존한다. Win32 handle, file handle, 또는 platform lock 표현은 `Impl` 안에만 둔다. `FesaApplication`은 lease를 log close와 HDF5 finalization이 끝날 때까지 보관한다.
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
테스트를 먼저 추가한다.
|
||||||
|
|
||||||
|
- `NSNR-CLI-001`: argv의 모든 token을 왼쪽에서 오른쪽으로 검사하고, case-sensitive substring `--output`을 포함한 첫 token에서 exit code `2`와 diagnostic code `cli-usage`가 하나만 출력된다.
|
||||||
|
- `NSNR-CLI-002`: `abc--outputdef`, `--output-path`, `--output=foo`, `--output` 모두 input path resolution 전에 실패한다.
|
||||||
|
- `NSNR-CLI-003`: `--output` 실패는 parser, Analysis construction, lease acquisition, log create/truncate, HDF5 candidate creation을 호출하지 않는다.
|
||||||
|
- `NSNR-CLI-004`: relative `.inp` path는 invocation CWD 기준으로 lexical normalization만 하고 `<stem>_results.h5`, `<stem>_log.txt`를 같은 directory에 만든다.
|
||||||
|
- `NSNR-CLI-005`: final extension `.inp`는 case-insensitive이고 stem은 마지막 extension만 제거하며 basename case와 preceding dots를 보존한다.
|
||||||
|
- `NSNR-CLI-006`: output-busy lease collision은 exit code `6`이며 log와 HDF5를 만들거나 바꾸지 않는다.
|
||||||
|
- `NSNR-CLI-007`: previous result/log files가 있는 상태에서 `--output` 실패 후 bytes와 timestamps가 변하지 않는다.
|
||||||
|
- `NSNR-CLI-008`: existing default `fesa.exe <model.inp>` invocation은 더 이상 cwd `results.h5`를 기본값으로 쓰지 않는다.
|
||||||
|
- `NSNR-CLI-009`: `AnalysisRequest`가 `input_path`, `output_path`, `log_path`를 함께 전달한다.
|
||||||
|
|
||||||
|
실행:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "FesaApplication|OutputPath" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
기대: 새 테스트가 컴파일 실패 또는 assertion 실패로 실패한다. 새 테스트가 예상 없이 통과하면 구현을 중단하고 Coordinator에게 보고한다.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
- `output_paths` module에 argv 검사, lexical path derivation, input extension validation, lease acquisition을 구현한다.
|
||||||
|
- `FesaApplication`은 `DeriveSingleInputOutputPaths` 성공 뒤 `AcquireOutputWriteLease`를 호출한다.
|
||||||
|
- 이 Step에서는 nonlinear procedure를 만들지 않는다.
|
||||||
|
- `LinearStaticAnalysis` 호출은 기존 방식대로 유지하되 `AnalysisRequest::output_path`가 `<stem>_results.h5`를 가리키게 한다.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
실행 전 `Test-Path .harness\config.json`으로 Harness config를 재확인한다. 있으면 그 설정을 우선한다. 없으면 다음 순서로 실행한다.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "FesaApplication|OutputPath" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Executor가 선택한 current Step 0만 `completed`, `error`, `blocked` 중 하나로 갱신한다. 성공 시 summary 한 줄만 기록한다. timestamp, retry, commit, advancement는 Executor 소유다.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- `--output` alias 또는 deprecation path를 남기지 마라. 이유: 승인된 public compatibility가 fail-closed removal이다.
|
||||||
|
- path를 symlink, junction, short-name, case-normalized realpath로 resolve하지 마라. 이유: io.md가 lexical user-addressed identity를 요구한다.
|
||||||
|
- log/HDF5 작업이 끝나기 전에 `OutputWriteLease`를 파기하지 마라. 이유: exclusive ownership 보장이 깨진다.
|
||||||
|
- nonlinear analysis 분기를 `LinearStaticAnalysis` private lifecycle에 넣지 마라. 이유: Step 10의 별도 prepared flow가 소유한다.
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# Step 1: nonlinear-static-domain-contract
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||||
|
- `include/fesa/model/model_types.h`
|
||||||
|
- `include/fesa/model/domain.h`
|
||||||
|
- `src/fesa/model/domain.cpp`
|
||||||
|
- `src/fesa/io/abaqus/step_definition_mapper.cpp`
|
||||||
|
- `src/fesa/io/abaqus/domain_mapping_context.h`
|
||||||
|
- `src/fesa/io/abaqus/domain_mapping_context.cpp`
|
||||||
|
- `tests/unit/model/model_types_test.cpp`
|
||||||
|
- `tests/unit/model/domain_test.cpp`
|
||||||
|
- `tests/unit/io/abaqus/domain_mapper_test.cpp`
|
||||||
|
- `tests/unit/io/abaqus/domain_mapping_components_test.cpp`
|
||||||
|
- Step 0 files: `include/fesa/app/output_paths.h`, `include/fesa/analysis/analysis.h`, `src/fesa/app/fesa_application.cpp`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 0이 app-level path/log request fields를 만들었고 기존 linear invocation이 `<stem>_results.h5`를 사용한다.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Modify: `include/fesa/model/model_types.h`
|
||||||
|
- Modify: `include/fesa/model/domain.h`
|
||||||
|
- Modify: `src/fesa/model/domain.cpp`
|
||||||
|
- Modify: `src/fesa/io/abaqus/step_definition_mapper.cpp`
|
||||||
|
- Modify: `src/fesa/io/abaqus/domain_mapping_context.h`
|
||||||
|
- Modify: `src/fesa/io/abaqus/domain_mapping_context.cpp`
|
||||||
|
- Test: `tests/unit/model/model_types_test.cpp`
|
||||||
|
- Test: `tests/unit/model/domain_test.cpp`
|
||||||
|
- Test: `tests/unit/io/abaqus/domain_mapper_test.cpp`
|
||||||
|
- Test: `tests/unit/io/abaqus/domain_mapping_components_test.cpp`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
enum class StaticProcedureKind {
|
||||||
|
kLinearSmallDisplacement,
|
||||||
|
kNonlinearFullNewton
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StaticStepDefinition {
|
||||||
|
std::string name;
|
||||||
|
std::vector<PrescribedDisplacementDefinition> boundaries;
|
||||||
|
std::vector<NodalLoad> loads;
|
||||||
|
StaticProcedureKind procedure_kind;
|
||||||
|
bool nlgeom;
|
||||||
|
double initial_increment;
|
||||||
|
double time_period;
|
||||||
|
double minimum_increment;
|
||||||
|
double maximum_increment;
|
||||||
|
SourceLocation location;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StepDefinition {
|
||||||
|
public:
|
||||||
|
StaticProcedureKind ProcedureKind() const noexcept;
|
||||||
|
bool IsNonlinearStatic() const noexcept;
|
||||||
|
double InitialIncrement() const noexcept;
|
||||||
|
double TimePeriod() const noexcept;
|
||||||
|
double MinimumIncrement() const noexcept;
|
||||||
|
double MaximumIncrement() const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
Domain stores procedure identity and raw four `*STATIC` values only. Factor sequence is derived in Step 5. PRESELECT output requests are warning no-ops and do not create Domain, Analysis, or HDF5 state.
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-IO-001`: `*STEP, NLGEOM=YES` maps to `StaticProcedureKind::kNonlinearFullNewton`.
|
||||||
|
- `NSNR-IO-002`: `*STEP, NLGEOM=NO` maps to `kLinearSmallDisplacement` and existing shell linear tests keep passing.
|
||||||
|
- `NSNR-IO-003`: missing `NLGEOM` keeps current linear behavior.
|
||||||
|
- `NSNR-IO-004`: nonlinear `*STATIC` requires four finite positive values and time period exactly `1.0`.
|
||||||
|
- `NSNR-IO-005`: raw values are preserved in `StepDefinition` without derived factor list.
|
||||||
|
- `NSNR-IO-006`: unsupported nonlinear procedure or mixed linear/nonlinear steps fail closed with `unsupported-analysis-procedure`.
|
||||||
|
- `NSNR-IO-007`: S4 and S4R shell definitions remain approved nonlinear semantic inputs.
|
||||||
|
- `NSNR-IO-008`: mixed B33/S4 nonlinear model fails with `unsupported-mixed-element-model`.
|
||||||
|
- `NSNR-IO-009`: `*OUTPUT, FIELD, VARIABLE=PRESELECT` is accepted with deterministic warning and no Domain state.
|
||||||
|
- `NSNR-IO-010`: `*OUTPUT, HISTORY, VARIABLE=PRESELECT` is accepted with deterministic warning and no Domain state.
|
||||||
|
- `NSNR-IO-011`: malformed PRESELECT parameters fail as input errors.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "Domain|DomainMapping|Abaqus" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops the Step.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
- Extend `StaticStepDefinition` and `StepDefinition` exactly with the fields and accessors above.
|
||||||
|
- Update domain construction so source-order boundaries and loads remain deterministic.
|
||||||
|
- Update `domain_mapping_context` to parse `NLGEOM=YES`, preserve raw `*STATIC`, emit PRESELECT warnings, and keep PRESELECT out of Domain state.
|
||||||
|
- Preserve existing linear shell and beam mappings.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "Domain|DomainMapping|Abaqus" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before using these defaults.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Only Step 1 status and one-line summary/error/blocked payload may be updated by the Implementation Agent. Executor owns timestamps, commits, retry, and next Step selection.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not add `LoadFactorSequence()` to Domain. 이유: factor sequence ownership belongs to Step 5 control.
|
||||||
|
- Do not store PRESELECT flags in Domain or HDF5 state. 이유: approved I/O contract makes PRESELECT an ignored warning no-op.
|
||||||
|
- Do not alter requirements or I/O docs. 이유: upstream contracts are approved.
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
# Step 10: prepared-analysis-flow-and-full-procedure
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `include/fesa/analysis/analysis.h`
|
||||||
|
- `include/fesa/analysis/linear_static_analysis.h`
|
||||||
|
- `src/fesa/analysis/linear_static_analysis.cpp`
|
||||||
|
- `src/fesa/app/fesa_application.cpp`
|
||||||
|
- `include/fesa/io/hdf5/hdf5_results_writer.h`
|
||||||
|
- `include/fesa/results/results_writer.h`
|
||||||
|
- `include/fesa/results/nonlinear_results_writer.h`
|
||||||
|
- Step 0 files: `include/fesa/app/output_paths.h`, `src/fesa/app/output_paths.cpp`
|
||||||
|
- Step 1 files: `include/fesa/model/domain.h`, `src/fesa/io/abaqus/domain_mapping_context.cpp`
|
||||||
|
- Step 5 files: `include/fesa/analysis/nonlinear_static_control.h`
|
||||||
|
- Step 6 files: `include/fesa/solvers/linear/tangent_solver.h`
|
||||||
|
- Step 7 files: `include/fesa/analysis/newton_iteration_log.h`
|
||||||
|
- Step 8 files: `include/fesa/analysis/nonlinear_analysis_state.h`
|
||||||
|
- Step 9 files: `include/fesa/results/nonlinear_results_writer.h`, `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Steps 0-9 provide path/lease, Domain procedure identity, nonlinear element/control/solver/log/state, and nonlinear HDF5 writer.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/analysis/prepared_analysis.h`
|
||||||
|
- Create: `src/fesa/analysis/prepared_analysis.cpp`
|
||||||
|
- Create: `include/fesa/analysis/linear_static_procedure.h`
|
||||||
|
- Create: `src/fesa/analysis/linear_static_procedure.cpp`
|
||||||
|
- Create: `include/fesa/analysis/nonlinear_static_procedure.h`
|
||||||
|
- Create: `src/fesa/analysis/nonlinear_static_procedure.cpp`
|
||||||
|
- Modify: `include/fesa/analysis/linear_static_analysis.h`
|
||||||
|
- Modify: `src/fesa/analysis/linear_static_analysis.cpp`
|
||||||
|
- Modify: `src/fesa/app/fesa_application.cpp`
|
||||||
|
- Test: `tests/integration/analysis/linear_static_analysis_test.cpp`
|
||||||
|
- Create: `tests/integration/analysis/nonlinear_static_procedure_test.cpp`
|
||||||
|
- Test: `tests/integration/app/fesa_application_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct PreparedAnalysisInput {
|
||||||
|
Domain domain;
|
||||||
|
std::vector<Diagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<PreparedAnalysisInput> PrepareAnalysisInput(
|
||||||
|
const std::filesystem::path& input_path);
|
||||||
|
|
||||||
|
struct LinearStaticExecutionResult {
|
||||||
|
AnalysisState state;
|
||||||
|
std::vector<Diagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LinearStaticProcedureExecutor {
|
||||||
|
public:
|
||||||
|
LinearStaticProcedureExecutor(const ParallelFor& parallel_for,
|
||||||
|
LinearSolver& linear_solver);
|
||||||
|
Result<LinearStaticExecutionResult> Execute(const Domain& domain) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ParallelFor& parallel_for_;
|
||||||
|
LinearSolver& linear_solver_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearStaticExecutionResult {
|
||||||
|
NonlinearAnalysisState state;
|
||||||
|
std::vector<Diagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonlinearStaticProcedureExecutor {
|
||||||
|
public:
|
||||||
|
NonlinearStaticProcedureExecutor(const ParallelFor& parallel_for,
|
||||||
|
TangentSolver& tangent_solver);
|
||||||
|
Result<NonlinearStaticExecutionResult> Execute(
|
||||||
|
const Domain& domain, NewtonIterationLogWriter& log) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ParallelFor& parallel_for_;
|
||||||
|
TangentSolver& tangent_solver_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PreparedAnalysisOutcome =
|
||||||
|
std::variant<LinearStaticExecutionResult, NonlinearStaticExecutionResult>;
|
||||||
|
|
||||||
|
Result<PreparedAnalysisOutcome> ExecutePreparedAnalysis(
|
||||||
|
const Domain& domain,
|
||||||
|
LinearStaticProcedureExecutor& linear_executor,
|
||||||
|
NonlinearStaticProcedureExecutor& nonlinear_executor,
|
||||||
|
NewtonIterationLogWriter& log);
|
||||||
|
|
||||||
|
Status FinalizePreparedAnalysisResult(
|
||||||
|
const DerivedOutputPaths& paths,
|
||||||
|
const Domain& domain,
|
||||||
|
const PreparedAnalysisOutcome& outcome,
|
||||||
|
const std::vector<Diagnostic>& diagnostics,
|
||||||
|
ResultsWriter& linear_writer,
|
||||||
|
NonlinearResultsWriter& nonlinear_writer);
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-PROC-001`: app validates argv, derives paths, acquires `OutputWriteLease`, opens log, then parses/maps exactly once.
|
||||||
|
- `NSNR-PROC-002`: parse/map diagnostics are sorted and preserved in prepared input.
|
||||||
|
- `NSNR-PROC-003`: linear `NLGEOM=NO` run uses `LinearStaticProcedureExecutor` and preserves existing numerical/HDF5 meaning except output names and log lifecycle.
|
||||||
|
- `NSNR-PROC-004`: nonlinear `NLGEOM=YES` run uses `NonlinearStaticProcedureExecutor`.
|
||||||
|
- `NSNR-PROC-005`: linear executor receives injected `ParallelFor` and existing `LinearSolver`; nonlinear executor receives injected `ParallelFor` and `TangentSolver`.
|
||||||
|
- `NSNR-PROC-006`: app constructs and owns concrete `TbbParallelFor`, `MklPardisoSolver`, `MklPardisoTangentSolver`, `Hdf5ResultsWriter`, and `NonlinearHdf5ResultsWriter`.
|
||||||
|
- `NSNR-PROC-007`: procedure computation/recovery returns a validated outcome without opening HDF5.
|
||||||
|
- `NSNR-PROC-008`: app closes log successfully before calling injected linear or nonlinear writer.
|
||||||
|
- `NSNR-PROC-009`: log close failure blocks HDF5 candidate creation.
|
||||||
|
- `NSNR-PROC-010`: nonlinear executor builds `NonlinearStateBaselineInput` from Domain nodes in stable internal order, preserving each node's `EntityIndex` and full `SourceEntityId`, then constructs state through `NonlinearAnalysisState::Create(domain, dofs, baseline)` before the first increment; the factor-zero baseline is committed state only and is not an accepted frame.
|
||||||
|
- `NSNR-PROC-011`: nonlinear increment loop uses factors from Step 5 and iterations `1..100`.
|
||||||
|
- `NSNR-PROC-012`: each entered iteration performs fresh tangent factorization and solves `Kff * delta = -r_f`.
|
||||||
|
- `NSNR-PROC-013`: global external vector/tangent from Step 5 is assembled once and combined with approved signs `r = f_int - f_ext`, `K_T = K_int - K_ext`; the fixed-moment tangent is subtracted once and is never duplicated per incident element.
|
||||||
|
- `NSNR-PROC-014`: iteration 100 can accept if gates pass; failure at 100 emits `nonlinear-nonconvergence` with no retry.
|
||||||
|
- `NSNR-PROC-015`: nonfinite data, factorization failure, solve failure, invalid accepted state, and log failure map to approved diagnostics.
|
||||||
|
- `NSNR-PROC-016`: constrained correction is zero and reactions/free residuals come from full residual `r = f_int - f_ext`.
|
||||||
|
- `NSNR-PROC-017`: failed nonlinear run preserves prior final HDF5 according to output lifecycle.
|
||||||
|
- `NSNR-PROC-018`: deterministic repeat produces same sparse structure, nodal source-identity order, result row order, diagnostics, and log line ordering.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Refactor current parse/map and linear compute/recovery out of `LinearStaticAnalysis::Run()` into `PrepareAnalysisInput` and `LinearStaticProcedureExecutor`. Keep `LinearStaticAnalysis` as a compatibility wrapper that delegates through the new flow and does not contain nonlinear conditions. Implement `NonlinearStaticProcedureExecutor` in `nonlinear_static_procedure.*` using Steps 2-8, constructing state only through `NonlinearAnalysisState::Create(...)` with one baseline per Domain node in stable internal order, forming `r = f_int - f_ext` and `K_T = K_int - K_ext`, preserving `EntityIndex` plus full `SourceEntityId` into final writer inputs, and delaying all HDF5 work until `FinalizePreparedAnalysisResult`. The app owns concrete adapters and passes them through interfaces.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "LinearStaticAnalysis|NonlinearStaticProcedure|FesaApplication" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 10 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not parse/map twice. 이유: source identity, diagnostics, and Domain lifetime must be deterministic.
|
||||||
|
- Do not reconstruct nodal identity from source labels alone. 이유: labels can repeat across instances and HDF5/reference matching requires full `SourceEntityId`.
|
||||||
|
- Do not open HDF5 before log close succeeds. 이유: io.md requires log close success before HDF5 candidate open/write/final replace.
|
||||||
|
- Do not insert nonlinear branches into `LinearStaticAnalysis` private lifecycle. 이유: new procedure owns its own lifecycle.
|
||||||
|
- Do not replace final HDF5 on failed analysis, log failure, or HDF5 failure. 이유: asymmetric preservation contract requires prior valid final preservation.
|
||||||
|
- Do not construct MKL/TBB/HDF5 backends inside procedure executors. 이유: dependencies are injected so tests can observe lifecycle and no backend type crosses analysis/core public boundaries.
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
# Step 11: reference-comparison-gate
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/TOLERANCE.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `tests/reference/reference_tolerance_policy.h`
|
||||||
|
- `tests/reference/reference_tolerance_policy.cpp`
|
||||||
|
- `tests/reference/reference_comparison.h`
|
||||||
|
- `tests/reference/reference_comparison.cpp`
|
||||||
|
- `tests/reference/mitc4_reference_comparison.h`
|
||||||
|
- `tests/reference/mitc4_reference_comparison.cpp`
|
||||||
|
- Step 9 files: `include/fesa/results/nonlinear_results_writer.h`, `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h`
|
||||||
|
- Step 10 files: `include/fesa/analysis/prepared_analysis.h`, `src/fesa/app/fesa_application.cpp`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 10 runs copied input files through FESA and writes authoritative HDF5 outputs after log close.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `tests/reference/nonlinear_static_reference_comparison.h`
|
||||||
|
- Create: `tests/reference/nonlinear_static_reference_comparison.cpp`
|
||||||
|
- Create: `tests/reference/nonlinear_static_reference_cases_test.cpp`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa::test {
|
||||||
|
|
||||||
|
struct NonlinearReferenceCase {
|
||||||
|
std::string case_id;
|
||||||
|
std::filesystem::path original_input_path;
|
||||||
|
std::filesystem::path displacement_csv_path;
|
||||||
|
std::filesystem::path reaction_csv_path;
|
||||||
|
std::filesystem::path stress_inventory_path;
|
||||||
|
std::filesystem::path execution_directory;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ArtifactSnapshot {
|
||||||
|
std::filesystem::path path;
|
||||||
|
std::string sha256;
|
||||||
|
std::uintmax_t byte_size;
|
||||||
|
std::filesystem::file_time_type last_write_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class NonlinearReferenceDisposition {
|
||||||
|
kBlocking,
|
||||||
|
kWarningOnly,
|
||||||
|
kExcluded
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearReferenceRowKey {
|
||||||
|
std::string case_id;
|
||||||
|
std::string accepted_state;
|
||||||
|
std::string instance_name;
|
||||||
|
std::int64_t source_node_label;
|
||||||
|
std::string component;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearReferenceFamilyReport {
|
||||||
|
std::string family_identity;
|
||||||
|
std::vector<std::string> components;
|
||||||
|
NonlinearReferenceDisposition disposition;
|
||||||
|
std::size_t row_count;
|
||||||
|
ReferenceToleranceFamilyDecision tolerance;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GeneratedRunArtifacts {
|
||||||
|
std::filesystem::path copied_input_path;
|
||||||
|
std::filesystem::path generated_results_hdf5;
|
||||||
|
std::filesystem::path generated_log_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearReferenceComparisonReport {
|
||||||
|
std::string case_id;
|
||||||
|
std::filesystem::path original_input_path;
|
||||||
|
std::filesystem::path copied_input_path;
|
||||||
|
std::filesystem::path generated_results_hdf5;
|
||||||
|
std::filesystem::path generated_log_path;
|
||||||
|
std::vector<ArtifactSnapshot> pre_run_artifacts;
|
||||||
|
std::vector<ArtifactSnapshot> post_run_artifacts;
|
||||||
|
std::vector<NonlinearReferenceFamilyReport> families;
|
||||||
|
bool blocking_passed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class NonlinearReferenceClassification {
|
||||||
|
kPassed,
|
||||||
|
kFailed,
|
||||||
|
kWarningOnlyDifferences
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<std::vector<ArtifactSnapshot>> ArtifactCheck(
|
||||||
|
const NonlinearReferenceCase& reference_case);
|
||||||
|
Result<std::filesystem::path> CopyInputToExecutionDirectory(
|
||||||
|
const NonlinearReferenceCase& reference_case);
|
||||||
|
Result<GeneratedRunArtifacts> RunFesaApplicationOnCopiedInput(
|
||||||
|
const NonlinearReferenceCase& reference_case,
|
||||||
|
const std::filesystem::path& copied_input_path);
|
||||||
|
Result<NonlinearReferenceComparisonReport> CompareHdf5ToReferenceCsv(
|
||||||
|
const NonlinearReferenceCase& reference_case,
|
||||||
|
const std::filesystem::path& hdf5_results_path);
|
||||||
|
NonlinearReferenceClassification ClassifyReferenceComparison(
|
||||||
|
const NonlinearReferenceComparisonReport& report);
|
||||||
|
NonlinearReferenceComparisonReport BuildReferenceComparisonReport(
|
||||||
|
const NonlinearReferenceCase& reference_case,
|
||||||
|
const std::filesystem::path& hdf5_results_path);
|
||||||
|
|
||||||
|
} // namespace fesa::test
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-REF-001`: artifact check verifies exact pre-run SHA-256 for every declared input/CSV path.
|
||||||
|
- `NSNR-REF-002`: original `reference/shellNL/shellNL.inp` bytes are copied unchanged into a unique build-local temp case directory and only the copied `.inp` is passed to `FesaApplication`.
|
||||||
|
- `NSNR-REF-003`: original `reference/shell/shell.inp` bytes are copied unchanged into a unique build-local temp case directory and only the copied `.inp` is passed to `FesaApplication`.
|
||||||
|
- `NSNR-REF-004`: copied shellNL run produces copied-sibling `shellNL_results.h5` and `shellNL_log.txt`; copied shell run produces copied-sibling `shell_results.h5` and `shell_log.txt`.
|
||||||
|
- `NSNR-REF-005`: HDF5 source path identity matches the copied user-addressed input path, and source content identity matches the approved original input hash.
|
||||||
|
- `NSNR-REF-006`: exact post-run SHA-256, byte size, timestamp, and inventory for all original declared reference artifacts match pre-run snapshots.
|
||||||
|
- `NSNR-REF-007`: shellNL displacement/reaction rows require exact `Frame` value `Increment 10: Step Time = 1.000`.
|
||||||
|
- `NSNR-REF-008`: required CSV wide rows expand to unique `(case_id, accepted_state, instance, source_node_label, component)` keys.
|
||||||
|
- `NSNR-REF-009`: HDF5 rows and CSV rows reject missing, extra, duplicate, and nonfinite required rows before tolerance.
|
||||||
|
- `NSNR-REF-010`: `linear.translation` has 147 blocking rows.
|
||||||
|
- `NSNR-REF-011`: `linear.rotation` has 147 warning-only rows.
|
||||||
|
- `NSNR-REF-012`: `nonlinear.translation` has 147 blocking rows.
|
||||||
|
- `NSNR-REF-013`: `nonlinear.rotation` has 147 warning-only rows.
|
||||||
|
- `NSNR-REF-014`: shellNL constrained nodes select only labels `1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33`.
|
||||||
|
- `NSNR-REF-015`: `RF1/RF2` has 48 blocking rows, `RF3` has 24 blocking rows, and `RM1/RM2` has 48 blocking rows.
|
||||||
|
- `NSNR-REF-016`: `RM3` and stress quantities create no numeric comparison family.
|
||||||
|
- `NSNR-REF-017`: docs/TOLERANCE.md family policy is applied exactly and warning-only failures do not change blocking verdict.
|
||||||
|
- `NSNR-REF-018`: stress CSV files are hash-audited as nonblocking inventory artifacts and their schema/order is not a blocking verdict.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement `ARTIFACT CHECK -> COPY -> RUN -> COMPARE -> CLASSIFY -> REPORT` while preserving the required public gate wording `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` in reports. The runner never passes the original reference input path to `FesaApplication`; it copies input bytes unchanged into a unique build-local temp case directory, runs the copied `.inp`, consumes copied-sibling `_results.h5` and `_log.txt`, and compares HDF5 data to original read-only CSVs. Use exact declared paths and hashes:
|
||||||
|
|
||||||
|
| path | rows | SHA-256 |
|
||||||
|
| --- | ---: | --- |
|
||||||
|
| `reference/shellNL/shellNL.inp` | input | `4BF3ECB0F7F1E8462C573E993DBC97AC5D920C91CF6F23AD4C6891D77FFBADA2` |
|
||||||
|
| `reference/shellNL/shellNL displacements.csv` | 49 | `4E0F99CA9372B1ADF7FAF102F43BC0B887DC743FDEDA378E4342D2CF8E0C0786` |
|
||||||
|
| `reference/shellNL/shellNL reactions.csv` | 49 | `001CB1541A9E94424E5E650509D46BC8724970DF4DE47184D9DB09C7938AB069` |
|
||||||
|
| `reference/shellNL/shellNL stresses.csv` | 288 | `5500E5114B1C44887528E30CEC054A1EB0F68BE3F4B8CE81FA59FC74A881483F` |
|
||||||
|
| `reference/shell/shell.inp` | input | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` |
|
||||||
|
| `reference/shell/shell displacements.csv` | 49 | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` |
|
||||||
|
| `reference/shell/shell reactions.csv` | 49 | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` |
|
||||||
|
| `reference/shell/shell stresses.csv` | 288 | `2B75A5B0DEB045A283C9BB7E9B1153B79F7537FF487214BF4A23316B59B660A7` |
|
||||||
|
|
||||||
|
Use docs/TOLERANCE.md exactly: family scale `S=max(abs(reference))`, near-zero band `0.01*S`, non-near relative error `<=0.05`, family `RMS(error)/S<=0.01`, zero-scale exact zero only. Original reference directory inventory, bytes, timestamps, and hashes must be unchanged after the run.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference|ReferenceTolerance|Mitc4Reference" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 11 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not rewrite, rename, normalize, or repair `.inp` or CSV artifacts. 이유: reference artifacts are immutable external evidence.
|
||||||
|
- Do not run `FesaApplication` on original `reference/shellNL/shellNL.inp` or `reference/shell/shell.inp`. 이유: CLI derives sibling outputs and would mutate the reference directory.
|
||||||
|
- Do not compare `RM3`. 이유: approved contract excludes stabilization-dependent drilling reaction.
|
||||||
|
- Do not numerically compare stress CSV data. 이유: stress artifacts are nonblocking inventory only in this feature.
|
||||||
|
- Do not average, omit, synthesize, or row-order match reference rows. 이유: source/component identity prechecks are mandatory.
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# Step 12: execution-closure-and-evidence-docs
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/PRD.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/CODINGSTYLE.md`
|
||||||
|
- `docs/TOLERANCE.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `phases/nonlinear-static-newton-raphson/index.json`
|
||||||
|
- Step 0-11 modified source/test/CMake files
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Steps 0-11 have implemented and verified CLI lifecycle, Domain contract, nonlinear MITC4, controls, tangent solver, log, state, HDF5 schema v1, full prepared procedure, and reference comparison tests.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Modify: `docs/PRD.md`
|
||||||
|
- Modify: `docs/ARCHITECTURE.md`
|
||||||
|
- Modify: `docs/ADR.md`
|
||||||
|
- Create: `docs/nonlinear-static-newton-raphson/implementation-report.md`
|
||||||
|
- Create: `docs/nonlinear-static-newton-raphson/build-test.md`
|
||||||
|
- Create: `docs/nonlinear-static-newton-raphson/reference-comparison.md`
|
||||||
|
|
||||||
|
No C++ production file is owned by this Step.
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
Evidence documents must record actual observed outputs:
|
||||||
|
|
||||||
|
```text
|
||||||
|
implementation-report.md: RED/GREEN/VERIFY command log, Step summaries, diagnostics, implementation-owned decisions.
|
||||||
|
build-test.md: fresh configure/build/discovery/full CTest commands, exit codes, duration, stdout/stderr tail, warning audit, failure classification.
|
||||||
|
reference-comparison.md: exact artifact inventory, HDF5 paths, projection, row prechecks, tolerance, per-family decisions, classification, no-change assertion.
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Before writing evidence docs, run an evidence freshness audit by checking that the three evidence docs do not already contain current command outputs from this final Step.
|
||||||
|
|
||||||
|
- `NSNR-EVID-001`: missing or stale `implementation-report.md` is a failing precondition.
|
||||||
|
- `NSNR-EVID-002`: missing or stale `build-test.md` is a failing precondition.
|
||||||
|
- `NSNR-EVID-003`: missing or stale `reference-comparison.md` is a failing precondition.
|
||||||
|
- `NSNR-EVID-004`: PRD/ARCHITECTURE/ADR still contain directly superseded global CLI/procedure/output statements.
|
||||||
|
- `NSNR-EVID-005`: reference artifact pre-run SHA inventory must match Step 11 values.
|
||||||
|
|
||||||
|
Expected: evidence freshness audit fails before this Step writes docs. If it unexpectedly passes with current evidence already present, stop and report to Coordinator.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
- Run fresh MSVC x64 Debug configure/build/discovery/full CTest.
|
||||||
|
- Run focused nonlinear reference comparison repeat.
|
||||||
|
- Run deterministic repeat/reference checks required by Step 11.
|
||||||
|
- Run warning audit from build output.
|
||||||
|
- Run `git diff --check` and `git status --short`.
|
||||||
|
- Run reference artifact post-run SHA audit and compare to pre-run values.
|
||||||
|
- Update only directly superseded PRD/ARCHITECTURE/ADR statements for CLI removal, prepared linear/nonlinear procedure boundary, output naming, log lifecycle, and nonlinear HDF5 schema.
|
||||||
|
- Create the three Stage 6 evidence docs from actual command outputs only.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
Recheck `.harness/config.json`. If absent, use:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticReference" --output-on-failure
|
||||||
|
git diff --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Record command, exit code, duration, stdout/stderr tail, and failure classification for every command in the evidence docs.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 12 status and one-line payload. Executor owns timestamps, commits, retry, top-level phase completion, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not claim success before the commands above actually pass. 이유: Stage 6 evidence docs must be output-backed.
|
||||||
|
- Do not broadly rewrite global docs. 이유: Step 12 only synchronizes directly superseded CLI/procedure/output statements.
|
||||||
|
- Do not change reference artifact content. 이유: SHA pre/post immutability is part of the acceptance evidence.
|
||||||
|
- Do not run `scripts/execute.py` from this Step. 이유: Executor already owns Harness execution.
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# Step 2: finite-rotation-state
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||||
|
- `include/fesa/math/vector3.h`
|
||||||
|
- `include/fesa/math/matrix.h`
|
||||||
|
- `tests/unit/math/vector3_test.cpp`
|
||||||
|
- `tests/unit/math/matrix_test.cpp`
|
||||||
|
- Step 1 files: `include/fesa/model/model_types.h`, `include/fesa/model/domain.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 1 exposes nonlinear static semantic selection. This Step adds finite rotation math used by nonlinear MITC4 and state recovery.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/elements/finite_rotation.h`
|
||||||
|
- Create: `src/fesa/elements/finite_rotation.cpp`
|
||||||
|
- Create: `tests/unit/elements/finite_rotation_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct FiniteRotationState {
|
||||||
|
Vector3 phi;
|
||||||
|
Matrix q;
|
||||||
|
Vector3 director;
|
||||||
|
};
|
||||||
|
|
||||||
|
Matrix ExpSkew(const Vector3& phi);
|
||||||
|
Matrix LeftJacobianSO3(const Vector3& phi);
|
||||||
|
Matrix InverseTransposeLeftJacobianSO3(const Vector3& phi);
|
||||||
|
Result<FiniteRotationState> MakeFiniteRotationState(
|
||||||
|
const Vector3& phi, const Matrix& initial_frame);
|
||||||
|
Result<FiniteRotationState> ApplyGlobalRotationIncrement(
|
||||||
|
const FiniteRotationState& committed,
|
||||||
|
const Vector3& delta_phi,
|
||||||
|
const Matrix& initial_frame);
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-ROT-001`: zero `phi` returns `Q0` and `director=Q0*e3`.
|
||||||
|
- `NSNR-ROT-002`: finite `phi` satisfies `Q=exp(phi^)Q0`, `Q^T Q=I`, `det(Q)=1`, `director=Qe3`.
|
||||||
|
- `NSNR-ROT-003`: update uses `Q+ = exp((phi + delta_phi)^)Q0`.
|
||||||
|
- `NSNR-ROT-004`: principal branch margin `sqrt(epsilon_double)` rejects ambiguous rotations near `pi`.
|
||||||
|
- `NSNR-ROT-005`: `LeftJacobianSO3` and inverse-transpose are finite and derivative-consistent for small, medium, and near-branch-safe rotations.
|
||||||
|
- `NSNR-ROT-006`: nonfinite rotation components fail with `invalid-accepted-state` or the Step-introduced finite-rotation diagnostic.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "FiniteRotation" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: tests fail because the rotation module does not exist. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement the SO(3) helper functions with finite checks and principal-branch validation. Use existing FESA math types and keep MKL/vendor types out of public headers.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "FiniteRotation" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before using default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 2 status and summary/error/blocked payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not normalize invalid rotation matrices to make tests pass. 이유: invalid nonlinear state must fail closed.
|
||||||
|
- Do not add element residual or tangent code here. 이유: this Step owns only finite rotation state.
|
||||||
|
- Do not expose backend/vendor types. 이유: public solver core must remain backend-neutral.
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
# Step 3: nonlinear-mitc4-kinematics-and-recovery
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `include/fesa/elements/mitc4_shell.h`
|
||||||
|
- `src/fesa/elements/mitc4_shell.cpp`
|
||||||
|
- `tests/unit/elements/mitc4_shell_test.cpp`
|
||||||
|
- `include/fesa/model/shell_geometry.h`
|
||||||
|
- `src/fesa/model/shell_geometry.cpp`
|
||||||
|
- `include/fesa/model/model_types.h`
|
||||||
|
- `include/fesa/results/result_records.h`
|
||||||
|
- Step 2 files: `include/fesa/elements/finite_rotation.h`, `src/fesa/elements/finite_rotation.cpp`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 2 provides finite rotation state and SO(3) Jacobian helpers.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
- Create: `src/fesa/elements/nonlinear_mitc4_shell.cpp`
|
||||||
|
- Create: `tests/unit/elements/nonlinear_mitc4_shell_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct NonlinearMitc4TrialDofs {
|
||||||
|
std::array<Vector3, 4> displacement;
|
||||||
|
std::array<Vector3, 4> rotation_vector;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearMitc4RecoveryPoint {
|
||||||
|
ShellMidsurfaceLocation location;
|
||||||
|
std::array<double, 2> natural_coordinates;
|
||||||
|
Mitc4LocalFrame local_frame;
|
||||||
|
std::array<double, 8> generalized_strain;
|
||||||
|
std::array<double, 8> section_resultant;
|
||||||
|
std::array<ShellSectionStressRow, 3> stress;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearMitc4Recovery {
|
||||||
|
std::array<NonlinearMitc4RecoveryPoint, 4> gauss_points;
|
||||||
|
double physical_strain_energy;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonlinearMitc4Shell {
|
||||||
|
public:
|
||||||
|
static Result<NonlinearMitc4Shell> Create(
|
||||||
|
std::array<const Node*, 4> nodes,
|
||||||
|
std::array<ShellNodeInitialFrame, 4> initial_frames,
|
||||||
|
const ShellSection& section,
|
||||||
|
const LinearElasticMaterial& material);
|
||||||
|
|
||||||
|
Result<NonlinearMitc4Recovery> EvaluateKinematics(
|
||||||
|
const NonlinearMitc4TrialDofs& trial) const;
|
||||||
|
Result<NonlinearMitc4Recovery> RecoverState(
|
||||||
|
const NonlinearMitc4TrialDofs& trial) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-ELEM-KIN-001`: initial undeformed state produces zero generalized strain and zero material stress.
|
||||||
|
- `NSNR-ELEM-KIN-001A`: `NonlinearMitc4Shell::Create` requires exactly four `Node` pointers, four corresponding `ShellNodeInitialFrame` records, one `ShellSection`, and one `LinearElasticMaterial`; invalid or mismatched inputs fail closed.
|
||||||
|
- `NSNR-ELEM-KIN-002`: fixed-initial Total Lagrangian geometry uses initial midsurface and initial directors.
|
||||||
|
- `NSNR-ELEM-KIN-003`: current director interpolation for strain uses unnormalized interpolated director where formulation requires it.
|
||||||
|
- `NSNR-ELEM-KIN-004`: opposed or degenerate director state fails closed.
|
||||||
|
- `NSNR-ELEM-KIN-005`: small-rotation linear limit matches existing `Mitc4Shell` recovery within numerical-review tolerance.
|
||||||
|
- `NSNR-ELEM-KIN-006`: finite rigid translation/rotation produces objective zero physical strain/stress.
|
||||||
|
- `NSNR-ELEM-KIN-007`: recovery emits exactly four midsurface Gauss rows in `ShellMidsurfaceLocation` order; each row has generalized strain `[E11,E22,2E12,K11,K22,2K12,G13,G23]`, section resultant `[N11,N22,N12,M11,M22,M12,Q13,Q23]`, and stress positions `[BOTTOM,MIDDLE,TOP]` with components `[S11,S22,S12]`.
|
||||||
|
- `NSNR-ELEM-KIN-008`: recovery emits no S33, S13, S23 and no nodal extrapolated/corner/averaged stress.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: compile or test failure because nonlinear MITC4 files do not exist. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement nonlinear MITC4 creation, kinematics, and recovery using approved 2x2x2 integration, MITC4 edge-midpoint shear tying, initial shell frames, homogeneous isotropic materially linear response, fixed-size row shapes, and source-order recovery rows.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Shell|NonlinearMitc4Recovery" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 3 status and one-line result payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not change existing `Mitc4Shell` behavior. 이유: linear MITC4 reference regression must remain stable.
|
||||||
|
- Do not create stress quantities outside approved schema. 이유: I/O excludes S33/S13/S23 and nodal stress projections.
|
||||||
|
- Do not add residual/tangent solve logic here. 이유: Step 4 owns residual and tangent.
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# Step 4: nonlinear-mitc4-residual-and-tangent
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
- `src/fesa/elements/nonlinear_mitc4_shell.cpp`
|
||||||
|
- `tests/unit/elements/nonlinear_mitc4_shell_test.cpp`
|
||||||
|
- Step 2 files: `include/fesa/elements/finite_rotation.h`
|
||||||
|
- Step 3 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 3 provides nonlinear MITC4 creation, kinematics, and recovery rows.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Modify: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
- Modify: `src/fesa/elements/nonlinear_mitc4_shell.cpp`
|
||||||
|
- Create: `tests/unit/elements/nonlinear_mitc4_shell_tangent_test.cpp`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct NonlinearMitc4InternalEquilibrium {
|
||||||
|
Vector internal_residual;
|
||||||
|
Matrix internal_tangent;
|
||||||
|
Vector internal_force;
|
||||||
|
NonlinearMitc4Recovery recovery;
|
||||||
|
double physical_strain_energy;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<NonlinearMitc4InternalEquilibrium> EvaluateInternalResidualAndTangent(
|
||||||
|
const NonlinearMitc4Shell& element,
|
||||||
|
const NonlinearMitc4TrialDofs& trial);
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-ELEM-TAN-001`: residual and tangent are evaluated at the same trial state.
|
||||||
|
- `NSNR-ELEM-TAN-002`: directional derivative schedule uses `h={1e-3,3e-4,1e-4,3e-5,1e-5,3e-6,1e-6,3e-7}` and requires at least two observed orders `>=1.5`.
|
||||||
|
- `NSNR-ELEM-TAN-003`: one interior scaled derivative error is `<=1e-6`.
|
||||||
|
- `NSNR-ELEM-TAN-004`: zero analytical directions produce scaled absolute error `<=1e-10`.
|
||||||
|
- `NSNR-ELEM-TAN-005`: no-moment tangent satisfies scaled Frobenius symmetry `<=1e-12` after `Dq^T K_T Dq`.
|
||||||
|
- `NSNR-ELEM-TAN-006`: internal tangent contains no external fixed-load contribution; applying the same element to two incident-element load-sharing scenarios does not change internal residual/tangent.
|
||||||
|
- `NSNR-ELEM-TAN-007`: finite rigid motion keeps physical residual/objectivity invariants.
|
||||||
|
- `NSNR-ELEM-TAN-008`: patch/sign recovery identities pass relative `<=1e-9`.
|
||||||
|
- `NSNR-ELEM-TAN-009`: nonfinite trial/residual/tangent data fails closed.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement same-trial internal residual/tangent, exact rotation derivative terms through `J_l`, map Hessian terms, objective drilling contribution, and physical recovery in the element-local contract. External CLOAD vector and tangent are not element inputs and are assembled globally in Step 5.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearMitc4Residual|NonlinearMitc4Tangent|NonlinearMitc4Objectivity|NonlinearMitc4Patch" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 4 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not symmetrize the internal tangent as a cleanup step. 이유: derivative and symmetry tests must observe the mathematically assembled operator; Step 5 owns external moment tangent nonsymmetry.
|
||||||
|
- Do not add solver factorization in this Step. 이유: Step 6 owns tangent solver backend.
|
||||||
|
- Do not pass nodal CLOAD force or moment into each incident element. 이유: it duplicates source-node loads; Step 5 owns global-once external assembly.
|
||||||
|
- Do not claim Abaqus internal equivalence. 이유: FESA only uses Abaqus CSV as external numeric reference.
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
# Step 5: load-boundary-path-and-convergence-gates
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `include/fesa/core/diagnostic.h`
|
||||||
|
- `include/fesa/fem/dof_manager.h`
|
||||||
|
- `include/fesa/math/sparse_matrix.h`
|
||||||
|
- `include/fesa/math/vector3.h`
|
||||||
|
- Step 1 files: `include/fesa/model/domain.h`, `include/fesa/model/model_types.h`
|
||||||
|
- Step 4 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 1 stores raw nonlinear static values in Domain. Step 4 provides internal-only element residual/tangent. This Step owns global-once fixed CLOAD, absolute boundary path assembly, and the external contribution sign contract used by Step 10: `r = f_int - f_ext`, `K_T = K_int - K_ext`.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/analysis/nonlinear_static_control.h`
|
||||||
|
- Create: `src/fesa/analysis/nonlinear_static_control.cpp`
|
||||||
|
- Create: `tests/unit/analysis/nonlinear_static_control_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct LoadFactorIncrement {
|
||||||
|
std::uint32_t increment_index;
|
||||||
|
double load_factor;
|
||||||
|
bool is_factor_one;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class NewtonChannelUnit {
|
||||||
|
kForce,
|
||||||
|
kForceLength,
|
||||||
|
kLength,
|
||||||
|
kDimensionless
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr double kNewtonRelativeThreshold = 1.0e-2;
|
||||||
|
inline constexpr double kNewtonZeroScaleThreshold = 1.0e-3;
|
||||||
|
|
||||||
|
struct NewtonResidualChannelInput {
|
||||||
|
std::string identity;
|
||||||
|
Vector free_residual;
|
||||||
|
Vector free_internal;
|
||||||
|
Vector free_external;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonCorrectionChannelInput {
|
||||||
|
std::string identity;
|
||||||
|
Vector fresh_correction;
|
||||||
|
Vector current_increment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonConvergenceInput {
|
||||||
|
NewtonResidualChannelInput force_residual;
|
||||||
|
NewtonResidualChannelInput moment_residual;
|
||||||
|
NewtonCorrectionChannelInput translation_correction;
|
||||||
|
NewtonCorrectionChannelInput rotation_correction;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class NewtonConvergenceBranch {
|
||||||
|
kRelative,
|
||||||
|
kZeroScale
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonChannelDecision {
|
||||||
|
std::string identity;
|
||||||
|
double numerator_norm;
|
||||||
|
double denominator_scale;
|
||||||
|
NewtonConvergenceBranch branch;
|
||||||
|
double threshold;
|
||||||
|
NewtonChannelUnit threshold_unit;
|
||||||
|
bool passed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonConvergenceResult {
|
||||||
|
NewtonChannelDecision force_residual;
|
||||||
|
NewtonChannelDecision moment_residual;
|
||||||
|
NewtonChannelDecision translation_correction;
|
||||||
|
NewtonChannelDecision rotation_correction;
|
||||||
|
bool combined_passed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GlobalFixedLoadContribution {
|
||||||
|
Vector generalized_external_force;
|
||||||
|
SparseMatrix generalized_external_tangent;
|
||||||
|
std::vector<Diagnostic> diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<std::vector<LoadFactorIncrement>> BuildFixedLoadFactorSequence(
|
||||||
|
const StepDefinition& step);
|
||||||
|
Result<Vector> ApplyAbsolutePrescribedDisplacementTarget(
|
||||||
|
const StepDefinition& step, double load_factor);
|
||||||
|
Result<GlobalFixedLoadContribution> AssembleGlobalFixedLoadContribution(
|
||||||
|
const Domain& domain,
|
||||||
|
const DofManager& dofs,
|
||||||
|
const Vector& trial_generalized_coordinates,
|
||||||
|
double load_factor);
|
||||||
|
Status CheckMomentAdmissibility(const Vector3& director,
|
||||||
|
const Vector3& source_moment);
|
||||||
|
NewtonConvergenceResult EvaluateNewtonConvergence(
|
||||||
|
const NewtonConvergenceInput& input);
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-CTRL-001`: raw `initial_increment=0.1` and `time_period=1.0` produce factors `0.1..1.0`.
|
||||||
|
- `NSNR-CTRL-002`: final factor is assigned exact `1.0`, not accumulated past one.
|
||||||
|
- `NSNR-CTRL-003`: positive minimum/maximum values are accepted but not used for runtime stepping.
|
||||||
|
- `NSNR-CTRL-004`: nonzero `*BOUNDARY` value is absolute factor-one target from step-start committed state.
|
||||||
|
- `NSNR-CTRL-005`: constrained Newton correction remains exactly zero.
|
||||||
|
- `NSNR-CTRL-006`: `*CLOAD` force and moment directions remain fixed global dead loads and scale by factor.
|
||||||
|
- `NSNR-CTRL-007`: moment admissibility accepts `rho_M <= 1e-12` and rejects larger drilling-aligned moment.
|
||||||
|
- `NSNR-CTRL-008`: `AssembleGlobalFixedLoadContribution` contributes each aggregated source node load exactly once, independent of incident element count.
|
||||||
|
- `NSNR-CTRL-009`: source-order load rows produce deterministic global vector and tangent order.
|
||||||
|
- `NSNR-CTRL-010`: fixed-spatial moment projection and `J_l`/map-Hessian tangent terms pass directional derivative checks and may make `K_ext` nonsymmetric.
|
||||||
|
- `NSNR-CTRL-011`: global fixed-load assembly returns external quantities consumed with approved signs `r = f_int - f_ext` and `K_T = K_int - K_ext`; the fixed-moment tangent is subtracted once and is never duplicated per incident element.
|
||||||
|
- `NSNR-CTRL-012`: `NewtonConvergenceInput` has no caller-supplied threshold or unit fields; `EvaluateNewtonConvergence` owns exact immutable constants `kNewtonRelativeThreshold=1.0e-2` and `kNewtonZeroScaleThreshold=1.0e-3`.
|
||||||
|
- `NSNR-CTRL-013`: four convergence gates expose identity, `numerator_norm`, `denominator_scale`, branch, typed threshold, `threshold_unit`, pass, and combined pass.
|
||||||
|
- `NSNR-CTRL-014`: nonzero-denominator relative branches use threshold `1.0e-2` and threshold unit `kDimensionless` for all four channels.
|
||||||
|
- `NSNR-CTRL-015`: zero-scale branches use threshold `1.0e-3` with units `kForce`, `kForceLength`, `kLength`, and `kDimensionless` for residual force, residual moment, correction translation, and correction rotation respectively.
|
||||||
|
- `NSNR-CTRL-016`: empty free channels evaluate with `numerator_norm=0`, `denominator_scale=0`, branch `kZeroScale`, exact zero-scale threshold/unit, and pass.
|
||||||
|
- `NSNR-CTRL-017`: iteration numbering remains `1..100` with no iteration `101`.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement factor sequence derivation, load/BC scaling, global-once fixed-load external vector `f_ext` and external tangent `K_ext` assembly, moment admissibility, and typed convergence-channel evaluation. Residual denominator scale is derived from the provided free internal/external channel values, correction denominator scale from the provided current increment channel values, and zero-scale branches use only `kZeroScale`. Thresholds and threshold units are not caller inputs; `EvaluateNewtonConvergence` assigns the exact branch/channel constants from `requirements.md` and `io.md`. Return structured diagnostics for invalid nonlinear static data, unsupported drilling load, nonfinite Newton data, and nonconvergence readiness.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearStaticControl|NonlinearConvergence|NonlinearLoadBoundary" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 5 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not put factor sequence storage into Domain. 이유: control layer derives runtime factors.
|
||||||
|
- Do not implement cutback, line search, damping, or automatic growth. 이유: approved Full Newton path excludes them.
|
||||||
|
- Do not mutate source load vectors. 이유: fixed-global source identity must remain immutable.
|
||||||
|
- Do not distribute full source-node CLOAD into every incident element. 이유: this would multiply loads by incident element count and violate formulation §11.2.
|
||||||
|
- Do not emit convergence branch labels outside `relative` and `zero-scale`. 이유: io.md exposes exactly those two branches.
|
||||||
|
- Do not accept per-call convergence thresholds or units. 이유: NSNR-069/070 fix branch thresholds and typed units globally.
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
# Step 6: backend-neutral-tangent-solver
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/numerical-review.md`
|
||||||
|
- `include/fesa/solvers/linear/linear_solver.h`
|
||||||
|
- `include/fesa/solvers/linear/mkl_pardiso_solver.h`
|
||||||
|
- `src/fesa/solvers/linear/mkl_pardiso_solver.cpp`
|
||||||
|
- `tests/unit/solvers/linear/linear_solver_test.cpp`
|
||||||
|
- `tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp`
|
||||||
|
- Step 4 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 4 defines generally nonsymmetric nonlinear tangent matrices. Current SPD `MklPardisoSolver` must remain unchanged.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/solvers/linear/tangent_solver.h`
|
||||||
|
- Create: `include/fesa/solvers/linear/mkl_pardiso_tangent_solver.h`
|
||||||
|
- Create: `src/fesa/solvers/linear/mkl_pardiso_tangent_solver.cpp`
|
||||||
|
- Create: `tests/unit/solvers/linear/tangent_solver_test.cpp`
|
||||||
|
- Test: `tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
class TangentSolver {
|
||||||
|
public:
|
||||||
|
virtual ~TangentSolver() = default;
|
||||||
|
virtual Status FactorizeFresh(const SparseMatrix& matrix) = 0;
|
||||||
|
virtual Status SolveCorrection(const Vector& rhs,
|
||||||
|
Vector& correction) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MklPardisoTangentSolver final : public TangentSolver {
|
||||||
|
public:
|
||||||
|
MklPardisoTangentSolver();
|
||||||
|
~MklPardisoTangentSolver() override;
|
||||||
|
Status FactorizeFresh(const SparseMatrix& matrix) override;
|
||||||
|
Status SolveCorrection(const Vector& rhs, Vector& correction) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
The MKL tangent adapter uses unsymmetric PARDISO full CSR with `mtype=11`. Existing `MklPardisoSolver` keeps `mtype=2`, SPD symmetry validation, and upper-triangle copy unchanged.
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-SOLVER-001`: nonsymmetric 2x2 matrix factorizes and solves a known correction.
|
||||||
|
- `NSNR-SOLVER-002`: `0x0` matrix factorize/solve succeeds with zero-size vectors.
|
||||||
|
- `NSNR-SOLVER-003`: nonfinite matrix or RHS values fail without modifying output correction.
|
||||||
|
- `NSNR-SOLVER-004`: singular/factorization failure maps to deterministic solver diagnostic.
|
||||||
|
- `NSNR-SOLVER-005`: solve before successful factorization fails with solver diagnostic.
|
||||||
|
- `NSNR-SOLVER-006`: existing SPD `MklPardisoSolver` still rejects nonsymmetric public CSR and passes prior tests.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement backend-neutral tangent solver boundary and MKL full-CSR adapter. Factorization is fresh per call, releases previous backend state, validates dimensions and finite values, and translates PARDISO errors to FESA `Status`.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "TangentSolver|MklPardiso" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 6 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not modify SPD `MklPardisoSolver` behavior except tests proving it is unchanged. 이유: existing linear solver contract must remain stable.
|
||||||
|
- Do not symmetrize or regularize tangent matrices. 이유: approved tangent may be nonsymmetric and failures must surface.
|
||||||
|
- Do not expose MKL types in public headers. 이유: backend types remain behind solver boundaries.
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
# Step 7: newton-iteration-log-writer
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/implementation-plan.md`
|
||||||
|
- Step 0 files: `include/fesa/app/output_paths.h`, `src/fesa/app/output_paths.cpp`, `include/fesa/analysis/analysis.h`
|
||||||
|
- Step 5 files: `include/fesa/analysis/nonlinear_static_control.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 0 gives app-owned log path and lease lifetime. Step 5 defines convergence-channel data that log records consume.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/analysis/newton_iteration_log.h`
|
||||||
|
- Create: `src/fesa/analysis/newton_iteration_log.cpp`
|
||||||
|
- Create: `tests/unit/analysis/newton_iteration_log_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
enum class NewtonIterationStage {
|
||||||
|
kEntered,
|
||||||
|
kKinematicsEvaluated,
|
||||||
|
kInternalAssembled,
|
||||||
|
kExternalAssembled,
|
||||||
|
kSolvedCorrection,
|
||||||
|
kConvergenceEvaluated,
|
||||||
|
kAccepted,
|
||||||
|
kFailed
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonIterationFailure {
|
||||||
|
bool present;
|
||||||
|
NewtonIterationStage stage;
|
||||||
|
std::string diagnostic_code;
|
||||||
|
std::string reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NewtonIterationLogRecord {
|
||||||
|
std::string step_name;
|
||||||
|
std::uint32_t increment_index;
|
||||||
|
double load_factor;
|
||||||
|
std::uint32_t iteration;
|
||||||
|
NewtonIterationStage last_completed_stage;
|
||||||
|
NewtonIterationFailure failure;
|
||||||
|
std::string transition;
|
||||||
|
std::string outcome;
|
||||||
|
std::string diagnostic_code;
|
||||||
|
NewtonChannelDecision force_residual;
|
||||||
|
NewtonChannelDecision moment_residual;
|
||||||
|
NewtonChannelDecision translation_correction;
|
||||||
|
NewtonChannelDecision rotation_correction;
|
||||||
|
bool combined_passed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NewtonIterationLogWriter {
|
||||||
|
public:
|
||||||
|
Status Open(const std::filesystem::path& log_path);
|
||||||
|
Status Write(const NewtonIterationLogRecord& record);
|
||||||
|
Status Flush();
|
||||||
|
Status Close();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
The serializer, not callers, owns the exact 39 labels and fixed order from `io.md`. For evaluated convergence channels it serializes only `relative` or `zero-scale` branch labels from `NewtonConvergenceBranch`. For unevaluated typed fields it writes `not-evaluated(reason)` using `NewtonIterationFailure::reason`. Callers cannot inject arbitrary fields.
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-LOG-001`: a complete Newton iteration writes exactly one LF-terminated line.
|
||||||
|
- `NSNR-LOG-002`: line is UTF-8 without BOM, no header, no trailer.
|
||||||
|
- `NSNR-LOG-003`: line has exactly 39 TAB-separated `label=value` fields in approved order.
|
||||||
|
- `NSNR-LOG-004`: finite numeric values round-trip without locale dependence.
|
||||||
|
- `NSNR-LOG-005`: each convergence channel serializes identity, `numerator_norm`, `denominator_scale`, branch, threshold, `threshold_unit`, and pass from `NewtonChannelDecision`.
|
||||||
|
- `NSNR-LOG-006`: evaluated empty free-channel decisions serialize `numerator_norm=0`, `denominator_scale=0`, threshold `1.0e-3`, the channel-specific zero-scale `threshold_unit`, and branch `zero-scale`; no other branch label appears.
|
||||||
|
- `NSNR-LOG-007`: combined pass, transition, outcome, failure stage, and diagnostic code are serialized from explicit record fields.
|
||||||
|
- `NSNR-LOG-008`: early failure fields after the failed stage use `not-evaluated(reason)`.
|
||||||
|
- `NSNR-LOG-009`: embedded tab, LF, CR, and backslash are escaped deterministically.
|
||||||
|
- `NSNR-LOG-010`: write/flush/close failure returns `log-output-failure` and prevents success classification.
|
||||||
|
- `NSNR-LOG-011`: non-Newton controlled failure path can leave a zero-byte log owned by app lifecycle.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NewtonIterationLog" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement a small log writer with explicit open/write/flush/close state, serializer-owned 39-field order, deterministic escaping, finite numeric formatting, `relative`/`zero-scale` convergence branch mapping, typed `not-evaluated(reason)` substitution, and structured `Status` failures.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NewtonIterationLog" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 7 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not duplicate per-iteration log lines to stderr. 이유: approved log is file-only.
|
||||||
|
- Do not accept arbitrary caller-provided field vectors. 이유: io.md requires an exact fixed schema and order.
|
||||||
|
- Do not write HDF5 trial history. 이유: log is diagnostic and HDF5 stores accepted frames only.
|
||||||
|
- Do not continue after log write/flush/close failure. 이유: log failure blocks result commit.
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
# Step 8: nonlinear-state-commit-rollback
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `include/fesa/analysis/analysis_state.h`
|
||||||
|
- `src/fesa/analysis/analysis_state.cpp`
|
||||||
|
- `include/fesa/core/source_identity.h`
|
||||||
|
- `include/fesa/fem/dof_manager.h`
|
||||||
|
- `include/fesa/model/domain.h`
|
||||||
|
- `include/fesa/results/result_records.h`
|
||||||
|
- Step 3 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
- Step 4 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||||
|
- Step 5 files: `include/fesa/analysis/nonlinear_static_control.h`
|
||||||
|
- Step 6 files: `include/fesa/solvers/linear/tangent_solver.h`
|
||||||
|
- Step 7 files: `include/fesa/analysis/newton_iteration_log.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Steps 3-7 provide nonlinear element recovery, residual/tangent, controls, tangent solver, and Newton log record types.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/analysis/nonlinear_analysis_state.h`
|
||||||
|
- Create: `src/fesa/analysis/nonlinear_analysis_state.cpp`
|
||||||
|
- Create: `tests/unit/analysis/nonlinear_analysis_state_test.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
struct NonlinearNodeBaseline {
|
||||||
|
EntityIndex node_index;
|
||||||
|
SourceEntityId source_id;
|
||||||
|
std::array<std::array<double, 3>, 3> triad;
|
||||||
|
std::array<double, 3> director;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearStateBaselineInput {
|
||||||
|
std::vector<NonlinearNodeBaseline> node_baselines;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonlinearTrialState {
|
||||||
|
std::uint32_t increment_index;
|
||||||
|
double load_factor;
|
||||||
|
bool is_factor_zero_baseline;
|
||||||
|
std::vector<EntityIndex> nodal_internal_order;
|
||||||
|
std::vector<SourceEntityId> nodal_source_ids;
|
||||||
|
Vector generalized_coordinates;
|
||||||
|
Vector displacement;
|
||||||
|
Vector rotation_vector;
|
||||||
|
std::vector<std::array<std::array<double, 3>, 3>> nodal_triad;
|
||||||
|
std::vector<std::array<double, 3>> nodal_director;
|
||||||
|
Vector internal_force;
|
||||||
|
Vector external_force;
|
||||||
|
Vector residual;
|
||||||
|
Vector reaction;
|
||||||
|
std::vector<ShellResultRow> shell_results;
|
||||||
|
double physical_strain_energy;
|
||||||
|
std::array<double, 6> global_equilibrium;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AcceptedFrameState {
|
||||||
|
std::uint32_t frame_index;
|
||||||
|
std::uint32_t increment_index;
|
||||||
|
double load_factor;
|
||||||
|
std::uint32_t iteration_count;
|
||||||
|
bool is_factor_one;
|
||||||
|
std::vector<EntityIndex> nodal_internal_order;
|
||||||
|
std::vector<SourceEntityId> nodal_source_ids;
|
||||||
|
Vector generalized_coordinates;
|
||||||
|
Vector displacement;
|
||||||
|
Vector rotation_vector;
|
||||||
|
std::vector<std::array<std::array<double, 3>, 3>> nodal_triad;
|
||||||
|
std::vector<std::array<double, 3>> nodal_director;
|
||||||
|
Vector internal_force;
|
||||||
|
Vector external_force;
|
||||||
|
Vector residual;
|
||||||
|
Vector reaction;
|
||||||
|
std::vector<ShellResultRow> shell_results;
|
||||||
|
double physical_strain_energy;
|
||||||
|
std::array<double, 6> global_equilibrium;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonlinearAnalysisState {
|
||||||
|
public:
|
||||||
|
static Result<NonlinearAnalysisState> Create(
|
||||||
|
const Domain& domain,
|
||||||
|
const DofManager& dofs,
|
||||||
|
const NonlinearStateBaselineInput& baseline);
|
||||||
|
|
||||||
|
Result<NonlinearTrialState> BeginTrialFromCommitted() const;
|
||||||
|
Status CommitAcceptedFrame(const AcceptedFrameState& frame);
|
||||||
|
void DiscardTrial() noexcept;
|
||||||
|
const std::vector<AcceptedFrameState>& AcceptedFrames() const noexcept;
|
||||||
|
const NonlinearTrialState& CommittedState() const noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-STATE-000`: `NonlinearAnalysisState::Create` requires exactly one `NonlinearNodeBaseline` per `Domain.Nodes()` entry in stable internal order; each entry has `node_index` equal to its vector offset and `source_id` equal to `Domain.Nodes()[node_index].source_id`.
|
||||||
|
- `NSNR-STATE-001`: `NonlinearAnalysisState::Create` rejects missing, extra, duplicate, out-of-order, or instance-label mismatched node identities before any mutable state is produced.
|
||||||
|
- `NSNR-STATE-002`: `NonlinearAnalysisState::Create` validates node/DOF/frame inventory, sizes all vectors, preserves `nodal_internal_order` and `nodal_source_ids`, and creates a committed factor-zero baseline with `increment_index=0`, `load_factor=0.0`, `is_factor_zero_baseline=true`, and no accepted frames.
|
||||||
|
- `NSNR-STATE-003`: duplicate source labels across different instances remain distinct when `SourceEntityId::instance_name` differs.
|
||||||
|
- `NSNR-STATE-004`: trial state starts from committed state and can be discarded without mutation.
|
||||||
|
- `NSNR-STATE-005`: accepted frames are appended in stable accepted-factor order.
|
||||||
|
- `NSNR-STATE-006`: frame index is zero-based accepted-frame order; the factor-zero committed baseline is metadata/state only and is never appended as an accepted frame.
|
||||||
|
- `NSNR-STATE-007`: final frame at load factor `1.0` has `is_factor_one=true`.
|
||||||
|
- `NSNR-STATE-008`: residual and reaction are stored from full residual `r = f_int - f_ext`.
|
||||||
|
- `NSNR-STATE-009`: accepted frame owns generalized coordinates, displacement, rotation vector, per-node identity/order, per-node triad/director, internal/external/residual/reaction, stable `ShellResultRow` recovery, physical strain energy, and global equilibrium.
|
||||||
|
- `NSNR-STATE-010`: all accepted-frame vectors match node/DOF counts and all `ShellResultRow` rows are stable element/midsurface order.
|
||||||
|
- `NSNR-STATE-011`: commit validates finite values for every approved scalar and atomically rejects nonfinite frames with `invalid-accepted-state`.
|
||||||
|
- `NSNR-STATE-012`: failed trial preserves prior committed state.
|
||||||
|
- `NSNR-STATE-013`: no unapproved verification data is stored.
|
||||||
|
- `NSNR-STATE-014`: committed and accepted nodal identity vectors are preserved for Step 9 HDF5 node datasets and Step 11 HDF5-to-reference source mapping; source label alone is never used as identity.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement `NonlinearAnalysisState::Create` as the only construction seam for a valid nonlinear state. It uses `Domain`, `DofManager`, and `NonlinearStateBaselineInput` to require one baseline per Domain node in stable internal order, match both `EntityIndex` and full `SourceEntityId`, allocate zero generalized/displacement/rotation/internal/external/residual/reaction vectors, preserve nodal order/source identity for HDF5/reference mapping, install finite per-node triads/directors, and establish the committed factor-zero baseline without adding an accepted frame. Commit validates inventory, order, shape, identity, and finiteness before mutating committed state.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 8 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not put equation ids into Node or Element objects. 이유: `DofManager` owns equation numbering.
|
||||||
|
- Do not identify baseline nodes by source label alone. 이유: labels are not unique across instances and cannot support stable HDF5/reference mapping.
|
||||||
|
- Do not commit trial data before convergence gates pass. 이유: rollback/preservation contract depends on committed-state isolation.
|
||||||
|
- Do not expand existing `AnalysisState` for future nonlinear features. 이유: this Step owns only approved NSNR state.
|
||||||
|
- Do not store stress projections or verification data outside approved `ShellResultRow`, physical energy, and global equilibrium fields. 이유: schema v1 has a bounded accepted-state contract.
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# Step 9: nonlinear-hdf5-schema-v1-writer
|
||||||
|
|
||||||
|
## 읽어야 할 파일
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `docs/ARCHITECTURE.md`
|
||||||
|
- `docs/ADR.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||||
|
- `docs/nonlinear-static-newton-raphson/reference-model.md`
|
||||||
|
- `include/fesa/io/hdf5/hdf5_results_writer.h`
|
||||||
|
- `include/fesa/results/results_writer.h`
|
||||||
|
- `src/fesa/io/hdf5/hdf5_results_writer.cpp`
|
||||||
|
- `src/fesa/io/hdf5/hdf5_primitives.h`
|
||||||
|
- `src/fesa/io/hdf5/hdf5_primitives.cpp`
|
||||||
|
- `src/fesa/io/hdf5/hdf5_self_check.h`
|
||||||
|
- `src/fesa/io/hdf5/hdf5_self_check.cpp`
|
||||||
|
- `tests/unit/io/hdf5/hdf5_results_writer_test.cpp`
|
||||||
|
- Step 8 files: `include/fesa/analysis/nonlinear_analysis_state.h`
|
||||||
|
|
||||||
|
## 이전 Step 전제
|
||||||
|
|
||||||
|
Step 8 provides committed nonlinear accepted-frame state. Step 0 and Step 10 own the rule that log close succeeds before this writer is invoked.
|
||||||
|
|
||||||
|
## 소유 파일
|
||||||
|
|
||||||
|
- Create: `include/fesa/io/hdf5/nonlinear_hdf5_results_writer.h`
|
||||||
|
- Create: `src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp`
|
||||||
|
- Create: `include/fesa/results/nonlinear_results_writer.h`
|
||||||
|
- Create: `tests/unit/io/hdf5/nonlinear_hdf5_results_writer_test.cpp`
|
||||||
|
- Modify: `src/fesa/io/hdf5/hdf5_primitives.h`
|
||||||
|
- Modify: `src/fesa/io/hdf5/hdf5_primitives.cpp`
|
||||||
|
- Modify: `src/fesa/io/hdf5/hdf5_self_check.h`
|
||||||
|
- Modify: `src/fesa/io/hdf5/hdf5_self_check.cpp`
|
||||||
|
- Modify: `src/fesa/CMakeLists.txt`
|
||||||
|
- Modify: `tests/CMakeLists.txt`
|
||||||
|
|
||||||
|
## 인터페이스
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
namespace fesa {
|
||||||
|
|
||||||
|
class NonlinearResultsWriter {
|
||||||
|
public:
|
||||||
|
virtual ~NonlinearResultsWriter() = default;
|
||||||
|
virtual Status Write(const std::filesystem::path& output_path,
|
||||||
|
const Domain& domain,
|
||||||
|
const NonlinearAnalysisState& state,
|
||||||
|
const std::vector<Diagnostic>& diagnostics) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonlinearHdf5ResultsWriter final : public NonlinearResultsWriter {
|
||||||
|
public:
|
||||||
|
Status Write(const std::filesystem::path& output_path,
|
||||||
|
const Domain& domain,
|
||||||
|
const NonlinearAnalysisState& state,
|
||||||
|
const std::vector<Diagnostic>& diagnostics) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
|
```
|
||||||
|
|
||||||
|
## RED
|
||||||
|
|
||||||
|
Add tests first.
|
||||||
|
|
||||||
|
- `NSNR-HDF5-001`: `/metadata` has `schema_version=1`, `feature_id=nonlinear-static-newton-raphson`, and approved procedure/formulation/integration attributes.
|
||||||
|
- `NSNR-HDF5-002`: `/model/nodes`, `/model/elements`, shell section/material/frame/director/constraint datasets match I/O schema.
|
||||||
|
- `NSNR-HDF5-003`: `/steps/Step-1/accepted_frames` has one row per committed increment.
|
||||||
|
- `NSNR-HDF5-004`: final row has load factor `1.0` and `is_factor_one=1`.
|
||||||
|
- `NSNR-HDF5-005`: factor zero metadata exists and factor zero is not a frame.
|
||||||
|
- `NSNR-HDF5-006`: per-frame nodal displacement, triad, director, internal, external, residual, reaction datasets have approved shapes and column ordering.
|
||||||
|
- `NSNR-HDF5-007`: reaction rotational columns store `J_l(phi)^(-T)` spatial physical moment.
|
||||||
|
- `NSNR-HDF5-008`: element shell local frame, generalized strain, section resultant, stress datasets exist with approved shape and identity.
|
||||||
|
- `NSNR-HDF5-009`: `/global/energy` and `/global/equilibrium` exist for each accepted frame.
|
||||||
|
- `NSNR-HDF5-010`: no trial history dataset is written.
|
||||||
|
- `NSNR-HDF5-011`: HDF5 candidate failure preserves prior final file.
|
||||||
|
- `NSNR-HDF5-012`: writer consumes `std::vector<Diagnostic>` and writes deterministic diagnostics.
|
||||||
|
- `NSNR-HDF5-013`: `NonlinearHdf5ResultsWriter` implements backend-neutral `NonlinearResultsWriter`, and no HDF5 handle/type appears in analysis/core public headers.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: new tests fail. Unexpected pass stops.
|
||||||
|
|
||||||
|
## GREEN
|
||||||
|
|
||||||
|
Implement `include/fesa/results/nonlinear_results_writer.h` as the backend-neutral boundary and implement schema-v1 nonlinear HDF5 writer using existing HDF5 RAII/primitives/self-check style. Keep HDF5 and platform types private to `src/fesa/io/hdf5`.
|
||||||
|
|
||||||
|
## VERIFY
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug -R "NonlinearHdf5|Hdf5ResultsWriter" --output-on-failure
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
Recheck `.harness/config.json` before default commands.
|
||||||
|
|
||||||
|
## 상태 기록
|
||||||
|
|
||||||
|
Update only Step 9 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||||
|
|
||||||
|
## 금지사항
|
||||||
|
|
||||||
|
- Do not open, write, or replace HDF5 before log close succeeds. 이유: Step 10 app lifecycle enforces log-before-HDF5 finalization.
|
||||||
|
- Do not write compression, chunking, or trial history. 이유: io.md requires contiguous accepted-state storage.
|
||||||
|
- Do not make CSV an authoritative output. 이유: official solver output is HDF5.
|
||||||
|
- Do not include HDF5 headers from analysis/core public headers. 이유: output backend types stay behind writer interfaces.
|
||||||
+53
-2
@@ -66,8 +66,12 @@ class StepExecutor:
|
|||||||
"""Phase 디렉토리 안의 step들을 순차 실행하는 하네스."""
|
"""Phase 디렉토리 안의 step들을 순차 실행하는 하네스."""
|
||||||
|
|
||||||
MAX_RETRIES = 3
|
MAX_RETRIES = 3
|
||||||
|
CODEX_TIMEOUT_SECONDS = 1800
|
||||||
CODEX_SANDBOX_ENV = "FESA_HARNESS_CODEX_SANDBOX"
|
CODEX_SANDBOX_ENV = "FESA_HARNESS_CODEX_SANDBOX"
|
||||||
CODEX_SANDBOX_MODES = frozenset({"workspace-write", "danger-full-access"})
|
CODEX_SANDBOX_MODES = frozenset({"workspace-write", "danger-full-access"})
|
||||||
|
IMPLEMENTATION_AGENT_PROFILE = Path(
|
||||||
|
".codex/agents/implementation-agent.toml"
|
||||||
|
)
|
||||||
FEAT_MSG = "feat({phase}): step {num} - {name}"
|
FEAT_MSG = "feat({phase}): step {num} - {name}"
|
||||||
CHORE_MSG = "chore({phase}): step {num} output"
|
CHORE_MSG = "chore({phase}): step {num} output"
|
||||||
TZ = timezone(timedelta(hours=9))
|
TZ = timezone(timedelta(hours=9))
|
||||||
@@ -253,6 +257,35 @@ class StepExecutor:
|
|||||||
)
|
)
|
||||||
return mode
|
return mode
|
||||||
|
|
||||||
|
def _implementation_agent_settings(self) -> tuple[str, str]:
|
||||||
|
profile_path = Path(self._root) / self.IMPLEMENTATION_AGENT_PROFILE
|
||||||
|
try:
|
||||||
|
profile_lines = profile_path.read_text(encoding="utf-8").splitlines()
|
||||||
|
except OSError as exc:
|
||||||
|
raise CodexEnvironmentError(
|
||||||
|
f"Implementation Agent profile을 읽을 수 없습니다: {profile_path}"
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
settings = {}
|
||||||
|
for line in profile_lines:
|
||||||
|
key, separator, value = line.partition("=")
|
||||||
|
key = key.strip()
|
||||||
|
if separator and key in {"model", "model_reasoning_effort"}:
|
||||||
|
try:
|
||||||
|
settings[key] = json.loads(value.strip())
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
raise CodexEnvironmentError(
|
||||||
|
f"Implementation Agent profile의 {key} 값이 올바른 문자열이 아닙니다."
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
model = settings.get("model")
|
||||||
|
reasoning_effort = settings.get("model_reasoning_effort")
|
||||||
|
if not isinstance(model, str) or not isinstance(reasoning_effort, str):
|
||||||
|
raise CodexEnvironmentError(
|
||||||
|
"Implementation Agent profile에 model과 model_reasoning_effort 문자열이 필요합니다."
|
||||||
|
)
|
||||||
|
return model, reasoning_effort
|
||||||
|
|
||||||
def _invoke_codex(self, step: dict, preamble: str) -> dict:
|
def _invoke_codex(self, step: dict, preamble: str) -> dict:
|
||||||
step_num, step_name = step["step"], step["name"]
|
step_num, step_name = step["step"], step["name"]
|
||||||
step_file = self._phase_dir / f"step{step_num}.md"
|
step_file = self._phase_dir / f"step{step_num}.md"
|
||||||
@@ -262,12 +295,20 @@ class StepExecutor:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
prompt = preamble + step_file.read_text(encoding="utf-8")
|
prompt = preamble + step_file.read_text(encoding="utf-8")
|
||||||
|
sandbox_mode = self._codex_sandbox_mode()
|
||||||
|
model, reasoning_effort = self._implementation_agent_settings()
|
||||||
command = [
|
command = [
|
||||||
"codex",
|
"codex",
|
||||||
"exec",
|
"exec",
|
||||||
|
"--disable",
|
||||||
|
"unified_exec",
|
||||||
"--json",
|
"--json",
|
||||||
|
"--model",
|
||||||
|
model,
|
||||||
|
"--config",
|
||||||
|
f"model_reasoning_effort={json.dumps(reasoning_effort)}",
|
||||||
"--sandbox",
|
"--sandbox",
|
||||||
self._codex_sandbox_mode(),
|
sandbox_mode,
|
||||||
"--dangerously-bypass-hook-trust",
|
"--dangerously-bypass-hook-trust",
|
||||||
"--cd",
|
"--cd",
|
||||||
self._root,
|
self._root,
|
||||||
@@ -281,12 +322,22 @@ class StepExecutor:
|
|||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
timeout=1800,
|
timeout=self.CODEX_TIMEOUT_SECONDS,
|
||||||
)
|
)
|
||||||
except FileNotFoundError as exc:
|
except FileNotFoundError as exc:
|
||||||
raise CodexEnvironmentError(
|
raise CodexEnvironmentError(
|
||||||
"Codex CLI를 찾을 수 없습니다. codex를 설치하고 PATH를 확인하세요."
|
"Codex CLI를 찾을 수 없습니다. codex를 설치하고 PATH를 확인하세요."
|
||||||
) from exc
|
) from exc
|
||||||
|
except subprocess.TimeoutExpired as exc:
|
||||||
|
timeout_message = f"Codex timed out after {exc.timeout} seconds."
|
||||||
|
stderr = exc.stderr or ""
|
||||||
|
if stderr:
|
||||||
|
stderr = f"{timeout_message}\n{stderr}"
|
||||||
|
else:
|
||||||
|
stderr = timeout_message
|
||||||
|
result = subprocess.CompletedProcess(
|
||||||
|
command, 124, stdout=exc.stdout or "", stderr=stderr
|
||||||
|
)
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
print(f"\n WARN: Codex가 비정상 종료됨 (code {result.returncode})")
|
print(f"\n WARN: Codex가 비정상 종료됨 (code {result.returncode})")
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ add_library(
|
|||||||
analysis/analysis_state.cpp
|
analysis/analysis_state.cpp
|
||||||
analysis/linear_static_analysis.cpp
|
analysis/linear_static_analysis.cpp
|
||||||
app/fesa_application.cpp
|
app/fesa_application.cpp
|
||||||
|
app/output_paths.cpp
|
||||||
assembly/load_assembler.cpp
|
assembly/load_assembler.cpp
|
||||||
assembly/parallel_for.cpp
|
assembly/parallel_for.cpp
|
||||||
assembly/sparse_assembler.cpp
|
assembly/sparse_assembler.cpp
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "fesa/analysis/analysis.h"
|
#include "fesa/analysis/analysis.h"
|
||||||
#include "fesa/analysis/linear_static_analysis.h"
|
#include "fesa/analysis/linear_static_analysis.h"
|
||||||
|
#include "fesa/app/output_paths.h"
|
||||||
#include "fesa/assembly/parallel_for.h"
|
#include "fesa/assembly/parallel_for.h"
|
||||||
#include "fesa/core/diagnostic.h"
|
#include "fesa/core/diagnostic.h"
|
||||||
#include "fesa/io/hdf5/hdf5_results_writer.h"
|
#include "fesa/io/hdf5/hdf5_results_writer.h"
|
||||||
@@ -23,19 +24,6 @@ constexpr int kModelExitCode = 4;
|
|||||||
constexpr int kSolverExitCode = 5;
|
constexpr int kSolverExitCode = 5;
|
||||||
constexpr int kOutputExitCode = 6;
|
constexpr int kOutputExitCode = 6;
|
||||||
|
|
||||||
bool StartsWithOption(const std::string& argument) {
|
|
||||||
return !argument.empty() && argument.front() == '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
Diagnostic UsageDiagnostic() {
|
|
||||||
return {Severity::kError,
|
|
||||||
"cli-usage",
|
|
||||||
{{}, 0U},
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"Usage: fesa.exe <model.inp> [--output <results.h5>]."};
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* SeverityName(const Severity severity) {
|
const char* SeverityName(const Severity severity) {
|
||||||
return severity == Severity::kWarning ? "warning" : "error";
|
return severity == Severity::kWarning ? "warning" : "error";
|
||||||
}
|
}
|
||||||
@@ -72,23 +60,23 @@ int ExitCodeFor(const Status& status) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int FesaApplication::Run(const std::vector<std::string>& arguments) {
|
int FesaApplication::Run(const std::vector<std::string>& arguments) {
|
||||||
const bool default_output_form = arguments.size() == 1U &&
|
const auto paths = DeriveSingleInputOutputPaths(
|
||||||
!arguments[0U].empty() &&
|
arguments, std::filesystem::current_path());
|
||||||
!StartsWithOption(arguments[0U]);
|
if (!paths.HasValue()) {
|
||||||
const bool explicit_output_form =
|
WriteDiagnostics(paths.GetStatus().Diagnostics());
|
||||||
arguments.size() == 3U && !arguments[0U].empty() &&
|
|
||||||
!StartsWithOption(arguments[0U]) && arguments[1U] == "--output" &&
|
|
||||||
!arguments[2U].empty() && !StartsWithOption(arguments[2U]);
|
|
||||||
if (!default_output_form && !explicit_output_form) {
|
|
||||||
WriteDiagnostics({UsageDiagnostic()});
|
|
||||||
return kUsageExitCode;
|
return kUsageExitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto lease = AcquireOutputWriteLease(paths.Value());
|
||||||
|
if (!lease.HasValue()) {
|
||||||
|
WriteDiagnostics(lease.GetStatus().Diagnostics());
|
||||||
|
return kOutputExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
AnalysisRequest request;
|
AnalysisRequest request;
|
||||||
request.input_path = arguments[0U];
|
request.input_path = paths.Value().input_path;
|
||||||
request.output_path = explicit_output_form
|
request.output_path = paths.Value().results_path;
|
||||||
? std::filesystem::path{arguments[2U]}
|
request.log_path = paths.Value().log_path;
|
||||||
: std::filesystem::current_path() / "results.h5";
|
|
||||||
|
|
||||||
TbbParallelFor parallel_for;
|
TbbParallelFor parallel_for;
|
||||||
MklPardisoSolver linear_solver;
|
MklPardisoSolver linear_solver;
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
#include "fesa/app/output_paths.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "fesa/core/ascii.h"
|
||||||
|
|
||||||
|
namespace fesa {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
Status UsageFailure(const std::string& identity, const std::string& message) {
|
||||||
|
return Status::Failure(
|
||||||
|
FailureCategory::kInput,
|
||||||
|
{{Severity::kError, "cli-usage", {{}, 0U}, "", identity, message}});
|
||||||
|
}
|
||||||
|
|
||||||
|
Status OutputBusyFailure(const std::filesystem::path& results_path) {
|
||||||
|
return Status::Failure(
|
||||||
|
FailureCategory::kOutput,
|
||||||
|
{{Severity::kError,
|
||||||
|
"output-busy",
|
||||||
|
{{}, 0U},
|
||||||
|
"",
|
||||||
|
results_path.generic_u8string(),
|
||||||
|
"The derived output pair is already owned by another invocation."}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StartsWithOption(const std::string& argument) {
|
||||||
|
return !argument.empty() && argument.front() == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ArgumentIdentity(const std::size_t argument_index,
|
||||||
|
const std::string& argument) {
|
||||||
|
return "argument_index=" + std::to_string(argument_index) +
|
||||||
|
";argument=" + argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path LockPathFor(const DerivedOutputPaths& paths) {
|
||||||
|
std::filesystem::path lock_path = paths.results_path;
|
||||||
|
lock_path += ".fesa.lock";
|
||||||
|
return lock_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class OutputWriteLease::Impl {
|
||||||
|
public:
|
||||||
|
explicit Impl(const HANDLE handle) noexcept : handle_{handle} {}
|
||||||
|
|
||||||
|
Impl(const Impl&) = delete;
|
||||||
|
Impl& operator=(const Impl&) = delete;
|
||||||
|
|
||||||
|
~Impl() {
|
||||||
|
if (handle_ != INVALID_HANDLE_VALUE) {
|
||||||
|
(void)CloseHandle(handle_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
HANDLE handle_{INVALID_HANDLE_VALUE};
|
||||||
|
};
|
||||||
|
|
||||||
|
OutputWriteLease::OutputWriteLease(std::unique_ptr<Impl> impl) noexcept
|
||||||
|
: impl_{std::move(impl)} {}
|
||||||
|
|
||||||
|
OutputWriteLease::OutputWriteLease(OutputWriteLease&&) noexcept = default;
|
||||||
|
|
||||||
|
OutputWriteLease& OutputWriteLease::operator=(OutputWriteLease&&) noexcept =
|
||||||
|
default;
|
||||||
|
|
||||||
|
OutputWriteLease::~OutputWriteLease() = default;
|
||||||
|
|
||||||
|
Result<DerivedOutputPaths> DeriveSingleInputOutputPaths(
|
||||||
|
const std::vector<std::string>& arguments,
|
||||||
|
const std::filesystem::path& invocation_cwd) {
|
||||||
|
for (std::size_t index = 0U; index < arguments.size(); ++index) {
|
||||||
|
if (arguments[index].find("--output") != std::string::npos) {
|
||||||
|
return Result<DerivedOutputPaths>::Failure(UsageFailure(
|
||||||
|
ArgumentIdentity(index, arguments[index]),
|
||||||
|
"The --output option is not supported."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.size() != 1U || arguments.front().empty() ||
|
||||||
|
StartsWithOption(arguments.front())) {
|
||||||
|
return Result<DerivedOutputPaths>::Failure(
|
||||||
|
UsageFailure("", "Usage: fesa.exe <model.inp>."));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path input_path{arguments.front()};
|
||||||
|
if (input_path.is_relative()) {
|
||||||
|
input_path = invocation_cwd / input_path;
|
||||||
|
}
|
||||||
|
input_path = input_path.lexically_normal();
|
||||||
|
if (!AsciiCaseInsensitiveEquals(input_path.extension().string(), ".inp")) {
|
||||||
|
return Result<DerivedOutputPaths>::Failure(
|
||||||
|
UsageFailure(input_path.generic_u8string(),
|
||||||
|
"The input path must end in .inp."));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path stem = input_path.stem();
|
||||||
|
const std::filesystem::path output_directory = input_path.parent_path();
|
||||||
|
return Result<DerivedOutputPaths>::Success(
|
||||||
|
{input_path, output_directory / (stem.string() + "_results.h5"),
|
||||||
|
output_directory / (stem.string() + "_log.txt")});
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<OutputWriteLease> AcquireOutputWriteLease(
|
||||||
|
const DerivedOutputPaths& paths) {
|
||||||
|
const std::filesystem::path lock_path = LockPathFor(paths);
|
||||||
|
const HANDLE lock_handle = CreateFileW(
|
||||||
|
lock_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0U, nullptr, CREATE_NEW,
|
||||||
|
FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_DELETE_ON_CLOSE, nullptr);
|
||||||
|
if (lock_handle == INVALID_HANDLE_VALUE) {
|
||||||
|
return Result<OutputWriteLease>::Failure(
|
||||||
|
OutputBusyFailure(paths.results_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result<OutputWriteLease>::Success(
|
||||||
|
OutputWriteLease{std::make_unique<OutputWriteLease::Impl>(lock_handle)});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fesa
|
||||||
@@ -9,6 +9,7 @@ add_executable(
|
|||||||
unit/assembly/parallel_for_test.cpp
|
unit/assembly/parallel_for_test.cpp
|
||||||
unit/assembly/load_assembler_test.cpp
|
unit/assembly/load_assembler_test.cpp
|
||||||
unit/assembly/sparse_assembler_test.cpp
|
unit/assembly/sparse_assembler_test.cpp
|
||||||
|
unit/app/output_paths_test.cpp
|
||||||
unit/constraints/boundary_condition_test.cpp
|
unit/constraints/boundary_condition_test.cpp
|
||||||
unit/constraints/essential_constraints_test.cpp
|
unit/constraints/essential_constraints_test.cpp
|
||||||
unit/core/ascii_test.cpp
|
unit/core/ascii_test.cpp
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "fesa/app/fesa_application.h"
|
#include "fesa/app/fesa_application.h"
|
||||||
|
#include "fesa/app/output_paths.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <hdf5.h>
|
#include <hdf5.h>
|
||||||
|
|
||||||
@@ -9,6 +11,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -332,32 +335,37 @@ void ExpectDiagnosticFieldOrder(const std::string& text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> ExplicitOutputArguments(
|
struct FileSnapshot {
|
||||||
const std::filesystem::path& input, const std::filesystem::path& output) {
|
std::string contents;
|
||||||
// FesaApplication receives argv[0]-excluded operands and options.
|
std::filesystem::file_time_type write_time;
|
||||||
return {input.string(), "--output", output.string()};
|
};
|
||||||
|
|
||||||
|
FileSnapshot SnapshotFile(const std::filesystem::path& path) {
|
||||||
|
std::ifstream stream{path, std::ios::binary};
|
||||||
|
if (!stream) {
|
||||||
|
throw std::runtime_error{"Unable to open an app output fixture."};
|
||||||
|
}
|
||||||
|
return {{std::istreambuf_iterator<char>{stream},
|
||||||
|
std::istreambuf_iterator<char>{}},
|
||||||
|
std::filesystem::last_write_time(path)};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(LinearStaticCli, DefaultAndExplicitOutputProduceFesaHdf5) {
|
// NSNR-CLI-008: the application no longer uses a CWD-global results.h5.
|
||||||
|
TEST(LinearStaticCli, DefaultOutputUsesInputSiblingDerivedName) {
|
||||||
TempDirectory directory{"paths"};
|
TempDirectory directory{"paths"};
|
||||||
const auto input = directory.Path() / "model.inp";
|
const auto input = directory.Path() / "Beam.Model.INP";
|
||||||
WriteText(input, AxialDeck(true, false, false));
|
WriteText(input, AxialDeck(true, false, false));
|
||||||
|
|
||||||
const auto default_output = directory.Path() / "results.h5";
|
const auto default_output = directory.Path() / "Beam.Model_results.h5";
|
||||||
{
|
{
|
||||||
CurrentDirectoryGuard current_directory{directory.Path()};
|
CurrentDirectoryGuard current_directory{directory.Path()};
|
||||||
const auto result = RunApplication({input.string()});
|
const auto result = RunApplication({input.string()});
|
||||||
ASSERT_EQ(result.exit_code, 0) << result.standard_error;
|
ASSERT_EQ(result.exit_code, 0) << result.standard_error;
|
||||||
}
|
}
|
||||||
ExpectFesaHdf5Identity(default_output, input);
|
ExpectFesaHdf5Identity(default_output, input);
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(directory.Path() / "results.h5"));
|
||||||
const auto explicit_output = directory.Path() / "named-output.h5";
|
|
||||||
const auto result =
|
|
||||||
RunApplication(ExplicitOutputArguments(input, explicit_output));
|
|
||||||
ASSERT_EQ(result.exit_code, 0) << result.standard_error;
|
|
||||||
ExpectFesaHdf5Identity(explicit_output, input);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LinearStaticCli, ReturnsEveryExactExitCodeAndOrderedDiagnostic) {
|
TEST(LinearStaticCli, ReturnsEveryExactExitCodeAndOrderedDiagnostic) {
|
||||||
@@ -369,8 +377,7 @@ TEST(LinearStaticCli, ReturnsEveryExactExitCodeAndOrderedDiagnostic) {
|
|||||||
WriteText(model_input, AxialDeck(true, true, false));
|
WriteText(model_input, AxialDeck(true, true, false));
|
||||||
WriteText(solver_input, AxialDeck(false, false, false));
|
WriteText(solver_input, AxialDeck(false, false, false));
|
||||||
|
|
||||||
const auto success = RunApplication(
|
const auto success = RunApplication({valid_input.string()});
|
||||||
ExplicitOutputArguments(valid_input, directory.Path() / "success.h5"));
|
|
||||||
const auto usage = RunApplication({});
|
const auto usage = RunApplication({});
|
||||||
const auto missing_input = directory.Path() / "missing.inp";
|
const auto missing_input = directory.Path() / "missing.inp";
|
||||||
const auto input = RunApplication({missing_input.string()});
|
const auto input = RunApplication({missing_input.string()});
|
||||||
@@ -378,25 +385,19 @@ TEST(LinearStaticCli, ReturnsEveryExactExitCodeAndOrderedDiagnostic) {
|
|||||||
RunApplication({missing_input.string(), "--output", "--output"});
|
RunApplication({missing_input.string(), "--output", "--output"});
|
||||||
const auto unknown_output_option =
|
const auto unknown_output_option =
|
||||||
RunApplication({missing_input.string(), "--output", "--bogus"});
|
RunApplication({missing_input.string(), "--output", "--bogus"});
|
||||||
const auto model = RunApplication(ExplicitOutputArguments(
|
const auto model = RunApplication({model_input.string()});
|
||||||
model_input, directory.Path() / "model-failure.h5"));
|
const auto solver = RunApplication({solver_input.string()});
|
||||||
const auto solver = RunApplication(ExplicitOutputArguments(
|
|
||||||
solver_input, directory.Path() / "solver-failure.h5"));
|
|
||||||
const auto output = RunApplication(ExplicitOutputArguments(
|
|
||||||
valid_input, directory.Path() / "nonexistent-parent" / "results.h5"));
|
|
||||||
|
|
||||||
EXPECT_EQ(success.exit_code, 0) << success.standard_error;
|
EXPECT_EQ(success.exit_code, 0) << success.standard_error;
|
||||||
EXPECT_EQ(usage.exit_code, 2);
|
EXPECT_EQ(usage.exit_code, 2);
|
||||||
EXPECT_EQ(input.exit_code, 3);
|
EXPECT_EQ(input.exit_code, 3);
|
||||||
EXPECT_EQ(model.exit_code, 4);
|
EXPECT_EQ(model.exit_code, 4);
|
||||||
EXPECT_EQ(solver.exit_code, 5);
|
EXPECT_EQ(solver.exit_code, 5);
|
||||||
EXPECT_EQ(output.exit_code, 6);
|
|
||||||
|
|
||||||
ExpectDiagnosticFieldOrder(usage.standard_error);
|
ExpectDiagnosticFieldOrder(usage.standard_error);
|
||||||
ExpectDiagnosticFieldOrder(input.standard_error);
|
ExpectDiagnosticFieldOrder(input.standard_error);
|
||||||
ExpectDiagnosticFieldOrder(model.standard_error);
|
ExpectDiagnosticFieldOrder(model.standard_error);
|
||||||
ExpectDiagnosticFieldOrder(solver.standard_error);
|
ExpectDiagnosticFieldOrder(solver.standard_error);
|
||||||
ExpectDiagnosticFieldOrder(output.standard_error);
|
|
||||||
EXPECT_EQ(repeated_output.exit_code, 2);
|
EXPECT_EQ(repeated_output.exit_code, 2);
|
||||||
ExpectDiagnosticFieldOrder(repeated_output.standard_error);
|
ExpectDiagnosticFieldOrder(repeated_output.standard_error);
|
||||||
EXPECT_NE(repeated_output.standard_error.find("code=cli-usage"),
|
EXPECT_NE(repeated_output.standard_error.find("code=cli-usage"),
|
||||||
@@ -407,24 +408,79 @@ TEST(LinearStaticCli, ReturnsEveryExactExitCodeAndOrderedDiagnostic) {
|
|||||||
std::string::npos);
|
std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-003 and NSNR-CLI-007: usage failure precedes every output side
|
||||||
|
// effect, including replacement of existing derived files.
|
||||||
|
TEST(LinearStaticCli, OutputSubstringRejectionLeavesDerivedFilesUnchanged) {
|
||||||
|
TempDirectory directory{"usage-no-output"};
|
||||||
|
const auto input = directory.Path() / "model.inp";
|
||||||
|
const auto results = directory.Path() / "model_results.h5";
|
||||||
|
const auto log = directory.Path() / "model_log.txt";
|
||||||
|
WriteText(input, AxialDeck(true, false, false));
|
||||||
|
WriteText(results, "previous-results");
|
||||||
|
WriteText(log, "previous-log");
|
||||||
|
const FileSnapshot previous_results = SnapshotFile(results);
|
||||||
|
const FileSnapshot previous_log = SnapshotFile(log);
|
||||||
|
|
||||||
|
for (const char* argument :
|
||||||
|
{"abc--outputdef", "--output-path", "--output=foo", "--output"}) {
|
||||||
|
const auto result = RunApplication({input.string(), argument});
|
||||||
|
EXPECT_EQ(result.exit_code, 2) << argument;
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::count(result.standard_error.begin(), result.standard_error.end(), '\n'),
|
||||||
|
1U)
|
||||||
|
<< result.standard_error;
|
||||||
|
EXPECT_NE(result.standard_error.find("code=cli-usage"),
|
||||||
|
std::string::npos);
|
||||||
|
EXPECT_EQ(SnapshotFile(results).contents, previous_results.contents);
|
||||||
|
EXPECT_EQ(SnapshotFile(results).write_time, previous_results.write_time);
|
||||||
|
EXPECT_EQ(SnapshotFile(log).contents, previous_log.contents);
|
||||||
|
EXPECT_EQ(SnapshotFile(log).write_time, previous_log.write_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-006: a held lease blocks the application before any public output
|
||||||
|
// is opened, truncated, or replaced.
|
||||||
|
TEST(LinearStaticCli, BusyOutputLeaseLeavesDerivedFilesUnchanged) {
|
||||||
|
TempDirectory directory{"busy-output"};
|
||||||
|
const auto input = directory.Path() / "model.inp";
|
||||||
|
const auto results = directory.Path() / "model_results.h5";
|
||||||
|
const auto log = directory.Path() / "model_log.txt";
|
||||||
|
WriteText(input, AxialDeck(true, false, false));
|
||||||
|
WriteText(results, "previous-results");
|
||||||
|
WriteText(log, "previous-log");
|
||||||
|
const FileSnapshot previous_results = SnapshotFile(results);
|
||||||
|
const FileSnapshot previous_log = SnapshotFile(log);
|
||||||
|
|
||||||
|
const fesa::DerivedOutputPaths paths{input, results, log};
|
||||||
|
auto lease = fesa::AcquireOutputWriteLease(paths);
|
||||||
|
ASSERT_TRUE(lease.HasValue()) << lease.GetStatus().Diagnostics().size();
|
||||||
|
|
||||||
|
const auto result = RunApplication({input.string()});
|
||||||
|
EXPECT_EQ(result.exit_code, 6) << result.standard_error;
|
||||||
|
EXPECT_NE(result.standard_error.find("code=output-busy"),
|
||||||
|
std::string::npos);
|
||||||
|
EXPECT_EQ(SnapshotFile(results).contents, previous_results.contents);
|
||||||
|
EXPECT_EQ(SnapshotFile(results).write_time, previous_results.write_time);
|
||||||
|
EXPECT_EQ(SnapshotFile(log).contents, previous_log.contents);
|
||||||
|
EXPECT_EQ(SnapshotFile(log).write_time, previous_log.write_time);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(LinearStaticCli, OutputRequestsDoNotFilterMandatoryResults) {
|
TEST(LinearStaticCli, OutputRequestsDoNotFilterMandatoryResults) {
|
||||||
TempDirectory directory{"output-requests"};
|
TempDirectory directory{"output-requests"};
|
||||||
const auto plain_input = directory.Path() / "plain.inp";
|
const auto plain_input = directory.Path() / "plain.inp";
|
||||||
const auto requested_input = directory.Path() / "requested.inp";
|
const auto requested_input = directory.Path() / "requested.inp";
|
||||||
const auto plain_output = directory.Path() / "plain.h5";
|
|
||||||
const auto requested_output = directory.Path() / "requested.h5";
|
|
||||||
WriteText(plain_input, AxialDeck(true, false, false));
|
WriteText(plain_input, AxialDeck(true, false, false));
|
||||||
WriteText(requested_input, AxialDeck(true, false, true));
|
WriteText(requested_input, AxialDeck(true, false, true));
|
||||||
|
|
||||||
const auto plain =
|
const auto plain = RunApplication({plain_input.string()});
|
||||||
RunApplication(ExplicitOutputArguments(plain_input, plain_output));
|
const auto requested = RunApplication({requested_input.string()});
|
||||||
const auto requested = RunApplication(
|
|
||||||
ExplicitOutputArguments(requested_input, requested_output));
|
|
||||||
ASSERT_EQ(plain.exit_code, 0) << plain.standard_error;
|
ASSERT_EQ(plain.exit_code, 0) << plain.standard_error;
|
||||||
ASSERT_EQ(requested.exit_code, 0) << requested.standard_error;
|
ASSERT_EQ(requested.exit_code, 0) << requested.standard_error;
|
||||||
|
|
||||||
const auto plain_file = OpenFile(plain_output);
|
const auto plain_file =
|
||||||
const auto requested_file = OpenFile(requested_output);
|
OpenFile(plain_input.parent_path() / "plain_results.h5");
|
||||||
|
const auto requested_file =
|
||||||
|
OpenFile(requested_input.parent_path() / "requested_results.h5");
|
||||||
ExpectMandatoryInventory(plain_file.Get());
|
ExpectMandatoryInventory(plain_file.Get());
|
||||||
ExpectMandatoryInventory(requested_file.Get());
|
ExpectMandatoryInventory(requested_file.Get());
|
||||||
|
|
||||||
@@ -449,10 +505,10 @@ TEST(LinearStaticCli, OutputRequestsDoNotFilterMandatoryResults) {
|
|||||||
TEST(Mitc4ShellCli, WritesShellHdf5ThroughTheExistingApplicationRoute) {
|
TEST(Mitc4ShellCli, WritesShellHdf5ThroughTheExistingApplicationRoute) {
|
||||||
TempDirectory directory{"shell-route"};
|
TempDirectory directory{"shell-route"};
|
||||||
const auto input = directory.Path() / "shell.inp";
|
const auto input = directory.Path() / "shell.inp";
|
||||||
const auto output = directory.Path() / "shell-results.h5";
|
const auto output = directory.Path() / "shell_results.h5";
|
||||||
WriteText(input, AllConstrainedShellDeck());
|
WriteText(input, AllConstrainedShellDeck());
|
||||||
|
|
||||||
const auto result = RunApplication(ExplicitOutputArguments(input, output));
|
const auto result = RunApplication({input.string()});
|
||||||
ASSERT_EQ(result.exit_code, 0) << result.standard_error;
|
ASSERT_EQ(result.exit_code, 0) << result.standard_error;
|
||||||
ExpectShellHdf5Identity(output, input);
|
ExpectShellHdf5Identity(output, input);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,8 @@ TEST(B33ReferenceComparison, GeneratesAuthoritativeHdf5AndComparisonEvidence) {
|
|||||||
const auto input = reference_directory / "cantilever beam.inp";
|
const auto input = reference_directory / "cantilever beam.inp";
|
||||||
const auto output_directory =
|
const auto output_directory =
|
||||||
binary_root / "reference" / "cantilever-beam-b33";
|
binary_root / "reference" / "cantilever-beam-b33";
|
||||||
const auto results = output_directory / "results.h5";
|
const auto execution_input = output_directory / input.filename();
|
||||||
|
const auto results = output_directory / "cantilever beam_results.h5";
|
||||||
const auto comparison = output_directory / "comparison.json";
|
const auto comparison = output_directory / "comparison.json";
|
||||||
|
|
||||||
// Only the exact build-local evidence directory is reset; the approved
|
// Only the exact build-local evidence directory is reset; the approved
|
||||||
@@ -173,16 +174,18 @@ TEST(B33ReferenceComparison, GeneratesAuthoritativeHdf5AndComparisonEvidence) {
|
|||||||
std::filesystem::path{"cantilever beam reactions.csv"});
|
std::filesystem::path{"cantilever beam reactions.csv"});
|
||||||
EXPECT_EQ(reference_before[3U].relative_path,
|
EXPECT_EQ(reference_before[3U].relative_path,
|
||||||
std::filesystem::path{"cantilever beam.inp"});
|
std::filesystem::path{"cantilever beam.inp"});
|
||||||
|
ASSERT_TRUE(std::filesystem::copy_file(input, execution_input, error));
|
||||||
|
ASSERT_FALSE(error);
|
||||||
|
|
||||||
fesa::FesaApplication application;
|
fesa::FesaApplication application;
|
||||||
// FesaApplication receives application operands/options; main strips argv[0].
|
ASSERT_EQ(application.Run({execution_input.string()}), 0);
|
||||||
ASSERT_EQ(application.Run({input.string(), "--output", results.string()}), 0);
|
|
||||||
ASSERT_TRUE(std::filesystem::is_regular_file(results));
|
ASSERT_TRUE(std::filesystem::is_regular_file(results));
|
||||||
ASSERT_GT(H5Fis_hdf5(results.string().c_str()), 0);
|
ASSERT_GT(H5Fis_hdf5(results.string().c_str()), 0);
|
||||||
EXPECT_GT(StressRowCount(results), 0U);
|
EXPECT_GT(StressRowCount(results), 0U);
|
||||||
|
|
||||||
auto comparison_result =
|
auto comparison_result =
|
||||||
fesa::test::ReferenceComparison::Compare(results, reference_directory);
|
fesa::test::ReferenceComparison::Compare(results, reference_directory,
|
||||||
|
execution_input);
|
||||||
ASSERT_TRUE(comparison_result.HasValue());
|
ASSERT_TRUE(comparison_result.HasValue());
|
||||||
const auto& report = comparison_result.Value();
|
const auto& report = comparison_result.Value();
|
||||||
ASSERT_TRUE(report.passed);
|
ASSERT_TRUE(report.passed);
|
||||||
@@ -248,7 +251,9 @@ TEST(B33ReferenceComparison, GeneratesAuthoritativeHdf5AndComparisonEvidence) {
|
|||||||
}
|
}
|
||||||
std::sort(generated_names.begin(), generated_names.end());
|
std::sort(generated_names.begin(), generated_names.end());
|
||||||
EXPECT_EQ(generated_names,
|
EXPECT_EQ(generated_names,
|
||||||
(std::vector<std::string>{"comparison.json", "results.h5"}));
|
(std::vector<std::string>{"cantilever beam.inp",
|
||||||
|
"cantilever beam_results.h5",
|
||||||
|
"comparison.json"}));
|
||||||
|
|
||||||
ExpectTreeUnchanged(reference_before, SnapshotTree(reference_directory));
|
ExpectTreeUnchanged(reference_before, SnapshotTree(reference_directory));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,14 +75,19 @@ CaseEvidence RunCase(const std::string& case_id,
|
|||||||
if (!std::filesystem::create_directories(output_directory, error) || error) {
|
if (!std::filesystem::create_directories(output_directory, error) || error) {
|
||||||
throw std::runtime_error{"Unable to create MITC4 evidence directory."};
|
throw std::runtime_error{"Unable to create MITC4 evidence directory."};
|
||||||
}
|
}
|
||||||
const auto results = output_directory / "results.h5";
|
const auto execution_input = output_directory / input.filename();
|
||||||
|
if (!std::filesystem::copy_file(input, execution_input, error) || error) {
|
||||||
|
throw std::runtime_error{"Unable to copy MITC4 input for execution."};
|
||||||
|
}
|
||||||
|
const auto results = output_directory /
|
||||||
|
(execution_input.stem().string() + "_results.h5");
|
||||||
const auto comparison = output_directory / "comparison.json";
|
const auto comparison = output_directory / "comparison.json";
|
||||||
|
|
||||||
fesa::FesaApplication application;
|
fesa::FesaApplication application;
|
||||||
EXPECT_EQ(application.Run({input.string(), "--output", results.string()}), 0);
|
EXPECT_EQ(application.Run({execution_input.string()}), 0);
|
||||||
EXPECT_TRUE(std::filesystem::is_regular_file(results));
|
EXPECT_TRUE(std::filesystem::is_regular_file(results));
|
||||||
auto comparison_result = fesa::test::Mitc4ReferenceComparison::Compare(
|
auto comparison_result = fesa::test::Mitc4ReferenceComparison::Compare(
|
||||||
{case_id, source_element_type, input, csv, results});
|
{case_id, source_element_type, execution_input, csv, results});
|
||||||
if (!comparison_result.HasValue()) {
|
if (!comparison_result.HasValue()) {
|
||||||
std::string diagnostics;
|
std::string diagnostics;
|
||||||
for (const auto& diagnostic : comparison_result.GetStatus().Diagnostics()) {
|
for (const auto& diagnostic : comparison_result.GetStatus().Diagnostics()) {
|
||||||
@@ -104,7 +109,9 @@ CaseEvidence RunCase(const std::string& case_id,
|
|||||||
}
|
}
|
||||||
std::sort(generated.begin(), generated.end());
|
std::sort(generated.begin(), generated.end());
|
||||||
EXPECT_EQ(generated,
|
EXPECT_EQ(generated,
|
||||||
(std::vector<std::string>{"comparison.json", "results.h5"}));
|
(std::vector<std::string>{"comparison.json",
|
||||||
|
input.filename().string(),
|
||||||
|
results.filename().string()}));
|
||||||
EXPECT_TRUE(std::filesystem::is_directory(reference_directory));
|
EXPECT_TRUE(std::filesystem::is_directory(reference_directory));
|
||||||
ExpectUnchanged(input, input_before);
|
ExpectUnchanged(input, input_before);
|
||||||
ExpectUnchanged(csv, csv_before);
|
ExpectUnchanged(csv, csv_before);
|
||||||
|
|||||||
@@ -1345,10 +1345,18 @@ bool FiniteReport(const ComparisonReport& report) {
|
|||||||
Result<ComparisonReport> ReferenceComparison::Compare(
|
Result<ComparisonReport> ReferenceComparison::Compare(
|
||||||
const std::filesystem::path& results_hdf5,
|
const std::filesystem::path& results_hdf5,
|
||||||
const std::filesystem::path& legacy_reference_directory) {
|
const std::filesystem::path& legacy_reference_directory) {
|
||||||
|
return Compare(results_hdf5, legacy_reference_directory,
|
||||||
|
legacy_reference_directory / kInputName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<ComparisonReport> ReferenceComparison::Compare(
|
||||||
|
const std::filesystem::path& results_hdf5,
|
||||||
|
const std::filesystem::path& legacy_reference_directory,
|
||||||
|
const std::filesystem::path& execution_input_path) {
|
||||||
try {
|
try {
|
||||||
RequireExactArtifactInventory(legacy_reference_directory);
|
RequireExactArtifactInventory(legacy_reference_directory);
|
||||||
const auto input = legacy_reference_directory / kInputName;
|
const auto reference_input = legacy_reference_directory / kInputName;
|
||||||
Domain domain = ReadApprovedDomain(input);
|
Domain domain = ReadApprovedDomain(reference_input);
|
||||||
const ReferenceTable displacement =
|
const ReferenceTable displacement =
|
||||||
ReadReferenceCsv(legacy_reference_directory / kDisplacementName,
|
ReadReferenceCsv(legacy_reference_directory / kDisplacementName,
|
||||||
{"Frame", "Part Instance Name", "Node Label", "U-U1",
|
{"Frame", "Part Instance Name", "Node Label", "U-U1",
|
||||||
@@ -1359,7 +1367,8 @@ Result<ComparisonReport> ReferenceComparison::Compare(
|
|||||||
"RF-RF2", "RF-RF3", "RM-RM1", "RM-RM2", "RM-RM3"});
|
"RF-RF2", "RF-RF3", "RM-RM1", "RM-RM2", "RM-RM3"});
|
||||||
const SectionReferenceTable section =
|
const SectionReferenceTable section =
|
||||||
ReadSectionReferenceCsv(legacy_reference_directory / kSectionName);
|
ReadSectionReferenceCsv(legacy_reference_directory / kSectionName);
|
||||||
HdfProjection hdf = ReadHdfProjection(results_hdf5, input, domain);
|
HdfProjection hdf =
|
||||||
|
ReadHdfProjection(results_hdf5, execution_input_path, domain);
|
||||||
const auto displacement_rows = OrderedRows(displacement, hdf.nodes);
|
const auto displacement_rows = OrderedRows(displacement, hdf.nodes);
|
||||||
const auto reaction_rows = OrderedRows(reaction, hdf.nodes);
|
const auto reaction_rows = OrderedRows(reaction, hdf.nodes);
|
||||||
const auto section_rows = OrderedSectionRows(section, hdf);
|
const auto section_rows = OrderedSectionRows(section, hdf);
|
||||||
|
|||||||
@@ -84,6 +84,15 @@ class ReferenceComparison {
|
|||||||
static Result<ComparisonReport> Compare(
|
static Result<ComparisonReport> Compare(
|
||||||
const std::filesystem::path& results_hdf5,
|
const std::filesystem::path& results_hdf5,
|
||||||
const std::filesystem::path& legacy_reference_directory);
|
const std::filesystem::path& legacy_reference_directory);
|
||||||
|
|
||||||
|
/// @brief Compares results using a separately copied execution input path.
|
||||||
|
/// @param execution_input_path Input path recorded by the solver in HDF5.
|
||||||
|
/// @note Reference inputs and CSV files remain in legacy_reference_directory.
|
||||||
|
static Result<ComparisonReport> Compare(
|
||||||
|
const std::filesystem::path& results_hdf5,
|
||||||
|
const std::filesystem::path& legacy_reference_directory,
|
||||||
|
const std::filesystem::path& execution_input_path);
|
||||||
|
|
||||||
static Status WriteDeterministicJson(
|
static Status WriteDeterministicJson(
|
||||||
const ComparisonReport& report, const std::filesystem::path& output_json);
|
const ComparisonReport& report, const std::filesystem::path& output_json);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,17 @@ import pytest
|
|||||||
from scripts import execute
|
from scripts import execute
|
||||||
|
|
||||||
|
|
||||||
|
def write_implementation_agent_profile(
|
||||||
|
root, *, model="gpt-5.6-terra", reasoning="xhigh"
|
||||||
|
):
|
||||||
|
profile = root / ".codex" / "agents" / "implementation-agent.toml"
|
||||||
|
profile.parent.mkdir(parents=True)
|
||||||
|
profile.write_text(
|
||||||
|
f'model = "{model}"\nmodel_reasoning_effort = "{reasoning}"\n',
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
|
def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
|
||||||
phase_dir = tmp_path / "phases" / "unicode-phase"
|
phase_dir = tmp_path / "phases" / "unicode-phase"
|
||||||
phase_dir.mkdir(parents=True)
|
phase_dir.mkdir(parents=True)
|
||||||
@@ -20,6 +31,7 @@ def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
|
|||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
(phase_dir / "step0.md").write_text("Euler–Bernoulli 보", encoding="utf-8")
|
(phase_dir / "step0.md").write_text("Euler–Bernoulli 보", encoding="utf-8")
|
||||||
|
write_implementation_agent_profile(tmp_path)
|
||||||
|
|
||||||
invocation = {}
|
invocation = {}
|
||||||
|
|
||||||
@@ -40,6 +52,44 @@ def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
|
|||||||
assert invocation["command"][sandbox_index + 1] == "workspace-write"
|
assert invocation["command"][sandbox_index + 1] == "workspace-write"
|
||||||
|
|
||||||
|
|
||||||
|
def test_invoke_codex_uses_implementation_agent_command_contract(
|
||||||
|
tmp_path, monkeypatch
|
||||||
|
):
|
||||||
|
phase_dir = tmp_path / "phases" / "agent-phase"
|
||||||
|
phase_dir.mkdir(parents=True)
|
||||||
|
(phase_dir / "index.json").write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"project": "FESA Structural Solver",
|
||||||
|
"phase": "agent-phase",
|
||||||
|
"steps": [{"step": 0, "name": "agent", "status": "pending"}],
|
||||||
|
}
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
(phase_dir / "step0.md").write_text("agent routing", encoding="utf-8")
|
||||||
|
write_implementation_agent_profile(tmp_path)
|
||||||
|
|
||||||
|
invocation = {}
|
||||||
|
|
||||||
|
def capture_run(command, **kwargs):
|
||||||
|
invocation["command"] = command
|
||||||
|
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
|
||||||
|
|
||||||
|
monkeypatch.setattr(execute, "ROOT", tmp_path)
|
||||||
|
monkeypatch.setattr(execute.subprocess, "run", capture_run)
|
||||||
|
|
||||||
|
executor = execute.StepExecutor("agent-phase")
|
||||||
|
executor._invoke_codex({"step": 0, "name": "agent"}, "")
|
||||||
|
|
||||||
|
model_index = invocation["command"].index("--model")
|
||||||
|
config_index = invocation["command"].index("--config")
|
||||||
|
assert invocation["command"][model_index + 1] == "gpt-5.6-terra"
|
||||||
|
assert invocation["command"][config_index + 1] == 'model_reasoning_effort="xhigh"'
|
||||||
|
adjacent_arguments = list(zip(invocation["command"], invocation["command"][1:]))
|
||||||
|
assert ("--disable", "unified_exec") in adjacent_arguments
|
||||||
|
|
||||||
|
|
||||||
def test_invoke_codex_accepts_explicit_danger_full_access_override(
|
def test_invoke_codex_accepts_explicit_danger_full_access_override(
|
||||||
tmp_path, monkeypatch
|
tmp_path, monkeypatch
|
||||||
):
|
):
|
||||||
@@ -56,6 +106,7 @@ def test_invoke_codex_accepts_explicit_danger_full_access_override(
|
|||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
(phase_dir / "step0.md").write_text("sandbox override", encoding="utf-8")
|
(phase_dir / "step0.md").write_text("sandbox override", encoding="utf-8")
|
||||||
|
write_implementation_agent_profile(tmp_path)
|
||||||
|
|
||||||
invocation = {}
|
invocation = {}
|
||||||
|
|
||||||
@@ -74,6 +125,80 @@ def test_invoke_codex_accepts_explicit_danger_full_access_override(
|
|||||||
assert invocation["command"][sandbox_index + 1] == "danger-full-access"
|
assert invocation["command"][sandbox_index + 1] == "danger-full-access"
|
||||||
|
|
||||||
|
|
||||||
|
def test_invoke_codex_timeout_writes_structured_failure(tmp_path, monkeypatch):
|
||||||
|
phase_dir = tmp_path / "phases" / "timeout-phase"
|
||||||
|
phase_dir.mkdir(parents=True)
|
||||||
|
(phase_dir / "index.json").write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"project": "FESA Structural Solver",
|
||||||
|
"phase": "timeout-phase",
|
||||||
|
"steps": [{"step": 0, "name": "timeout", "status": "pending"}],
|
||||||
|
}
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
(phase_dir / "step0.md").write_text("timeout", encoding="utf-8")
|
||||||
|
write_implementation_agent_profile(tmp_path)
|
||||||
|
|
||||||
|
def timeout_run(command, **kwargs):
|
||||||
|
raise subprocess.TimeoutExpired(
|
||||||
|
command, kwargs["timeout"], output="partial stdout", stderr="partial stderr"
|
||||||
|
)
|
||||||
|
|
||||||
|
monkeypatch.setattr(execute, "ROOT", tmp_path)
|
||||||
|
monkeypatch.setattr(execute.subprocess, "run", timeout_run)
|
||||||
|
|
||||||
|
executor = execute.StepExecutor("timeout-phase")
|
||||||
|
output = executor._invoke_codex({"step": 0, "name": "timeout"}, "")
|
||||||
|
|
||||||
|
assert output["exitCode"] == 124
|
||||||
|
assert output["stdout"] == "partial stdout"
|
||||||
|
assert "Codex timed out after 1800 seconds." in output["stderr"]
|
||||||
|
stored = json.loads((phase_dir / "step0-output.json").read_text(encoding="utf-8"))
|
||||||
|
assert stored == output
|
||||||
|
|
||||||
|
|
||||||
|
def test_execute_single_step_retries_structured_codex_timeout(tmp_path, monkeypatch):
|
||||||
|
phase_dir = tmp_path / "phases" / "retry-phase"
|
||||||
|
phase_dir.mkdir(parents=True)
|
||||||
|
(phase_dir / "index.json").write_text(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"project": "FESA Structural Solver",
|
||||||
|
"phase": "retry-phase",
|
||||||
|
"steps": [{"step": 0, "name": "retry", "status": "pending"}],
|
||||||
|
}
|
||||||
|
),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
(phase_dir / "step0.md").write_text("retry", encoding="utf-8")
|
||||||
|
write_implementation_agent_profile(tmp_path)
|
||||||
|
attempts = []
|
||||||
|
|
||||||
|
def timeout_run(command, **kwargs):
|
||||||
|
attempts.append(command)
|
||||||
|
raise subprocess.TimeoutExpired(command, kwargs["timeout"])
|
||||||
|
|
||||||
|
monkeypatch.setattr(execute, "ROOT", tmp_path)
|
||||||
|
monkeypatch.setattr(execute.subprocess, "run", timeout_run)
|
||||||
|
|
||||||
|
executor = execute.StepExecutor("retry-phase")
|
||||||
|
executor.MAX_RETRIES = 2
|
||||||
|
monkeypatch.setattr(executor, "_commit_step", lambda *args: None)
|
||||||
|
monkeypatch.setattr(executor, "_update_top_index", lambda *args: None)
|
||||||
|
|
||||||
|
with pytest.raises(SystemExit, match="1"):
|
||||||
|
executor._execute_single_step(
|
||||||
|
{"step": 0, "name": "retry", "status": "pending"}, ""
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(attempts) == 2
|
||||||
|
index = json.loads((phase_dir / "index.json").read_text(encoding="utf-8"))
|
||||||
|
assert index["steps"][0]["status"] == "error"
|
||||||
|
assert "Codex timed out after 1800 seconds." in index["steps"][0]["error_message"]
|
||||||
|
|
||||||
|
|
||||||
def test_invoke_codex_rejects_unknown_sandbox_override(tmp_path, monkeypatch):
|
def test_invoke_codex_rejects_unknown_sandbox_override(tmp_path, monkeypatch):
|
||||||
phase_dir = tmp_path / "phases" / "sandbox-phase"
|
phase_dir = tmp_path / "phases" / "sandbox-phase"
|
||||||
phase_dir.mkdir(parents=True)
|
phase_dir.mkdir(parents=True)
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
#include "fesa/app/output_paths.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "fesa/analysis/analysis.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class TempDirectory {
|
||||||
|
public:
|
||||||
|
explicit TempDirectory(const std::string& label) {
|
||||||
|
const auto tick =
|
||||||
|
std::chrono::steady_clock::now().time_since_epoch().count();
|
||||||
|
path_ = std::filesystem::temp_directory_path() /
|
||||||
|
("fesa-output-paths-" + label + "-" + std::to_string(tick));
|
||||||
|
std::error_code error;
|
||||||
|
if (!std::filesystem::create_directory(path_, error) || error) {
|
||||||
|
throw std::runtime_error{"Unable to create an output-path test fixture."};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TempDirectory(const TempDirectory&) = delete;
|
||||||
|
TempDirectory& operator=(const TempDirectory&) = delete;
|
||||||
|
|
||||||
|
~TempDirectory() {
|
||||||
|
std::error_code ignored;
|
||||||
|
std::filesystem::remove_all(path_, ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path& Path() const noexcept { return path_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::filesystem::path path_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ExpectFailureCode(const fesa::Status& status, const char* code) {
|
||||||
|
ASSERT_FALSE(status.IsOk());
|
||||||
|
ASSERT_EQ(status.Diagnostics().size(), 1U);
|
||||||
|
EXPECT_EQ(status.Diagnostics().front().code, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-001 and NSNR-CLI-002: a token containing the literal substring
|
||||||
|
// must fail before input path validation or output derivation.
|
||||||
|
TEST(OutputPaths, RejectsFirstTokenContainingOutputSubstring) {
|
||||||
|
const auto paths = fesa::DeriveSingleInputOutputPaths(
|
||||||
|
{"abc--outputdef", "model.inp", "--output=ignored"},
|
||||||
|
std::filesystem::path{"C:/invocation"});
|
||||||
|
|
||||||
|
ASSERT_FALSE(paths.HasValue());
|
||||||
|
ExpectFailureCode(paths.GetStatus(), "cli-usage");
|
||||||
|
EXPECT_EQ(paths.GetStatus().Diagnostics().front().entity_identity,
|
||||||
|
"argument_index=0;argument=abc--outputdef");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(OutputPaths, RejectsEveryOutputSubstringVariant) {
|
||||||
|
for (const char* argument :
|
||||||
|
{"abc--outputdef", "--output-path", "--output=foo", "--output"}) {
|
||||||
|
const auto paths = fesa::DeriveSingleInputOutputPaths(
|
||||||
|
{"model.inp", argument}, std::filesystem::path{"C:/invocation"});
|
||||||
|
|
||||||
|
ASSERT_FALSE(paths.HasValue()) << argument;
|
||||||
|
ExpectFailureCode(paths.GetStatus(), "cli-usage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-004: derivation is lexical and does not inspect the filesystem.
|
||||||
|
TEST(OutputPaths, DerivesNormalizedSiblingNamesFromRelativeInput) {
|
||||||
|
const auto paths = fesa::DeriveSingleInputOutputPaths(
|
||||||
|
{"inputs/../models/Beam.Model.INP"},
|
||||||
|
std::filesystem::path{"C:/invocation/current"});
|
||||||
|
|
||||||
|
ASSERT_TRUE(paths.HasValue()) << paths.GetStatus().Diagnostics().size();
|
||||||
|
EXPECT_EQ(
|
||||||
|
paths.Value().input_path,
|
||||||
|
std::filesystem::path{"C:/invocation/current/models/Beam.Model.INP"});
|
||||||
|
EXPECT_EQ(paths.Value().results_path,
|
||||||
|
std::filesystem::path{
|
||||||
|
"C:/invocation/current/models/Beam.Model_results.h5"});
|
||||||
|
EXPECT_EQ(paths.Value().log_path,
|
||||||
|
std::filesystem::path{
|
||||||
|
"C:/invocation/current/models/Beam.Model_log.txt"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-005: only the final, case-insensitive input extension is removed.
|
||||||
|
TEST(OutputPaths, PreservesBasenameCaseAndPrecedingDots) {
|
||||||
|
const auto paths = fesa::DeriveSingleInputOutputPaths(
|
||||||
|
{"C:/models/.Beam.v2.iNp"}, std::filesystem::path{"C:/unused"});
|
||||||
|
|
||||||
|
ASSERT_TRUE(paths.HasValue());
|
||||||
|
EXPECT_EQ(paths.Value().results_path,
|
||||||
|
std::filesystem::path{"C:/models/.Beam.v2_results.h5"});
|
||||||
|
EXPECT_EQ(paths.Value().log_path,
|
||||||
|
std::filesystem::path{"C:/models/.Beam.v2_log.txt"});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(OutputPaths, RejectsInputWithoutInpFinalExtension) {
|
||||||
|
const auto paths = fesa::DeriveSingleInputOutputPaths(
|
||||||
|
{"model.inp.bak"}, std::filesystem::path{"C:/invocation"});
|
||||||
|
|
||||||
|
ASSERT_FALSE(paths.HasValue());
|
||||||
|
ExpectFailureCode(paths.GetStatus(), "cli-usage");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-006: the lease is exclusive and does not create public outputs.
|
||||||
|
TEST(OutputPaths, LeaseCollisionPreservesPublicOutputPaths) {
|
||||||
|
TempDirectory directory{"lease"};
|
||||||
|
const fesa::DerivedOutputPaths paths{
|
||||||
|
directory.Path() / "model.inp", directory.Path() / "model_results.h5",
|
||||||
|
directory.Path() / "model_log.txt"};
|
||||||
|
|
||||||
|
auto first = fesa::AcquireOutputWriteLease(paths);
|
||||||
|
ASSERT_TRUE(first.HasValue()) << first.GetStatus().Diagnostics().size();
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(paths.results_path));
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(paths.log_path));
|
||||||
|
|
||||||
|
const auto second = fesa::AcquireOutputWriteLease(paths);
|
||||||
|
ASSERT_FALSE(second.HasValue());
|
||||||
|
ExpectFailureCode(second.GetStatus(), "output-busy");
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(paths.results_path));
|
||||||
|
EXPECT_FALSE(std::filesystem::exists(paths.log_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSNR-CLI-009: procedure calls receive all derived output identities.
|
||||||
|
TEST(OutputPaths, AnalysisRequestCarriesInputResultAndLogPaths) {
|
||||||
|
const fesa::AnalysisRequest request{
|
||||||
|
std::filesystem::path{"C:/models/model.inp"},
|
||||||
|
std::filesystem::path{"C:/models/model_results.h5"},
|
||||||
|
std::filesystem::path{"C:/models/model_log.txt"}};
|
||||||
|
|
||||||
|
EXPECT_EQ(request.input_path, "C:/models/model.inp");
|
||||||
|
EXPECT_EQ(request.output_path, "C:/models/model_results.h5");
|
||||||
|
EXPECT_EQ(request.log_path, "C:/models/model_log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
Reference in New Issue
Block a user