radia 1.3.4__tar.gz → 1.3.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. {radia-1.3.4/src/radia.egg-info → radia-1.3.6}/PKG-INFO +79 -3
  2. {radia-1.3.4 → radia-1.3.6}/README.md +78 -2
  3. {radia-1.3.4 → radia-1.3.6}/docs/CF_BACKGROUND_FIELD_IMPLEMENTATION.md +63 -1
  4. radia-1.3.6/docs/SOLVER_METHODS.md +221 -0
  5. radia-1.3.6/examples/cube_uniform_field/README.md +55 -0
  6. radia-1.3.6/examples/cube_uniform_field/linear/README.md +334 -0
  7. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_external_field.py +379 -0
  8. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_high_mu.py +318 -0
  9. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_mesh_convergence.py +410 -0
  10. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_solver_methods.py +53 -0
  11. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_tetra_vs_hex.py +275 -0
  12. radia-1.3.6/examples/cube_uniform_field/linear/benchmark_tetra_vs_ngsolve.py +349 -0
  13. radia-1.3.6/examples/cube_uniform_field/linear/compare_external_field.py +406 -0
  14. radia-1.3.6/examples/cube_uniform_field/linear/evaluate_perturbation_field.py +370 -0
  15. radia-1.3.6/examples/cube_uniform_field/linear/precision_evaluation.py +504 -0
  16. radia-1.3.6/examples/cube_uniform_field/linear/test_method9_fine_mesh.py +132 -0
  17. radia-1.3.6/examples/cube_uniform_field/linear/test_method9_high_mu.py +138 -0
  18. radia-1.3.6/examples/cube_uniform_field/nonlinear/README.md +220 -0
  19. radia-1.3.6/examples/cube_uniform_field/nonlinear/benchmark_nonlinear_tetra_vs_hex.py +230 -0
  20. radia-1.3.6/examples/electromagnet/field_distribution.vtk +27350 -0
  21. radia-1.3.6/examples/solver_benchmarks/benchmark_lu_vs_hmatrix.py +345 -0
  22. {radia-1.3.4 → radia-1.3.6}/pyproject.toml +1 -1
  23. {radia-1.3.4 → radia-1.3.6}/setup.py +12 -13
  24. radia-1.3.6/src/python/radia.pyd +0 -0
  25. {radia-1.3.4 → radia-1.3.6}/src/python/radia_ngsolve.pyd +0 -0
  26. {radia-1.3.4 → radia-1.3.6/src/radia.egg-info}/PKG-INFO +79 -3
  27. {radia-1.3.4 → radia-1.3.6}/src/radia.egg-info/SOURCES.txt +22 -33
  28. radia-1.3.4/docs/hmatrix_field_design.md +0 -249
  29. radia-1.3.4/examples/NGSolve_Integration/example_hmatrix_cache_usage.py +0 -249
  30. radia-1.3.4/examples/electromagnet/field_distribution.vtk +0 -27350
  31. radia-1.3.4/examples/simple_problems/hmatrix_update_magnetization.py +0 -108
  32. radia-1.3.4/examples/solver_benchmarks/benchmark_hmatrix_field.py +0 -120
  33. radia-1.3.4/examples/solver_benchmarks/benchmark_hmatrix_scaling_exact.py +0 -312
  34. radia-1.3.4/examples/solver_benchmarks/run_all_hmatrix_benchmarks.py +0 -114
  35. radia-1.3.4/src/python/rad_ngsolve.pyd +0 -0
  36. radia-1.3.4/tests/benchmark_hmatrix.py +0 -303
  37. radia-1.3.4/tests/hmatrix/test_phase2a_final.py +0 -136
  38. radia-1.3.4/tests/hmatrix/test_phase2a_hmatrix_reuse.py +0 -181
  39. radia-1.3.4/tests/hmatrix/test_phase2a_with_field.py +0 -125
  40. radia-1.3.4/tests/hmatrix/test_phase2b_geometry_detection.py +0 -182
  41. radia-1.3.4/tests/hmatrix/test_phase3_magnetization_update.py +0 -207
  42. radia-1.3.4/tests/hmatrix/test_phase3b_large_problem.py +0 -243
  43. radia-1.3.4/tests/hmatrix/test_phase3b_serialization.py +0 -223
  44. radia-1.3.4/tests/hmatrix/test_phase3b_solver_cache.py +0 -235
  45. radia-1.3.4/tests/hmatrix/test_serialize_step1_build.py +0 -43
  46. radia-1.3.4/tests/hmatrix/test_serialize_step2_load.py +0 -44
  47. radia-1.3.4/tests/hmatrix/test_verify_field_simple.py +0 -93
  48. radia-1.3.4/tests/test_hmatrix_cache.py +0 -256
  49. radia-1.3.4/tests/test_hmatrix_cache_simple.py +0 -188
  50. radia-1.3.4/tests/test_rad_ngsolve_hmatrix.py +0 -226
  51. radia-1.3.4/tests/test_update_hmatrix_magnetization.py +0 -86
  52. {radia-1.3.4 → radia-1.3.6}/COPYRIGHT.txt +0 -0
  53. {radia-1.3.4 → radia-1.3.6}/LICENSE +0 -0
  54. {radia-1.3.4 → radia-1.3.6}/MANIFEST.in +0 -0
  55. {radia-1.3.4 → radia-1.3.6}/docs/API_EXTENSIONS.md +0 -0
  56. {radia-1.3.4 → radia-1.3.6}/docs/API_REFERENCE.md +0 -0
  57. {radia-1.3.4 → radia-1.3.6}/docs/HMATRIX_BENCHMARKS_RESULTS.md +0 -0
  58. {radia-1.3.4 → radia-1.3.6}/docs/HMATRIX_ENHANCEMENT_PROPOSAL_2025.md +0 -0
  59. {radia-1.3.4 → radia-1.3.6}/docs/HMATRIX_IMPLEMENTATION_HISTORY.md +0 -0
  60. {radia-1.3.4 → radia-1.3.6}/docs/HMATRIX_SERIALIZATION.md +0 -0
  61. {radia-1.3.4 → radia-1.3.6}/docs/HMATRIX_USER_GUIDE.md +0 -0
  62. {radia-1.3.4 → radia-1.3.6}/docs/MATERIAL_API_IMPLEMENTATION.md +0 -0
  63. {radia-1.3.4 → radia-1.3.6}/docs/ML_PARAMETER_TUNING.md +0 -0
  64. {radia-1.3.4 → radia-1.3.6}/docs/NGSOLVE_CF_BACKGROUND_FIELD_DESIGN.md +0 -0
  65. {radia-1.3.4 → radia-1.3.6}/docs/NGSOLVE_INTEGRATION.md +0 -0
  66. {radia-1.3.4 → radia-1.3.6}/docs/NGSOLVE_USAGE_GUIDE.md +0 -0
  67. {radia-1.3.4 → radia-1.3.6}/docs/README.md +0 -0
  68. {radia-1.3.4 → radia-1.3.6}/docs/scripts/README.md +0 -0
  69. {radia-1.3.4 → radia-1.3.6}/examples/README.md +0 -0
  70. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/README.md +0 -0
  71. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/cubit_to_nastran.py +0 -0
  72. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/permeability_comparison.py +0 -0
  73. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/quadrupole_analytical.py +0 -0
  74. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/quadrupole_analytical.vtk.vtk +0 -0
  75. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/sphere_in_quadrupole.py +0 -0
  76. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/sphere_nastran_analysis.py +0 -0
  77. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/sphere_nastran_field_mu.pvsm +0 -0
  78. {radia-1.3.4 → radia-1.3.6}/examples/background_fields/sphere_nastran_geometry.vtk +0 -0
  79. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/README.md +0 -0
  80. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/coil_geometry.vtk +0 -0
  81. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/coil_model.py +0 -0
  82. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/complex_coil.pvsm +0 -0
  83. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/field_map.py +0 -0
  84. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/field_map.vtk +0 -0
  85. {radia-1.3.4 → radia-1.3.6}/examples/complex_coil_geometry/visualize_coils.py +0 -0
  86. {radia-1.3.4/examples/magnets → radia-1.3.6/examples/cube_uniform_field/linear}/README_CUBE_BENCHMARK.md +0 -0
  87. {radia-1.3.4/examples/magnets → radia-1.3.6/examples/cube_uniform_field/linear}/cube_benchmark_external_field.py +0 -0
  88. {radia-1.3.4/examples/magnets → radia-1.3.6/examples/cube_uniform_field/linear}/cube_benchmark_radia.vtk +0 -0
  89. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/README.md +0 -0
  90. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/Radia_model.vtk +0 -0
  91. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/York.vtk +0 -0
  92. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/main_simulation_workflow.py +0 -0
  93. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/visualize_paraview.py +0 -0
  94. {radia-1.3.4 → radia-1.3.6}/examples/electromagnet/york_cubit_mesh.py +0 -0
  95. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/README.md +0 -0
  96. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/benchmark_gridfunction_set.py +0 -0
  97. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/demo_batch_evaluation.py +0 -0
  98. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/demo_field_types.py +0 -0
  99. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/RADIA_TETRA_ROOT_CAUSE.md +0 -0
  100. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/README.md +0 -0
  101. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/compare_radia_ngsolve_cube.py +0 -0
  102. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/cube_hex.vtk +0 -0
  103. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/demo_tetrahedral_methods_comparison.py +0 -0
  104. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/ngsolve_cube_graded_mesh.vtk +0 -0
  105. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/ngsolve_cube_uniform_field.py +0 -0
  106. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/ngsolve_tet_mesh.vtk +0 -0
  107. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/mesh_magnetization_import/sphere_domain_graded_mesh.vtk +0 -0
  108. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/test_batch_evaluation.py +0 -0
  109. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/verify_curl_A_equals_B.py +0 -0
  110. {radia-1.3.4/examples/NGSolve_Integration → radia-1.3.6/examples/ngsolve_integration}/visualize_field.py +0 -0
  111. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/CONVERSION_NOTES.md +0 -0
  112. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/README.md +0 -0
  113. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/arc_current_dual_magnets.py +0 -0
  114. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/arc_current_with_magnet.py +0 -0
  115. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/chamfered_pole_piece.py +0 -0
  116. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/compare_magpylib.py +0 -0
  117. {radia-1.3.4 → radia-1.3.6}/examples/simple_problems/cubic_polyhedron_magnet.py +0 -0
  118. {radia-1.3.4 → radia-1.3.6}/examples/smco_magnet_array/README.md +0 -0
  119. {radia-1.3.4 → radia-1.3.6}/examples/smco_magnet_array/smbo.pvsm +0 -0
  120. {radia-1.3.4 → radia-1.3.6}/examples/smco_magnet_array/smco_array.py +0 -0
  121. {radia-1.3.4 → radia-1.3.6}/examples/smco_magnet_array/smco_array.vtk +0 -0
  122. {radia-1.3.4 → radia-1.3.6}/examples/smco_magnet_array/smco_field_distribution.vtk +0 -0
  123. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/BENCHMARK_RESULTS.md +0 -0
  124. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/HMATRIX_FIELD_DESIGN.md +0 -0
  125. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/HMATRIX_FIELD_DESIGN_SIMPLIFIED.md +0 -0
  126. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/PHASE2B_REEVALUATION.md +0 -0
  127. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/README.md +0 -0
  128. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/SCALING_RESULTS.md +0 -0
  129. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_field_evaluation.py +0 -0
  130. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_large_scale_comparison.py +0 -0
  131. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_linear_material.py +0 -0
  132. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_matrix_construction.py +0 -0
  133. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_parallel_construction.py +0 -0
  134. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_solver.py +0 -0
  135. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_solver_comparison.py +0 -0
  136. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_solver_methods.py +0 -0
  137. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_solver_scaling.py +0 -0
  138. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/benchmark_solver_scaling_extended.py +0 -0
  139. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/plot_benchmark_results.py +0 -0
  140. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/run_all_benchmarks.py +0 -0
  141. {radia-1.3.4 → radia-1.3.6}/examples/solver_benchmarks/verify_field_accuracy.py +0 -0
  142. {radia-1.3.4 → radia-1.3.6}/setup.cfg +0 -0
  143. {radia-1.3.4 → radia-1.3.6}/src/python/__init__.py +0 -0
  144. {radia-1.3.4 → radia-1.3.6}/src/python/nastran_mesh_import.py +0 -0
  145. {radia-1.3.4 → radia-1.3.6}/src/python/netgen_mesh_import.py +0 -0
  146. {radia-1.3.4 → radia-1.3.6}/src/python/rad_ngsolve_fast.py +0 -0
  147. {radia-1.3.4 → radia-1.3.6}/src/python/radia_coil_builder.py +0 -0
  148. {radia-1.3.4 → radia-1.3.6}/src/python/radia_field_cached.py +0 -0
  149. {radia-1.3.4 → radia-1.3.6}/src/python/radia_ngsolve_field.py +0 -0
  150. {radia-1.3.4 → radia-1.3.6}/src/python/radia_ngsolve_utils.py +0 -0
  151. {radia-1.3.4 → radia-1.3.6}/src/python/radia_pyvista_viewer.py +0 -0
  152. {radia-1.3.4 → radia-1.3.6}/src/python/radia_vtk_export.py +0 -0
  153. {radia-1.3.4 → radia-1.3.6}/src/radia.egg-info/dependency_links.txt +0 -0
  154. {radia-1.3.4 → radia-1.3.6}/src/radia.egg-info/not-zip-safe +0 -0
  155. {radia-1.3.4 → radia-1.3.6}/src/radia.egg-info/requires.txt +0 -0
  156. {radia-1.3.4 → radia-1.3.6}/src/radia.egg-info/top_level.txt +0 -0
  157. {radia-1.3.4 → radia-1.3.6}/tests/README.md +0 -0
  158. {radia-1.3.4 → radia-1.3.6}/tests/__init__.py +0 -0
  159. {radia-1.3.4 → radia-1.3.6}/tests/benchmarks/benchmark_correct.py +0 -0
  160. {radia-1.3.4 → radia-1.3.6}/tests/benchmarks/benchmark_heavy.py +0 -0
  161. {radia-1.3.4 → radia-1.3.6}/tests/benchmarks/benchmark_openmp.py +0 -0
  162. {radia-1.3.4 → radia-1.3.6}/tests/benchmarks/benchmark_threads.py +0 -0
  163. {radia-1.3.4 → radia-1.3.6}/tests/conftest.py +0 -0
  164. {radia-1.3.4 → radia-1.3.6}/tests/profile_batch_performance.py +0 -0
  165. {radia-1.3.4 → radia-1.3.6}/tests/test_advanced.py +0 -0
  166. {radia-1.3.4 → radia-1.3.6}/tests/test_all_spaces.py +0 -0
  167. {radia-1.3.4 → radia-1.3.6}/tests/test_background_field_debug.py +0 -0
  168. {radia-1.3.4 → radia-1.3.6}/tests/test_batch_evaluation.py +0 -0
  169. {radia-1.3.4 → radia-1.3.6}/tests/test_cf_direct.py +0 -0
  170. {radia-1.3.4 → radia-1.3.6}/tests/test_convergence_hdiv.py +0 -0
  171. {radia-1.3.4 → radia-1.3.6}/tests/test_curlA_equals_B.py +0 -0
  172. {radia-1.3.4 → radia-1.3.6}/tests/test_curl_A_detailed.py +0 -0
  173. {radia-1.3.4 → radia-1.3.6}/tests/test_far_field_accuracy.py +0 -0
  174. {radia-1.3.4 → radia-1.3.6}/tests/test_fast_preparecache.py +0 -0
  175. {radia-1.3.4 → radia-1.3.6}/tests/test_fast_simple.py +0 -0
  176. {radia-1.3.4 → radia-1.3.6}/tests/test_group_operations.py +0 -0
  177. {radia-1.3.4 → radia-1.3.6}/tests/test_hcurl_vs_hdiv.py +0 -0
  178. {radia-1.3.4 → radia-1.3.6}/tests/test_l2_norm_debug.py +0 -0
  179. {radia-1.3.4 → radia-1.3.6}/tests/test_magpylib_comparison.py +0 -0
  180. {radia-1.3.4 → radia-1.3.6}/tests/test_materials.py +0 -0
  181. {radia-1.3.4 → radia-1.3.6}/tests/test_memory_allocation_tracking.py +0 -0
  182. {radia-1.3.4 → radia-1.3.6}/tests/test_minimal_cached.py +0 -0
  183. {radia-1.3.4 → radia-1.3.6}/tests/test_moving_magnet_memory.py +0 -0
  184. {radia-1.3.4 → radia-1.3.6}/tests/test_moving_magnet_memory_diagnosis.py +0 -0
  185. {radia-1.3.4 → radia-1.3.6}/tests/test_new_material_api.py +0 -0
  186. {radia-1.3.4 → radia-1.3.6}/tests/test_objbckg_simple.py +0 -0
  187. {radia-1.3.4 → radia-1.3.6}/tests/test_objbckgcf_alone.py +0 -0
  188. {radia-1.3.4 → radia-1.3.6}/tests/test_order1.py +0 -0
  189. {radia-1.3.4 → radia-1.3.6}/tests/test_parallel_performance.py +0 -0
  190. {radia-1.3.4 → radia-1.3.6}/tests/test_preparecache_performance.py +0 -0
  191. {radia-1.3.4 → radia-1.3.6}/tests/test_process_memory.py +0 -0
  192. {radia-1.3.4 → radia-1.3.6}/tests/test_python_cached_field.py +0 -0
  193. {radia-1.3.4 → radia-1.3.6}/tests/test_python_cached_simple.py +0 -0
  194. {radia-1.3.4 → radia-1.3.6}/tests/test_rad_ngsolve.py +0 -0
  195. {radia-1.3.4 → radia-1.3.6}/tests/test_rad_ngsolve_diagnostic.py +0 -0
  196. {radia-1.3.4 → radia-1.3.6}/tests/test_rad_ngsolve_function.py +0 -0
  197. {radia-1.3.4 → radia-1.3.6}/tests/test_radhmat.py +0 -0
  198. {radia-1.3.4 → radia-1.3.6}/tests/test_radia.py +0 -0
  199. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_core_memory.py +0 -0
  200. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_field_computation_memory.py +0 -0
  201. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_ngsolve_longrun.py +0 -0
  202. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_ngsolve_memory_leak.py +0 -0
  203. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_ngsolve_with_cache.py +0 -0
  204. {radia-1.3.4 → radia-1.3.6}/tests/test_radia_only_memory.py +0 -0
  205. {radia-1.3.4 → radia-1.3.6}/tests/test_serialization.py +0 -0
  206. {radia-1.3.4 → radia-1.3.6}/tests/test_set_vs_interpolate.py +0 -0
  207. {radia-1.3.4 → radia-1.3.6}/tests/test_simple.py +0 -0
  208. {radia-1.3.4 → radia-1.3.6}/tests/test_simple_fld_leak.py +0 -0
  209. {radia-1.3.4 → radia-1.3.6}/tests/test_square_coil_analytical.py +0 -0
  210. {radia-1.3.4 → radia-1.3.6}/tests/test_tetrahedral_solver.py +0 -0
  211. {radia-1.3.4 → radia-1.3.6}/tests/test_transformations.py +0 -0
  212. {radia-1.3.4 → radia-1.3.6}/tests/test_type_cast.py +0 -0
  213. {radia-1.3.4 → radia-1.3.6}/tests/test_unit_conversion_verify.py +0 -0
  214. {radia-1.3.4 → radia-1.3.6}/tests/test_utils.py +0 -0
  215. {radia-1.3.4 → radia-1.3.6}/tests/test_vector_potential.py +0 -0
  216. {radia-1.3.4 → radia-1.3.6}/tests/test_without_B_projection.py +0 -0
  217. {radia-1.3.4 → radia-1.3.6}/tests/test_without_gridfunction.py +0 -0
  218. {radia-1.3.4 → radia-1.3.6}/tests/verify_curl_A_equals_B.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: radia
3
- Version: 1.3.4
3
+ Version: 1.3.6
4
4
  Summary: Radia 3D Magnetostatics with NGSolve Integration and OpenMP Parallelization
5
5
  Home-page: https://github.com/ksugahar/Radia_NGSolve
6
6
  Author: Pascal Elleaume
@@ -296,6 +296,82 @@ export_geometry_to_vtk(mag, 'geometry.vtk')
296
296
  - NGSolve (optional, for FEM coupling via radia_ngsolve)
297
297
  - PyVista (optional, for 3D visualization)
298
298
 
299
+ ## Linear Material with External Field (ObjBckgCF)
300
+
301
+ Radia supports soft magnetic materials (linear materials) in external fields using `ObjBckgCF`.
302
+
303
+ ### Working Example
304
+
305
+ ```python
306
+ import radia as rad
307
+ import numpy as np
308
+
309
+ rad.UtiDelAll()
310
+ rad.FldUnits('m') # Use SI units
311
+
312
+ # Create soft iron cube (10cm side)
313
+ cube = rad.ObjRecMag([0, 0, 0], [0.1, 0.1, 0.1], [0, 0, 0])
314
+
315
+ # Apply isotropic linear material (mu_r = 100)
316
+ chi = 99.0 # chi = mu_r - 1
317
+ mat = rad.MatLin(chi) # IMPORTANT: Use single argument for isotropic
318
+ rad.MatApl(cube, mat)
319
+
320
+ # Create external field (1 Tesla in z-direction)
321
+ def uniform_B(pos):
322
+ return [0, 0, 1.0] # Returns B in Tesla
323
+ bg = rad.ObjBckgCF(uniform_B)
324
+
325
+ # Create system and solve
326
+ system = rad.ObjCnt([cube, bg])
327
+ result = rad.Solve(system, 0.0001, 1000)
328
+
329
+ # Result: M ~ 2.3 MA/m (correct for cube with mu_r=100 in 1T field)
330
+ M = rad.ObjM(cube)
331
+ print(f"Magnetization: {M[1]} A/m")
332
+ ```
333
+
334
+ ### Important Notes
335
+
336
+ 1. **Isotropic materials**: Always use `MatLin(chi)` (single argument)
337
+ - Do NOT use `MatLin(chi, [0, 0, 1e-10])` - this creates a poorly defined anisotropic tensor
338
+
339
+ 2. **Callback returns B in Tesla**: The callback function for `ObjBckgCF` should return magnetic flux density B in Tesla
340
+
341
+ 3. **Units**: When using `rad.FldUnits('m')`, all coordinates are in meters
342
+
343
+ 4. **Tetrahedral elements**: Also works with `ObjPolyhdr` tetrahedral meshes
344
+
345
+ ### Supported Element Types
346
+
347
+ | Element | API | External Field Support |
348
+ |---------|-----|----------------------|
349
+ | Hexahedron | `ObjRecMag` | Yes |
350
+ | Tetrahedron | `ObjPolyhdr` | Yes |
351
+ | Extruded Polygon | `ObjThckPgn` | Yes |
352
+
353
+ ## Tetrahedral Mesh Import from NGSolve/Netgen
354
+
355
+ Radia can import tetrahedral meshes from NGSolve/Netgen for complex geometries.
356
+
357
+ **Features:**
358
+ - Direct Netgen/OCC mesh import to Radia MMM
359
+ - Independent mesh optimization for FEM vs MMM
360
+ - Nastran CTETRA face connectivity standard
361
+
362
+ **Usage:** See `examples/cube_uniform_field/linear/` for examples.
363
+
364
+ **Benchmark** (mu_r=100, B0=1T, 100mm cube):
365
+
366
+ | Mesh | Elements | M_z (MA/m) | Error |
367
+ |------|----------|------------|-------|
368
+ | 1x1x1 hex | 1 | 2.3171 | 0.00% |
369
+ | 2x2x2 hex | 8 | 2.4180 | 4.36% |
370
+ | 5x5x5 hex | 125 | 2.6652 | 15.02% |
371
+
372
+ Analytical: M = 2.3171 MA/m (N = 1/3 for cube)
373
+
374
+
299
375
  ## Changes from Original Radia
300
376
 
301
377
  ### Removed Components
@@ -379,5 +455,5 @@ See [examples/NGSolve_CoefficientFunction_to_Radia_BackgroundField/](examples/NG
379
455
 
380
456
  ---
381
457
 
382
- **Version**: 1.0 (OpenMP + NGSolve Edition)
383
- **Last Updated**: 2025-11-02
458
+ **Version**: 1.3.4 (OpenMP + NGSolve Edition)
459
+ **Last Updated**: 2025-11-30
@@ -254,6 +254,82 @@ export_geometry_to_vtk(mag, 'geometry.vtk')
254
254
  - NGSolve (optional, for FEM coupling via radia_ngsolve)
255
255
  - PyVista (optional, for 3D visualization)
256
256
 
257
+ ## Linear Material with External Field (ObjBckgCF)
258
+
259
+ Radia supports soft magnetic materials (linear materials) in external fields using `ObjBckgCF`.
260
+
261
+ ### Working Example
262
+
263
+ ```python
264
+ import radia as rad
265
+ import numpy as np
266
+
267
+ rad.UtiDelAll()
268
+ rad.FldUnits('m') # Use SI units
269
+
270
+ # Create soft iron cube (10cm side)
271
+ cube = rad.ObjRecMag([0, 0, 0], [0.1, 0.1, 0.1], [0, 0, 0])
272
+
273
+ # Apply isotropic linear material (mu_r = 100)
274
+ chi = 99.0 # chi = mu_r - 1
275
+ mat = rad.MatLin(chi) # IMPORTANT: Use single argument for isotropic
276
+ rad.MatApl(cube, mat)
277
+
278
+ # Create external field (1 Tesla in z-direction)
279
+ def uniform_B(pos):
280
+ return [0, 0, 1.0] # Returns B in Tesla
281
+ bg = rad.ObjBckgCF(uniform_B)
282
+
283
+ # Create system and solve
284
+ system = rad.ObjCnt([cube, bg])
285
+ result = rad.Solve(system, 0.0001, 1000)
286
+
287
+ # Result: M ~ 2.3 MA/m (correct for cube with mu_r=100 in 1T field)
288
+ M = rad.ObjM(cube)
289
+ print(f"Magnetization: {M[1]} A/m")
290
+ ```
291
+
292
+ ### Important Notes
293
+
294
+ 1. **Isotropic materials**: Always use `MatLin(chi)` (single argument)
295
+ - Do NOT use `MatLin(chi, [0, 0, 1e-10])` - this creates a poorly defined anisotropic tensor
296
+
297
+ 2. **Callback returns B in Tesla**: The callback function for `ObjBckgCF` should return magnetic flux density B in Tesla
298
+
299
+ 3. **Units**: When using `rad.FldUnits('m')`, all coordinates are in meters
300
+
301
+ 4. **Tetrahedral elements**: Also works with `ObjPolyhdr` tetrahedral meshes
302
+
303
+ ### Supported Element Types
304
+
305
+ | Element | API | External Field Support |
306
+ |---------|-----|----------------------|
307
+ | Hexahedron | `ObjRecMag` | Yes |
308
+ | Tetrahedron | `ObjPolyhdr` | Yes |
309
+ | Extruded Polygon | `ObjThckPgn` | Yes |
310
+
311
+ ## Tetrahedral Mesh Import from NGSolve/Netgen
312
+
313
+ Radia can import tetrahedral meshes from NGSolve/Netgen for complex geometries.
314
+
315
+ **Features:**
316
+ - Direct Netgen/OCC mesh import to Radia MMM
317
+ - Independent mesh optimization for FEM vs MMM
318
+ - Nastran CTETRA face connectivity standard
319
+
320
+ **Usage:** See `examples/cube_uniform_field/linear/` for examples.
321
+
322
+ **Benchmark** (mu_r=100, B0=1T, 100mm cube):
323
+
324
+ | Mesh | Elements | M_z (MA/m) | Error |
325
+ |------|----------|------------|-------|
326
+ | 1x1x1 hex | 1 | 2.3171 | 0.00% |
327
+ | 2x2x2 hex | 8 | 2.4180 | 4.36% |
328
+ | 5x5x5 hex | 125 | 2.6652 | 15.02% |
329
+
330
+ Analytical: M = 2.3171 MA/m (N = 1/3 for cube)
331
+
332
+
257
333
  ## Changes from Original Radia
258
334
 
259
335
  ### Removed Components
@@ -337,5 +413,5 @@ See [examples/NGSolve_CoefficientFunction_to_Radia_BackgroundField/](examples/NG
337
413
 
338
414
  ---
339
415
 
340
- **Version**: 1.0 (OpenMP + NGSolve Edition)
341
- **Last Updated**: 2025-11-02
416
+ **Version**: 1.3.4 (OpenMP + NGSolve Edition)
417
+ **Last Updated**: 2025-11-30
@@ -405,19 +405,81 @@ create_analytical_field : For pure Python functions
405
405
  - Use uniform field approximation where possible
406
406
  - Consider direct C++ integration (future)
407
407
 
408
+ ## Bug Fixes
409
+
410
+ ### 2025-11-30: B Field Unit Conversion Fix
411
+
412
+ **Issue**: `rad.Fld(bg, 'b', pt)` returned values ~10^6 times smaller than expected.
413
+
414
+ **Root Cause**: `radTCoefficientFunctionFieldSource::B_comp()` was storing B field values in Tesla directly to `FieldPtr->B`, but Radia stores B internally in A/m units (H-like units) and multiplies by μ₀ on output.
415
+
416
+ **Fix** (rad_coefficient_field.cpp lines 116-124):
417
+ ```cpp
418
+ // B_from_cf is magnetic flux density in Tesla from user callback
419
+ // Radia stores B internally in A/m units (will be multiplied by mu0 on output)
420
+ // Convert Tesla to internal units: B_internal = B_tesla / mu0
421
+ const double invMu0 = 795774.715459; // 1/mu0 in A/(m*T)
422
+ TVector3d B_internal(Bx * invMu0, By * invMu0, Bz * invMu0);
423
+ if(FieldPtr->FieldKey.B_) FieldPtr->B += B_internal;
424
+ // H = B/mu0 (same as B_internal)
425
+ if(FieldPtr->FieldKey.H_) FieldPtr->H += B_internal;
426
+ ```
427
+
428
+ ### 2025-11-30: Solver Integration with ObjBckgCF
429
+
430
+ **Issue**: `rad.Solve()` with container containing ObjBckgCF and soft material returned zero magnetization.
431
+
432
+ **Root Cause**: Using `MatLin(chi, [0, 0, 1e-10])` creates an anisotropic material with a poorly defined susceptibility tensor. The small magnitude of the easy axis vector causes numerical issues in tensor setup.
433
+
434
+ **Fix**: Use isotropic material form:
435
+ ```python
436
+ # CORRECT - Isotropic material
437
+ mat = rad.MatLin(chi) # Single argument
438
+
439
+ # INCORRECT - Anisotropic with bad easy axis
440
+ mat = rad.MatLin(chi, [0, 0, 1e-10]) # Don't use small vectors!
441
+ ```
442
+
443
+ **Working Example**:
444
+ ```python
445
+ import radia as rad
446
+ import numpy as np
447
+
448
+ rad.UtiDelAll()
449
+ rad.FldUnits('m')
450
+
451
+ # Create soft iron
452
+ cube = rad.ObjRecMag([0, 0, 0], [0.1, 0.1, 0.1], [0, 0, 0])
453
+ chi = 99.0 # mu_r = 100
454
+ mat = rad.MatLin(chi) # ISOTROPIC form
455
+ rad.MatApl(cube, mat)
456
+
457
+ # Background field (1 Tesla)
458
+ def uniform_B(pos):
459
+ return [0, 0, 1.0]
460
+ bg = rad.ObjBckgCF(uniform_B)
461
+
462
+ # Solve
463
+ system = rad.ObjCnt([cube, bg])
464
+ result = rad.Solve(system, 0.0001, 1000)
465
+ # Result shows M ~ 2.3 MA/m (correct for cube in 1T field with mu_r=100)
466
+ ```
467
+
408
468
  ## Conclusion
409
469
 
410
470
  Successfully implemented arbitrary background field capability for Radia with:
411
471
  - ✅ Clean Python API
412
- - ✅ Unit conversion handling
472
+ - ✅ Unit conversion handling (fixed 2025-11-30)
413
473
  - ✅ Comprehensive test coverage
414
474
  - ✅ Utility functions for common field types
415
475
  - ✅ NGSolve CF integration path
476
+ - ✅ Works with rad.Solve() for soft materials (requires isotropic MatLin)
416
477
 
417
478
  The implementation enables powerful coupling between Radia magnetostatics and NGSolve FEM for complex electromagnetic simulations.
418
479
 
419
480
  ---
420
481
 
421
482
  **Implementation Date**: 2025-10-31
483
+ **Bug Fix Date**: 2025-11-30
422
484
  **Implemented By**: Claude Code
423
485
  **Status**: Ready for Production Use
@@ -0,0 +1,221 @@
1
+ # Radia Solver Methods
2
+
3
+ This document describes the available solver methods in Radia.
4
+
5
+ ## Available Methods
6
+
7
+ | Method | Name | Complexity | Linear | Nonlinear | Best For |
8
+ |--------|------|------------|--------|-----------|----------|
9
+ | **Newton-Raphson** | `'newton'` or `8` | O(N^2 * k) | Yes | Yes | Nonlinear materials |
10
+ | **LU Direct** | `'lu'` or `9` | O(N^3 * k) | Yes | Yes | Small problems (N < 500) |
11
+ | **BiCGSTAB** (Default) | `'bicgstab'` or `10` | O(N^2 * k) | Yes | Yes | General purpose |
12
+ | **BiCGSTAB + H-matrix** | `'bicgstab'` + `SolverHMatrixEnable()` | O(N log N * k) | Yes | Yes | Large problems (N > 1000) |
13
+
14
+ **Note:** All solvers now support both linear and nonlinear materials (v1.3.5+).
15
+
16
+ ## Usage
17
+
18
+ ### Basic Usage
19
+
20
+ ```python
21
+ import radia as rad
22
+
23
+ # Create geometry
24
+ cube = rad.ObjRecMag([0, 0, 0], [40, 40, 40], [0, 0, 0])
25
+ rad.ObjDivMag(cube, [5, 5, 5])
26
+ mat = rad.MatLin(999.0) # mu_r = 1000
27
+ rad.MatApl(cube, mat)
28
+
29
+ # Apply external field
30
+ ext_field = rad.ObjBckg([0, 0, 1.0]) # 1 T
31
+ grp = rad.ObjCnt([cube, ext_field])
32
+
33
+ # Solve using default method (BiCGSTAB)
34
+ res = rad.Solve(grp, 0.0001, 1000)
35
+
36
+ # Or specify method by name
37
+ res = rad.Solve(grp, 0.0001, 1000, 'bicgstab') # BiCGSTAB
38
+ res = rad.Solve(grp, 0.0001, 1000, 'lu') # LU decomposition
39
+ res = rad.Solve(grp, 0.0001, 1000, 'newton') # Newton-Raphson (nonlinear)
40
+
41
+ # Or by number (for backward compatibility)
42
+ res = rad.Solve(grp, 0.0001, 1000, 10) # BiCGSTAB
43
+ res = rad.Solve(grp, 0.0001, 1, 9) # LU (only 1 iteration needed)
44
+ res = rad.Solve(grp, 0.0001, 1000, 8) # Newton-Raphson
45
+ ```
46
+
47
+ ### Method Selection Guide
48
+
49
+ ```
50
+ Problem size?
51
+ |-- N < 500 --> 'lu' (LU Direct) or 'bicgstab' (default)
52
+ |-- N >= 500 --> 'bicgstab' (BiCGSTAB, default)
53
+ |-- N > 1000 --> 'bicgstab' + SolverHMatrixEnable()
54
+
55
+ Material type?
56
+ |-- Linear (MatLin) --> Any solver works
57
+ |-- Nonlinear (MatSatIso, MatSatIsoTab, etc.) --> Any solver works
58
+ 'newton' is traditional choice
59
+ 'bicgstab' also works well
60
+ ```
61
+
62
+ **Note:** All solvers now have outer nonlinear iteration loops, so they all
63
+ handle nonlinear materials correctly. The choice depends mainly on problem size.
64
+
65
+ ## Newton-Raphson (Method 8)
66
+
67
+ Newton-Raphson iterative solver for **nonlinear materials**. Uses local Jacobian for each element.
68
+
69
+ **Pros:**
70
+ - Handles nonlinear (saturable) materials correctly
71
+ - Uses instantaneous susceptibility at each iteration
72
+ - Good convergence for typical B-H curves
73
+
74
+ **Cons:**
75
+ - Slower than BiCGSTAB for linear materials
76
+ - Requires well-defined B-H curve
77
+
78
+ **Best for:** Nonlinear materials (MatSatIso, MatSatIsoTab, MatLam, etc.)
79
+
80
+ ```python
81
+ # Nonlinear material with B-H curve
82
+ bh_curve = [
83
+ [0, 0],
84
+ [100, 0.5],
85
+ [500, 1.2],
86
+ [2000, 1.6],
87
+ [10000, 1.9]
88
+ ]
89
+ mat = rad.MatSatIsoTab(bh_curve)
90
+ rad.MatApl(cube, mat)
91
+
92
+ # Solve with Newton-Raphson
93
+ res = rad.Solve(grp, 0.0001, 1000, 'newton')
94
+ ```
95
+
96
+ ## BiCGSTAB (Default)
97
+
98
+ BiCGSTAB (Biconjugate Gradient Stabilized) is an iterative solver with O(N^2 * k) complexity where k is the number of iterations.
99
+
100
+ **Pros:**
101
+ - Fast for medium to large problems
102
+ - Stable for high permeability materials
103
+ - Good convergence with Jacobi preconditioning
104
+ - Supports both linear and nonlinear materials
105
+
106
+ **Cons:**
107
+ - May not converge for ill-conditioned problems
108
+
109
+ **Best for:** General magnetostatic problems, tetrahedral meshes
110
+
111
+ ```python
112
+ res = rad.Solve(grp, 0.0001, 1000) # Uses default BiCGSTAB
113
+ res = rad.Solve(grp, 0.0001, 1000, 'bicgstab') # Explicit
114
+ ```
115
+
116
+ ## LU Direct Solver
117
+
118
+ Direct solver using LU decomposition with partial pivoting. O(N^3) complexity per nonlinear iteration.
119
+
120
+ **Pros:**
121
+ - Exact solution per nonlinear iteration
122
+ - Always converges
123
+ - Stable for all materials
124
+ - Supports both linear and nonlinear materials
125
+
126
+ **Cons:**
127
+ - O(N^3) time complexity - slow for large N
128
+ - O(N^2) memory usage
129
+
130
+ **Best for:** Small problems (N < 500), validation/debugging
131
+
132
+ ```python
133
+ res = rad.Solve(grp, 0.0001, 100, 'lu') # For nonlinear materials
134
+ res = rad.Solve(grp, 0.0001, 100, 9) # Same as above
135
+ ```
136
+
137
+ **Note:** For linear materials, LU converges in 1 outer iteration. For nonlinear
138
+ materials, multiple outer iterations are needed for chi(H) to converge.
139
+
140
+ ## H-Matrix Acceleration
141
+
142
+ Enable H-matrix with HACApK ACA+ algorithm for BiCGSTAB:
143
+
144
+ ```python
145
+ # Enable H-matrix
146
+ rad.SolverHMatrixEnable()
147
+ res = rad.Solve(grp, 0.0001, 1000, 'bicgstab')
148
+
149
+ # Disable H-matrix
150
+ rad.SolverHMatrixDisable()
151
+
152
+ # Check status
153
+ status = rad.SolverHMatrixStatus() # 1 if enabled, 0 if disabled
154
+ ```
155
+
156
+ **Pros:**
157
+ - O(N log N) per iteration instead of O(N^2)
158
+ - Reduced memory for large problems
159
+
160
+ **Cons:**
161
+ - Overhead for small problems
162
+
163
+ **Best for:** Large problems (N > 1000)
164
+
165
+ ## Performance Benchmark
166
+
167
+ Results from 40mm soft iron cube (mu_r=1000) in 1T uniform field:
168
+
169
+ | N_elem | LU Time | BiCGSTAB Time | BiCGSTAB Iters |
170
+ |--------|---------|---------------|----------------|
171
+ | 27 | 0.005s | 0.0003s | 6 |
172
+ | 125 | 0.010s | 0.005s | 12 |
173
+ | 512 | 0.72s | 0.10s | 14 |
174
+ | 1000 | 6.58s | 0.39s | 16 |
175
+ | 1728 | 34.1s | 1.25s | 18 |
176
+
177
+ ## Accuracy
178
+
179
+ Both LU and BiCGSTAB methods produce consistent results for linear materials:
180
+
181
+ | N_elem | LU Bz (T) | BiCGSTAB Bz (T) | Difference |
182
+ |--------|-----------|-----------------|------------|
183
+ | 27 | 0.1373162 | 0.1373157 | 0.0004% |
184
+ | 512 | 0.1406983 | 0.1406980 | 0.0002% |
185
+ | 1000 | 0.1411381 | 0.1411383 | 0.0001% |
186
+
187
+ ## Notes
188
+
189
+ 1. **Default change (v1.3.5):** BiCGSTAB is now the default solver
190
+ 2. **Nonlinear support (v1.3.5):** All solvers now use Newton-style M(H) updates and produce identical results
191
+ 3. **Tetrahedral meshes:** All methods work correctly with tetrahedral elements
192
+ 4. **Material types:**
193
+ - Linear materials (MatLin): Any solver works; 'bicgstab' is fastest for large problems
194
+ - Nonlinear materials (MatSatIso, MatSatIsoTab, MatLam): Any solver works; all produce identical results
195
+ 5. **Method numbers:** For backward compatibility, methods can also be specified by number (8=Newton, 9=LU, 10=BiCGSTAB)
196
+
197
+ ## Technical Details: Nonlinear Material Handling
198
+
199
+ **All solvers (v1.3.5+)** now use Newton-style M(H) updates for nonlinear materials:
200
+
201
+ 1. **Outer iteration loop**: After each linear system solve, apply Newton-style correction
202
+ 2. **Gauss-Seidel update**: For each element i:
203
+ - Compute quasi-external field: sum of contributions from all OTHER elements + external field
204
+ - Solve local equation: H = (I - chi*Nii)^{-1} * (QuasiExtField + Mr)
205
+ - Apply material's M(H) function directly: M = M(H)
206
+ 3. **Convergence check**: Monitor change in magnetization between iterations
207
+
208
+ This hybrid approach combines the efficiency of LU/BiCGSTAB with the accuracy of Newton-Raphson:
209
+ - LU/BiCGSTAB provide a good initial guess for M
210
+ - Newton-style M(H) update ensures correct nonlinear behavior
211
+ - All three solvers now produce identical results for both linear and nonlinear materials
212
+
213
+ **Solver Comparison** (v1.3.5+):
214
+
215
+ | Solver | Inner Method | Nonlinear Update | Best For |
216
+ |--------|--------------|------------------|----------|
217
+ | Newton (8) | Gauss-Seidel | M = M(H) | General purpose |
218
+ | LU (9) | LU decomposition | M = M(H) | Small problems, validation |
219
+ | BiCGSTAB (10) | BiCGSTAB iteration | M = M(H) | Large problems |
220
+
221
+ All solvers produce identical results for both linear and nonlinear materials.
@@ -0,0 +1,55 @@
1
+ # Cube in Uniform Field Benchmark
2
+
3
+ This folder contains benchmark examples for validating Radia's magnetostatic solver using a soft iron cube in a uniform external magnetic field.
4
+
5
+ ## Subfolder Structure
6
+
7
+ ```
8
+ cube_uniform_field/
9
+ linear/ - Linear material (constant mu_r)
10
+ nonlinear/ - Nonlinear material (BH curve with saturation)
11
+ ```
12
+
13
+ ## Problem Description
14
+
15
+ A soft iron cube (100mm x 100mm x 100mm) is placed in a uniform external magnetic field H0 along the z-axis. This is a classic magnetostatic problem with known analytical solutions for the limiting cases.
16
+
17
+ ## Benchmarks
18
+
19
+ ### Linear Material (`linear/`)
20
+
21
+ Tests Radia's solver with constant permeability materials:
22
+ - Hexahedral mesh (structured)
23
+ - Tetrahedral mesh (unstructured, via Netgen)
24
+ - Method 0 (polygon-based) vs Method 1 (analytical)
25
+ - Comparison with NGSolve FEM reference solution
26
+
27
+ ### Nonlinear Material (`nonlinear/`)
28
+
29
+ Tests Radia's nonlinear solver and H-matrix acceleration:
30
+ - Soft iron BH curve with saturation
31
+ - Direct solver vs H-matrix acceleration
32
+ - Convergence behavior for iterative relaxation
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ import radia as rad
38
+ rad.FldUnits('m') # Required for NGSolve compatibility
39
+
40
+ # Linear material example
41
+ exec(open('linear/cube_benchmark_external_field.py').read())
42
+
43
+ # Nonlinear material example
44
+ exec(open('nonlinear/cube_nonlinear_hmatrix.py').read())
45
+ ```
46
+
47
+ ## Related Examples
48
+
49
+ - `examples/electromagnet/` - Electromagnet with iron yoke
50
+ - `examples/simple_problems/` - Basic magnetostatic problems
51
+
52
+ ## References
53
+
54
+ 1. Chubar, O., Elleaume, P. "Accurate and Efficient Computation of Synchrotron Radiation in the Near Field Region". EPAC98.
55
+ 2. ELF/MAGIC - Electron Linear accelerator Facility, Magnetostatic Analysis using Generalized Integral Computations